Merged Jakub Nesveda's refactoring_custom into master.
--- a/.hgtags Sat May 09 10:22:57 2015 +0100
+++ b/.hgtags Sun Jun 14 09:54:32 2015 +0100
@@ -1,4 +1,5 @@
a27be88be57fe3d2ec05f2c08cf9baa9f22c7a14 expecco_2_7_0
+ce462903d43b4e1396691c65a4c24875dc1c4b16 thesis_submission
a27be88be57fe3d2ec05f2c08cf9baa9f22c7a14 expecco_2_7_0
feba6ee5c81409691496b92dabd87217d18adf11 expecco_2_7_0
feba6ee5c81409691496b92dabd87217d18adf11 expecco_2_7_0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,21 @@
+#
+# DO NOT EDIT
+#
+# make uses this file (Makefile) only, if there is no
+# file named "makefile" (lower-case m) in the same directory.
+# My only task is to generate the real makefile and call make again.
+# Thereafter, I am no longer used and needed.
+#
+
+.PHONY: run
+
+run: makefile
+ $(MAKE) -f makefile
+
+#only needed for the definition of $(TOP)
+include Make.proto
+
+makefile: mf
+
+mf:
+ $(TOP)/rules/stmkmf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/online/README.txt Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,3 @@
+This directory contains html documentation which
+is inpired by Smalltalk/X 'online' docs found here
+ http://live.exept.de/doc/online/english/TOP.html
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/online/english/programming/refactoring_custom-getting-started.html Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,149 @@
+<HTML>
+
+<HEAD>
+<TITLE>Smalltalk/X Programmers guide - API for custom code generators and refactorings - getting started</Title>
+</HEAD>
+
+<BODY>
+
+<A NOPRINT HREF="refactoring_custom-installation.html"> <IMG SRC="../../icons/DocsLeftArrow.gif" ALT="[prev]"></A>
+<A NOPRINT HREF="refactoring_custom.html"> <IMG SRC="../../icons/DocsUpArrow.gif" ALT="[up]"></A>
+<A NOPRINT HREF="#"> <IMG SRC="../../icons/DocsRightArrow.gif" ALT="[next]"></A>
+
+<H1>API for custom code generators and refactorings - getting started</H1>
+
+<p>
+This page describes how to create new code generator class.
+Further documentation can be found inside classes and methods comments.
+Existing code generator/refactoring classes has class (static) method "description"
+which should reveal the class purpose.
+</p>
+
+
+<h2>How to create new code generator class</h2>
+
+<p>
+Right-click somewhere in the class list within system browser and click
+on "Generate - Custom -> New Code Generator". Insert some class name
+and click on Ok button. Now you should have new class created with generated
+method stubs containg "self shouldImplement".
+</p>
+
+<h2>Implement required methods</h2>
+
+<p>
+Here we show a few examples how required methods can be implemented.
+Each method has documentation comment which describes its purpose.
+</p>
+
+<h3>Class (static) methods</h3>
+
+<pre class="code-snippet">
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Mark class as abstract'
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Mark class as abstract (by implementing class method #isAbstract)'
+
+availableInContext:aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ aCustomContext selectedClasses notEmptyOrNil
+
+availableInPerspective:aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ "Allows to locate generator in class/method/package/... context sub-menu.
+ See class CustomPerspective and its subclasses."
+ ^ aCustomPerspective isClassPerspective
+</pre>
+
+<h3>Instance methods</h3>
+
+<pre class="code-snippet">
+buildInContext: aCustomContext
+ "Creates a method isAbstract for selected classes"
+
+ | classes |
+
+ classes := aCustomContext selectedClasses.
+ classes do: [ :class |
+ | metaclass className |
+
+ metaclass := class theMetaclass.
+ className := class theNonMetaclass name.
+
+ (metaclass includesSelector: #isAbstract) ifFalse:[
+ self compile: ('isAbstract
+ ^ self == %1' bindWith: className) forClass: metaclass inCategory: 'testing'
+ ].
+ ]
+
+configureInContext:aCustomContext
+ "Optional method which is called only in interactive mode.
+ Allows to open the dialog-box in which an user can enter custom values.
+ This particular dialog asks for test method name."
+
+ aCustomContext selectedMethods do:[:selectedMethod |
+ | selector |
+
+ selector := selectedMethod selector asSymbol.
+ (testMethodSelectors includesKey: selector) ifFalse: [
+ testMethodSelectors
+ at: selector
+ put: (self createTestMethodSelectorFor: selector).
+ ].
+
+ dialog
+ addSelectorNameEntryOn:(DictionaryAdaptor new
+ subject:testMethodSelectors;
+ aspect:selector)
+ labeled:selector asString
+ validateBy:nil.
+ ].
+
+ dialog addButtons.
+ dialog open.
+</pre>
+
+<h2>How to create new refactoring class</h2>
+
+<p>
+The process is same as described for code generator class, but you need to
+select "Generate -> New Refactoring" in context menu instead.
+Code example below uses code expression replacements which is
+well documented in
+<a href="http://live.exept.de/doc/online/english/help/Browser/RBSearchPatterns.html">Code Search Patterns</a>.
+</p>
+
+<pre class="code-snippet">
+buildInContext: aCustomContext
+ "Performs a refactoring within given context scope.
+ This code replaces selected code in code editor with
+ translation call."
+
+ refactoryBuilder
+ replace:'`@expression'
+ with:'(resources string: (`@expression))'
+ inContext:aCustomContext
+</pre>
+
+<HR>
+<P>
+<IMG NOPRINT ALIGN=middle SRC="../../icons/stx.gif">
+
+</BODY>
+</HTML>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/online/english/programming/refactoring_custom-installation.html Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,80 @@
+<HTML>
+
+<HEAD>
+<TITLE>Smalltalk/X Programmers guide - API for custom code generators and refactorings - installation</TITLE>
+</HEAD>
+
+<BODY>
+
+<A NOPRINT HREF="refactoring_custom.html"> <IMG SRC="../../icons/DocsLeftArrow.gif" ALT="[prev]"></A>
+<A NOPRINT HREF="refactoring_custom.html"> <IMG SRC="../../icons/DocsUpArrow.gif" ALT="[up]"></A>
+<A NOPRINT HREF="refactoring_custom-getting-started.html"> <IMG SRC="../../icons/DocsRightArrow.gif" ALT="[next]"></A>
+
+<H1>API for custom code generators and refactorings - installation</H1>
+
+<h2>Requirements</h2>
+
+<p>
+<b>1. Smalltalk/X</b><br>
+You need recent <a href="http://swing.fit.cvut.cz/projects/stx-goodies/wiki/SmalltalkX">Smalltalk/X jv-branch</a> downloaded and
+installed on your computer. Package is not tested and maintained on official eXept
+Smalltalk/X distribution downloaded from <a href="http://www.exept.de">http://www.exept.de</a>.
+</p>
+
+<p>
+<b>2. Package source files</b><br>
+
+You need to download package from Bitbucket repository
+<a href="https://bitbucket.org/jnesveda/refactoring_custom">jnesveda/refactoring_custom</a>.
+You can download it via
+<a href="http://mercurial.selenic.com/">Mercurial</a>
+command "hg clone url/from/the/link/above" or by clicking on cloud icon in the
+left bar titled with "Downloads".
+</p>
+
+<h2>Installation</h2>
+
+<p>
+Add downloaded source files to folder named "jn/refactoring_custom" which needs
+to be located under your package path (easiest is to put it just in lib/smalltalkx/6.2.5/packages
+where 6.2.5 is STX version). Now run STX, open system browser and click on
+top menu items named "View -> Package". You should see new package named
+jn/refactoring_custom. Right-click on it and select "Load".
+<pre class="code-snippet">
+"To see whats you package path write following line somewhere in STX
+(code editor,launcher text-box), select it, rigt-click and choose Inspect."
+Smalltalk packagePath.
+"This will add a folder as package path"
+Smalltalk packagePath add: 'C:\path\to\your\packages'.
+</pre>
+</p>
+
+<p>
+If everything went well then you can select some class in the system browser,
+right-click on it and now you should see 2 new menu items "Refactor - Custom",
+"Generate - Custom". However, many troubles can happen during package loading.
+Subpackage "patches" has to also properly loaded, but can happen that it wont
+load with described procedure. There are many other possibilities how to load
+classes. You can try one of these if regular way fails (you will see classes marked
+as unloaded or you wont see them):
+<ul>
+ <li>Load classes one-by-one by double clicking on them</li>
+ <li>Click on View -> Category in the system browser, select category,
+ right-click on it and click on "Special -> Load"</li>
+ <li>Open file browser, locate the source files, select them, right-click
+ on it and click on FileIn</li>
+ <li>Paste "Smalltalk loadPackage: 'jn:refactoring_custom'" somewhere (e.g. launcher dialog),
+ select it, right-click on it and click on "DoIt" in the menu</li>
+</ul>
+Finally you can run tests using test runner from launcher to see if everything
+works as expected. You can check the test results against the newest STX-JV branch version
+in <a href="https://swing.fit.cvut.cz/jenkins/job/custom_refactorings_reports/">Jenkins job</a>,
+but this will be most probably removed when this project will be outdated.
+</p>
+
+<HR>
+<P>
+<IMG NOPRINT ALIGN=middle SRC="../../icons/stx.gif">
+
+</BODY>
+</HTML>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/online/english/programming/refactoring_custom.html Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,48 @@
+<HTML>
+
+<HEAD>
+<TITLE>Smalltalk/X Programmers guide - API for custom code generators and refactorings</TITLE>
+</HEAD>
+
+<BODY>
+
+<A NOPRINT HREF="tdv.html"> <IMG SRC="../../icons/DocsLeftArrow.gif" ALT="[prev]"></A>
+<A NOPRINT HREF="TOP.html"> <IMG SRC="../../icons/DocsUpArrow.gif" ALT="[up]"></A>
+<A NOPRINT HREF="refactoring_custom-installation.html"> <IMG SRC="../../icons/DocsRightArrow.gif" ALT="[next]"></A>
+
+<H1>API for custom code generators and refactorings</H1>
+
+<H2>Overview</H2>
+
+<p>
+API for programmers who would like to create their own code generators
+or refactorings in Smalltalk/X environment. This API is intended to be
+more user-friendly than existing possibilities in STX version 6.2.5 .
+The documentation here is not very detailed and further reading can be
+found in <A HREF="https://bitbucket.org/jnesveda/refactoring_custom_thesis">bachelor's thesis text</A>
+(BP_Nesveda_Jakub_2015.pdf), especially chapter "API in a nutshell" describes
+how to write code generators or refactoring.
+</p>
+
+<H2>Contents</H2>
+
+<OL>
+ <LI><A HREF="refactoring_custom-installation.html">Installation</A></LI>
+ <LI><A HREF="refactoring_custom-getting-started.html">Getting started</A></LI>
+</OL>
+
+<H2>Origin/Authors</H2>
+Authors:
+<BR>
+<UL>
+ <LI>Jan Vrany (eXept, SWING Research Group, Czech Technical University in Prague)</LI>
+ <LI>Jakub Nesveda (Czech Technical University in Prague, Faculty of Information Technology, Department of Software Engineering)</LI>
+</UL>
+
+<HR>
+<P>
+<IMG NOPRINT ALIGN=middle SRC="../../icons/stx.gif">
+
+
+</BODY>
+</HTML>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/Make.proto Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,204 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# The Makefile as generated by this Make.proto supports the following targets:
+# make - compile all st-files to a classLib
+# make clean - clean all temp files
+# make clobber - clean all
+#
+# This file contains definitions for Unix based platforms.
+# It shares common definitions with the win32-make in Make.spec.
+
+#
+# position (of this package) in directory hierarchy:
+# (must point to ST/X top directory, for tools and includes)
+TOP=../../..
+INCLUDE_TOP=$(TOP)/..
+
+# subdirectories where targets are to be made:
+SUBDIRS=
+
+
+# subdirectories where Makefiles are to be made:
+# (only define if different from SUBDIRS)
+# ALLSUBDIRS=
+
+REQUIRED_SUPPORT_DIRS=
+
+# if your embedded C code requires any system includes,
+# add the path(es) here:,
+# ********** OPTIONAL: MODIFY the next lines ***
+# LOCALINCLUDES=-Ifoo -Ibar
+LOCALINCLUDES= -I$(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes -I$(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers -I$(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser -I$(INCLUDE_TOP)/stx/goodies/smallsense -I$(INCLUDE_TOP)/stx/goodies/sunit -I$(INCLUDE_TOP)/stx/libbasic -I$(INCLUDE_TOP)/stx/libbasic3 -I$(INCLUDE_TOP)/stx/libcomp -I$(INCLUDE_TOP)/stx/libjava -I$(INCLUDE_TOP)/stx/libjava/tools -I$(INCLUDE_TOP)/stx/libjavascript -I$(INCLUDE_TOP)/stx/libtool -I$(INCLUDE_TOP)/stx/libview -I$(INCLUDE_TOP)/stx/libview2 -I$(INCLUDE_TOP)/stx/libwidg -I$(INCLUDE_TOP)/stx/libwidg2
+
+
+# if you need any additional defines for embedded C code,
+# add them here:,
+# ********** OPTIONAL: MODIFY the next lines ***
+# LOCALDEFINES=-Dfoo -Dbar -DDEBUG
+LOCALDEFINES=
+
+LIBNAME=libstx_goodies_smallsense_refactoring_custom
+STCLOCALOPT='-package=$(PACKAGE)' -I. $(LOCALINCLUDES) $(STCLOCALOPTIMIZATIONS) $(STCWARNINGS) $(LOCALDEFINES) -headerDir=. -varPrefix=$(LIBNAME)
+
+
+# ********** OPTIONAL: MODIFY the next line ***
+# additional C-libraries that should be pre-linked with the class-objects
+LD_OBJ_LIBS=
+LOCAL_SHARED_LIBS=
+
+
+# ********** OPTIONAL: MODIFY the next line ***
+# additional C targets or libraries should be added below
+LOCAL_EXTRA_TARGETS=
+
+OBJS= $(COMMON_OBJS) $(UNIX_OBJS)
+
+
+
+all:: preMake classLibRule postMake
+
+pre_objs::
+
+
+
+
+
+
+# Enforce recompilation of package definition class if Mercurial working
+# copy state changes. Together with --guessVersion it ensures that package
+# definition class always contains correct binary revision string.
+ifneq (**NOHG**, $(shell hg root 2> /dev/null || echo -n '**NOHG**'))
+stx_goodies_smallsense_refactoring_custom.$(O): $(shell hg root)/.hg/dirstate
+endif
+
+
+
+
+# run default testsuite for this package
+test: $(TOP)/goodies/builder/reports
+ $(MAKE) -C $(TOP)/goodies/builder/reports -f Makefile.init
+ $(TOP)/goodies/builder/reports/report-runner.sh -D . -r Builder::TestReport -p $(PACKAGE)
+
+
+
+# add more install actions here
+install::
+
+# add more install actions for aux-files (resources) here
+installAux::
+
+# add more preMake actions here
+preMake::
+
+# add more postMake actions here
+postMake:: cleanjunk
+
+# build all mandatory prerequisite packages (containing superclasses) for this package
+prereq:
+ cd $(TOP)/libbasic && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/goodies/refactoryBrowser/changes && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/goodies/refactoryBrowser/helpers && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/goodies/refactoryBrowser/parser && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libbasic2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libbasic3 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libcomp && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libui && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libview && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libview2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/goodies/sunit && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libwidg && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libwidg2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+ cd $(TOP)/libtool && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+
+
+
+# build all packages containing referenced classes for this package
+# they are not needed to compile the package (but later, to load it)
+references:
+
+
+cleanjunk::
+ -rm -f *.s *.s2
+
+clean::
+ -rm -f *.o *.H
+
+clobber:: clean
+ -rm -f *.so *.dll
+
+
+# BEGINMAKEDEPEND --- do not remove this line; make depend needs it
+$(OUTDIR)SmallSense__CustomChangeManager.$(O) SmallSense__CustomChangeManager.$(H): SmallSense__CustomChangeManager.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomClassQuery.$(O) SmallSense__CustomClassQuery.$(H): SmallSense__CustomClassQuery.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorOrRefactoring.$(O) SmallSense__CustomCodeGeneratorOrRefactoring.$(H): SmallSense__CustomCodeGeneratorOrRefactoring.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomContext.$(O) SmallSense__CustomContext.$(H): SmallSense__CustomContext.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomDialog.$(O) SmallSense__CustomDialog.$(H): SmallSense__CustomDialog.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomManager.$(O) SmallSense__CustomManager.$(H): SmallSense__CustomManager.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMenuBuilder.$(O) SmallSense__CustomMenuBuilder.$(H): SmallSense__CustomMenuBuilder.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMock.$(O) SmallSense__CustomMock.$(H): SmallSense__CustomMock.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNamespace.$(O) SmallSense__CustomNamespace.$(H): SmallSense__CustomNamespace.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBNamespace.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomParseTreeRewriter.$(O) SmallSense__CustomParseTreeRewriter.$(H): SmallSense__CustomParseTreeRewriter.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/ParseTreeRewriter.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/ParseTreeSearcher.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/ParseTreeSourceRewriter.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBProgramNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomPerspective.$(O) SmallSense__CustomPerspective.$(H): SmallSense__CustomPerspective.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoryBuilder.$(O) SmallSense__CustomRefactoryBuilder.$(H): SmallSense__CustomRefactoryBuilder.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeFormatter.$(O) SmallSense__CustomSourceCodeFormatter.$(H): SmallSense__CustomSourceCodeFormatter.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeGenerator.$(O) SmallSense__CustomSourceCodeGenerator.$(H): SmallSense__CustomSourceCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBProgramNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/CodeGenerator.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeSelection.$(O) SmallSense__CustomSourceCodeSelection.$(H): SmallSense__CustomSourceCodeSelection.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseHelper.$(O) SmallSense__CustomTestCaseHelper.$(H): SmallSense__CustomTestCaseHelper.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)stx_goodies_smallsense_refactoring_custom.$(O) stx_goodies_smallsense_refactoring_custom.$(H): stx_goodies_smallsense_refactoring_custom.st $(INCLUDE_TOP)/stx/libbasic/LibraryDefinition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomBrowserChangeManager.$(O) SmallSense__CustomBrowserChangeManager.$(H): SmallSense__CustomBrowserChangeManager.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomChangeManager.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomBrowserContext.$(O) SmallSense__CustomBrowserContext.$(H): SmallSense__CustomBrowserContext.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomContext.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGenerator.$(O) SmallSense__CustomCodeGenerator.$(H): SmallSense__CustomCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLocalChangeManager.$(O) SmallSense__CustomLocalChangeManager.$(H): SmallSense__CustomLocalChangeManager.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomChangeManager.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNoneSourceCodeFormatter.$(O) SmallSense__CustomNoneSourceCodeFormatter.$(H): SmallSense__CustomNoneSourceCodeFormatter.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomSourceCodeFormatter.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRBLocalSourceCodeFormatter.$(O) SmallSense__CustomRBLocalSourceCodeFormatter.$(H): SmallSense__CustomRBLocalSourceCodeFormatter.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomSourceCodeFormatter.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoring.$(O) SmallSense__CustomRefactoring.$(H): SmallSense__CustomRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSilentDialog.$(O) SmallSense__CustomSilentDialog.$(H): SmallSense__CustomSilentDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSubContext.$(O) SmallSense__CustomSubContext.$(H): SmallSense__CustomSubContext.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomContext.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUserDialog.$(O) SmallSense__CustomUserDialog.$(H): SmallSense__CustomUserDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomAccessMethodsCodeGenerator.$(O) SmallSense__CustomAccessMethodsCodeGenerator.$(H): SmallSense__CustomAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeSelectionRefactoring.$(O) SmallSense__CustomCodeSelectionRefactoring.$(H): SmallSense__CustomCodeSelectionRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomInspectorTabCodeGenerator.$(O) SmallSense__CustomInspectorTabCodeGenerator.$(H): SmallSense__CustomInspectorTabCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomIsAbstractCodeGenerator.$(O) SmallSense__CustomIsAbstractCodeGenerator.$(H): SmallSense__CustomIsAbstractCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNewClassGenerator.$(O) SmallSense__CustomNewClassGenerator.$(H): SmallSense__CustomNewClassGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(O) SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(H): SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSubclassResponsibilityCodeGenerator.$(O) SmallSense__CustomSubclassResponsibilityCodeGenerator.$(H): SmallSense__CustomSubclassResponsibilityCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseCodeGenerator.$(O) SmallSense__CustomTestCaseCodeGenerator.$(H): SmallSense__CustomTestCaseCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseMethodCodeGenerator.$(O) SmallSense__CustomTestCaseMethodCodeGenerator.$(H): SmallSense__CustomTestCaseMethodCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseSetUpCodeGenerator.$(O) SmallSense__CustomTestCaseSetUpCodeGenerator.$(H): SmallSense__CustomTestCaseSetUpCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseTearDownCodeGenerator.$(O) SmallSense__CustomTestCaseTearDownCodeGenerator.$(H): SmallSense__CustomTestCaseTearDownCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(O) SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(H): SmallSense__CustomUpdateTestCaseCategoryRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomVisitorCodeGenerator.$(O) SmallSense__CustomVisitorCodeGenerator.$(H): SmallSense__CustomVisitorCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(O) SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(H): SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(O) SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(H): SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorClassGenerator.$(O) SmallSense__CustomCodeGeneratorClassGenerator.$(H): SmallSense__CustomCodeGeneratorClassGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomNewClassGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(O) SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(H): SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomTestCaseCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeSelectionToResourceTranslation.$(O) SmallSense__CustomCodeSelectionToResourceTranslation.$(H): SmallSense__CustomCodeSelectionToResourceTranslation.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeSelectionRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(O) SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(H): SmallSense__CustomDefaultGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(O) SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(H): SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(O) SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(H): SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMultiSetterMethodsCodeGenerator.$(O) SmallSense__CustomMultiSetterMethodsCodeGenerator.$(H): SmallSense__CustomMultiSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomPrintCodeSelectionRefactoring.$(O) SmallSense__CustomPrintCodeSelectionRefactoring.$(H): SmallSense__CustomPrintCodeSelectionRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeSelectionRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoringClassGenerator.$(O) SmallSense__CustomRefactoringClassGenerator.$(H): SmallSense__CustomRefactoringClassGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomNewClassGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(O) SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(H): SmallSense__CustomSimpleAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(O) SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(H): SmallSense__CustomSimpleGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUITestCaseCodeGenerator.$(O) SmallSense__CustomUITestCaseCodeGenerator.$(H): SmallSense__CustomUITestCaseCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomTestCaseCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUITestCaseSetUpCodeGenerator.$(O) SmallSense__CustomUITestCaseSetUpCodeGenerator.$(H): SmallSense__CustomUITestCaseSetUpCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomTestCaseSetUpCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(O) SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(H): SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomVisitorCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes/AddClassChange.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes/AddMethodChange.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes/RefactoryChange.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes/RefactoryClassChange.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBAbstractClass.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBClass.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBMetaclass.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBMethod.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/SystemBrowser.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__NewSystemBrowser.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(STCHDR)
+
+# ENDMAKEDEPEND --- do not remove this line
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/Make.spec Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,190 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# This file contains specifications which are common to all platforms.
+#
+
+# Do NOT CHANGE THESE DEFINITIONS
+# (otherwise, ST/X will have a hard time to find out the packages location from its packageID,
+# to find the source code of a class and to find the library for a package)
+MODULE=stx
+MODULE_DIR=goodies/smallsense/refactoring_custom
+PACKAGE=$(MODULE):$(MODULE_DIR)
+
+
+# Argument(s) to the stc compiler (stc --usage).
+# -headerDir=. : create header files locally
+# (if removed, they will be created as common
+# -Pxxx : defines the package
+# -Zxxx : a prefix for variables within the classLib
+# -Dxxx : defines passed to to CC for inline C-code
+# -Ixxx : include path passed to CC for inline C-code
+# +optspace : optimized for space
+# +optspace2 : optimized more for space
+# +optspace3 : optimized even more for space
+# +optinline : generate inline code for some ST constructs
+# +inlineNew : additionally inline new
+# +inlineMath : additionally inline some floatPnt math stuff
+#
+# ********** OPTIONAL: MODIFY the next line(s) ***
+# STCLOCALOPTIMIZATIONS=+optinline +inlineNew
+# STCLOCALOPTIMIZATIONS=+optspace3
+STCLOCALOPTIMIZATIONS=+optspace3
+
+
+# Argument(s) to the stc compiler (stc --usage).
+# -warn : no warnings
+# -warnNonStandard : no warnings about ST/X extensions
+# -warnEOLComments : no warnings about EOL comment extension
+# -warnPrivacy : no warnings about privateClass extension
+# -warnUnused : no warnings about unused variables
+#
+# ********** OPTIONAL: MODIFY the next line(s) ***
+# STCWARNINGS=-warn
+# STCWARNINGS=-warnNonStandard
+# STCWARNINGS=-warnEOLComments
+STCWARNINGS=-warnNonStandard
+
+COMMON_CLASSES= \
+ SmallSense::CustomChangeManager \
+ SmallSense::CustomClassQuery \
+ SmallSense::CustomCodeGeneratorOrRefactoring \
+ SmallSense::CustomContext \
+ SmallSense::CustomDialog \
+ SmallSense::CustomManager \
+ SmallSense::CustomMenuBuilder \
+ SmallSense::CustomMock \
+ SmallSense::CustomNamespace \
+ SmallSense::CustomParseTreeRewriter \
+ SmallSense::CustomPerspective \
+ SmallSense::CustomRefactoryBuilder \
+ SmallSense::CustomSourceCodeFormatter \
+ SmallSense::CustomSourceCodeGenerator \
+ SmallSense::CustomSourceCodeSelection \
+ SmallSense::CustomTestCaseHelper \
+ stx_goodies_smallsense_refactoring_custom \
+ SmallSense::CustomBrowserChangeManager \
+ SmallSense::CustomBrowserContext \
+ SmallSense::CustomCodeGenerator \
+ SmallSense::CustomLocalChangeManager \
+ SmallSense::CustomNoneSourceCodeFormatter \
+ SmallSense::CustomRBLocalSourceCodeFormatter \
+ SmallSense::CustomRefactoring \
+ SmallSense::CustomSilentDialog \
+ SmallSense::CustomSubContext \
+ SmallSense::CustomUserDialog \
+ SmallSense::CustomAccessMethodsCodeGenerator \
+ SmallSense::CustomCodeSelectionRefactoring \
+ SmallSense::CustomInspectorTabCodeGenerator \
+ SmallSense::CustomIsAbstractCodeGenerator \
+ SmallSense::CustomJavaSimpleSetterMethodsCodeGenerator \
+ SmallSense::CustomNewClassGenerator \
+ SmallSense::CustomReplaceIfNilWithIfTrueRefactoring \
+ SmallSense::CustomSubclassResponsibilityCodeGenerator \
+ SmallSense::CustomTestCaseCodeGenerator \
+ SmallSense::CustomTestCaseMethodCodeGenerator \
+ SmallSense::CustomTestCaseSetUpCodeGenerator \
+ SmallSense::CustomTestCaseTearDownCodeGenerator \
+ SmallSense::CustomUpdateTestCaseCategoryRefactoring \
+ SmallSense::CustomVisitorCodeGenerator \
+ SmallSense::CustomChangeNotificationAccessMethodsCodeGenerator \
+ SmallSense::CustomChangeNotificationSetterMethodsCodeGenerator \
+ SmallSense::CustomCodeGeneratorClassGenerator \
+ SmallSense::CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator \
+ SmallSense::CustomCodeSelectionToResourceTranslation \
+ SmallSense::CustomDefaultGetterMethodsCodeGenerator \
+ SmallSense::CustomLazyInitializationAccessMethodsCodeGenerator \
+ SmallSense::CustomLazyInitializationGetterMethodsCodeGenerator \
+ SmallSense::CustomMultiSetterMethodsCodeGenerator \
+ SmallSense::CustomPrintCodeSelectionRefactoring \
+ SmallSense::CustomRefactoringClassGenerator \
+ SmallSense::CustomSimpleAccessMethodsCodeGenerator \
+ SmallSense::CustomSimpleGetterMethodsCodeGenerator \
+ SmallSense::CustomSimpleSetterMethodsCodeGenerator \
+ SmallSense::CustomUITestCaseCodeGenerator \
+ SmallSense::CustomUITestCaseSetUpCodeGenerator \
+ SmallSense::CustomValueHolderAccessMethodsCodeGenerator \
+ SmallSense::CustomValueHolderGetterMethodsCodeGenerator \
+ SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator \
+ SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator \
+ SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator \
+ SmallSense::CustomVisitorCodeGeneratorAcceptVisitor \
+ SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGenerator \
+
+
+
+
+COMMON_OBJS= \
+ $(OUTDIR_SLASH)SmallSense__CustomChangeManager.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomClassQuery.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomCodeGeneratorOrRefactoring.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomContext.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomDialog.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomManager.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomMenuBuilder.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomMock.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomNamespace.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomParseTreeRewriter.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomPerspective.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomRefactoryBuilder.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSourceCodeFormatter.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSourceCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSourceCodeSelection.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomTestCaseHelper.$(O) \
+ $(OUTDIR_SLASH)stx_goodies_smallsense_refactoring_custom.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomBrowserChangeManager.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomBrowserContext.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomLocalChangeManager.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomNoneSourceCodeFormatter.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomRBLocalSourceCodeFormatter.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomRefactoring.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSilentDialog.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSubContext.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomUserDialog.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomAccessMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomCodeSelectionRefactoring.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomInspectorTabCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomIsAbstractCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomNewClassGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSubclassResponsibilityCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomTestCaseCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomTestCaseMethodCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomTestCaseSetUpCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomTestCaseTearDownCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomVisitorCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomCodeGeneratorClassGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomCodeSelectionToResourceTranslation.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomMultiSetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomPrintCodeSelectionRefactoring.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomRefactoringClassGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomUITestCaseCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomUITestCaseSetUpCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(O) \
+ $(OUTDIR_SLASH)SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)extensions.$(O) \
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/Makefile.init Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,27 @@
+#
+# DO NOT EDIT
+#
+# make uses this file (Makefile) only, if there is no
+# file named "makefile" (lower-case m) in the same directory.
+# My only task is to generate the real makefile and call make again.
+# Thereafter, I am no longer used and needed.
+#
+# MACOSX caveat:
+# as filenames are not case sensitive (in a default setup),
+# we cannot use the above trick. Therefore, this file is now named
+# "Makefile.init", and you have to execute "make -f Makefile.init" to
+# get the initial makefile. This is now also done by the toplevel CONFIG
+# script.
+
+.PHONY: run
+
+run: makefile
+ $(MAKE) -f makefile
+
+#only needed for the definition of $(TOP)
+include Make.proto
+
+makefile: mf
+
+mf:
+ $(TOP)/rules/stmkmf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/README.md Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,7 @@
+# API for Code Generation and Refactoring #
+
+This repository contains bachelor's thesis source codes for Czech Technical University in Prague - Faculty of Information Technology - Department of Software Engineering. Submitted version is marked with tag #thesis_submission. Further reading can be found in folder docs or thesis text repo https://bitbucket.org/jnesveda/refactoring_custom_thesis .
+
+### Overview from docs ###
+
+API for programmers who would like to create their own code generators or refactorings in Smalltalk/X environment. This API is intended to be more user-friendly than existing possibilities in STX version 6.2.5 . The documentation here is not very detailed and further reading can be found in bachelor's thesis text (BP_Nesveda_Jakub_2015.pdf), especially chapter "API in a nutshell" describes how to write code generators or refactoring.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,223 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomAccessMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #(Accessors)
+
+ "Created: / 22-08-2014 / 18:45:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+
+ ^ aCustomContext selectedClasses notEmptyOrNil
+
+ "Modified: / 11-05-2014 / 17:37:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+
+ ^ aCustomPerspective isClassPerspective or: [
+ aCustomPerspective isInstanceVariablePerspective
+ ]
+
+ "Modified: / 11-05-2014 / 16:44:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'testing'!
+
+isAbstract
+ ^ self == CustomAccessMethodsCodeGenerator
+
+ "Modified: / 01-07-2014 / 16:19:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator methodsFor:'accessing'!
+
+protocol
+ "Returns protocol name in which will belong getter method"
+
+ ^ 'accessing'
+
+ "Created: / 12-05-2014 / 23:26:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Should return getter method source code for given class and variable name"
+
+ self subclassResponsibility
+
+ "Created: / 12-05-2014 / 22:44:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-05-2014 / 20:33:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ | selectedVariables |
+
+ selectedVariables := aCustomContext selectedVariables.
+
+ aCustomContext selectedClasses do: [ :class |
+ | variableNames |
+
+ variableNames := class instVarNames.
+
+ selectedVariables notEmptyOrNil ifTrue: [
+ variableNames := variableNames select: [ :variableName |
+ selectedVariables includes: variableName
+ ]
+ ].
+
+ variableNames do:[ :variableName |
+ | source |
+
+ source := self sourceForClass: class variableName: variableName.
+
+ model
+ compile: source
+ in: (self methodClass: class)
+ classified: self protocol
+ ]
+ ]
+
+ "Modified: / 25-01-2015 / 14:39:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator methodsFor:'protected'!
+
+argNameForMethodName: aMethodName
+ "Returns argument name based on given method name"
+
+ ((aMethodName size > 2) and:[ (aMethodName startsWith:'is') and:[ (aMethodName at:3) isUppercase ]])
+ ifTrue:[
+ ^ 'aBoolean'
+ ].
+
+ ^ 'something'
+
+ "Created: / 04-07-2014 / 10:24:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+defaultMethodNameFor: aVarName
+ "Creates getter method name for retrieving default variable value"
+
+ ^ 'default', aVarName asUppercaseFirst
+
+ "Created: / 29-06-2014 / 23:26:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodClass: aClass
+ "Returns class for which will be generated a getter method.
+ By overriding this is possible for example to specify only metaclass of given class."
+
+ ^ aClass
+
+ "Created: / 29-06-2014 / 22:52:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodNameFor: aVarName
+ "Creates getter method name for given variable name"
+
+ | methodName |
+
+ methodName := aVarName.
+ aVarName isUppercaseFirst ifTrue:[
+ (aVarName conform:[:ch | ch isLetter not or:[ch isUppercase]]) ifFalse:[ "/ allow all-uppercase for class-vars
+ methodName := methodName asLowercaseFirst.
+ ]
+ ].
+
+ ^ methodName
+
+ "Created: / 12-05-2014 / 22:04:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+varTypeOf: aVarName class: aClass
+ "Returns variable type as string for given variable name and class"
+
+ | classesClassVars varType |
+
+ classesClassVars := aClass theNonMetaclass allClassVarNames.
+
+ varType := (classesClassVars includes: aVarName)
+ ifTrue:['static']
+ ifFalse:[
+ (aClass isMeta ifTrue:['classInstVar'] ifFalse:['instance'])].
+
+ ^ varType
+
+ "Created: / 12-05-2014 / 21:40:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 20-06-2014 / 21:30:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomAccessMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,272 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomAccessMethodsCodeGeneratorTests
+ instanceVariableNames:'expectedSource class'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ | mockClass mockClassInstance |
+
+ mockClass := mock mockClassOf:CustomAccessMethodsCodeGenerator.
+ mockClass compileMockMethod: 'description ^ ''some description'' '.
+
+ mockClassInstance := mockClass new.
+ mockClassInstance compileMockMethod: 'sourceForClass:aClass variableName:varName
+ ^ varName, '' ^ '', varName'.
+
+ ^ mockClassInstance
+
+ "Modified: / 26-09-2014 / 10:54:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_arg_name_for_method_name_boolean
+ | actualArgName |
+
+ actualArgName := generatorOrRefactoring argNameForMethodName: 'isSomething'.
+
+ self assert: 'aBoolean' = actualArgName
+
+ "Created: / 04-07-2014 / 12:38:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_arg_name_for_method_name_other
+ | actualArgName |
+
+ actualArgName := generatorOrRefactoring argNameForMethodName: 'selector'.
+
+ self assert: 'something' = actualArgName
+
+ "Created: / 04-07-2014 / 12:39:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_in_context_with_none_selected_variable
+ | classWithInstVars testCompleted |
+
+ testCompleted := false.
+ [
+ classWithInstVars := self createClass.
+ classWithInstVars
+ instanceVariableNames: #('instanceVariable_01' 'instanceVariable_02' 'instanceVariable_03');
+ compile.
+
+ context selectedClasses: (Array with: classWithInstVars).
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertMethodCount: 3 inClass: classWithInstVars.
+
+ expectedSource := 'instanceVariable_02 ^ instanceVariable_02'.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_02.
+
+ expectedSource := 'instanceVariable_01 ^ instanceVariable_01'.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_01.
+
+ expectedSource := 'instanceVariable_03 ^ instanceVariable_03'.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_03.
+
+ testCompleted := true.
+ ] ensure: [
+ self assert: testCompleted
+ ].
+
+ "Created: / 20-06-2014 / 20:29:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-11-2014 / 15:44:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_in_context_with_one_selected_variable
+ | class |
+
+ class := self createClass.
+ class
+ instanceVariableNames: (Array with: 'instanceVariable_01' with: 'instanceVariable_02' with: 'instanceVariable_03');
+ compile.
+
+ context selectedClasses: (Array with: class).
+ context selectedVariables: (Array with: 'instanceVariable_02').
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertMethodCount: 1 inClass: class.
+
+ expectedSource := 'instanceVariable_02 ^ instanceVariable_02'.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_02.
+
+ "Created: / 17-06-2014 / 08:57:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 26-09-2014 / 10:57:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_in_context_with_two_selected_variables
+ | class |
+
+ class := self createClass.
+ class
+ instanceVariableNames: (Array with: 'instanceVariable_01' with: 'instanceVariable_02' with: 'instanceVariable_03');
+ compile.
+
+ context selectedClasses: (Array with: class).
+ context selectedVariables: (Array with: 'instanceVariable_02' with: 'instanceVariable_01').
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertMethodCount: 2 inClass: class.
+
+ expectedSource := 'instanceVariable_02 ^ instanceVariable_02'.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_02.
+
+ expectedSource := 'instanceVariable_01 ^ instanceVariable_01'.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_01.
+
+ "Created: / 20-06-2014 / 20:26:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 26-09-2014 / 11:03:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_default_method_name_for_variable_name
+ | actualDefaultMethodName |
+
+ actualDefaultMethodName := generatorOrRefactoring defaultMethodNameFor: 'varName'.
+
+ self assert: 'defaultVarName' = actualDefaultMethodName
+
+ "Created: / 29-06-2014 / 23:33:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_name_for_all_upper_case
+ | actualMethodName |
+
+ actualMethodName := generatorOrRefactoring methodNameFor: 'VAR'.
+
+ self assert: 'VAR' = actualMethodName
+
+ "Created: / 20-06-2014 / 21:11:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_name_for_class_variable
+ | actualMethodName |
+
+ actualMethodName := generatorOrRefactoring methodNameFor: 'ClassVar'.
+
+ self assert: 'classVar' = actualMethodName
+
+ "Created: / 20-06-2014 / 20:36:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_name_for_instance_variable
+
+ self assert: 'instVar' = (generatorOrRefactoring methodNameFor: 'instVar')
+
+ "Created: / 20-06-2014 / 20:35:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_name_for_number
+ | actualMethodName |
+
+ actualMethodName := generatorOrRefactoring methodNameFor: 'Var_7'.
+
+ self assert: 'var_7' = actualMethodName
+
+ "Created: / 20-06-2014 / 21:13:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_var_type_of_class_instance_variable
+ | actualVarType |
+
+ class := self createClass theMetaclass.
+ class
+ instanceVariableNames: (Array with: 'ClassInstVar1' with: 'ClassInstVar2').
+
+ self assert: class isMeta.
+
+ actualVarType := generatorOrRefactoring varTypeOf: 'ClassInstVar2' class: class.
+
+ self assert: 'classInstVar' = actualVarType
+
+ "Created: / 23-06-2014 / 19:27:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 26-09-2014 / 21:33:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_var_type_of_instance_variable
+ | actualVarType |
+
+ class := self createClass.
+ class instanceVariableNames: 'instVar1 instVar2'.
+
+ actualVarType := generatorOrRefactoring varTypeOf: 'instVar2' class: class.
+
+ self assert: 'instance' = actualVarType
+
+ "Created: / 23-06-2014 / 19:26:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_var_type_of_static
+ | actualVarType |
+
+ class := self createClass.
+ class classVariableNames: (Array with: 'ClassVar1' with: 'ClassVar2').
+
+ actualVarType := generatorOrRefactoring varTypeOf: 'ClassVar2' class: class.
+
+ self assert: 'static' = actualVarType
+
+ "Created: / 20-06-2014 / 21:22:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 26-09-2014 / 21:47:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomAddClassChangeTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,379 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomAddClassChangeTests
+ instanceVariableNames:'className change'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomAddClassChangeTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomAddClassChangeTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+ ^ nil
+
+ "Created: / 16-10-2014 / 22:57:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddClassChangeTests methodsFor:'initialize & release'!
+
+setUp
+ super setUp.
+
+ className := 'DummyTestClass01'.
+ self assert: (Smalltalk classNamed: className) isNil.
+
+ change := AddClassChange definition: '
+ Object subclass:#', className, '
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:''''
+ '.
+
+ "Modified: / 16-10-2014 / 22:55:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+ | realClass |
+
+ realClass := Smalltalk classNamed: className.
+ realClass notNil ifTrue: [
+ realClass removeFromSystem
+ ].
+
+ super tearDown.
+
+ "Modified: / 30-11-2014 / 17:04:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddClassChangeTests methodsFor:'tests'!
+
+test_argumens_by_selector_parts_from_message_arguments_missing
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+ messageNode arguments: #().
+
+ expectedResult := Dictionary new.
+ actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:12:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_none_argument
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'Object name'.
+
+ expectedResult := Dictionary new.
+ actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:03:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_one_argument
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'Object subclass: SomeClass01'.
+
+ expectedResult := Dictionary new
+ at: #subclass: put: (messageNode arguments first);
+ yourself.
+
+ actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:05:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:55:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_selector_empty
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+ messageNode selectorParts: #().
+
+ expectedResult := Dictionary new
+ at: 1 put: (messageNode arguments first);
+ at: 2 put: (messageNode arguments second);
+ yourself.
+
+ actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:10:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:55:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_selector_missing
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+ messageNode selectorParts: nil.
+
+ expectedResult := Dictionary new
+ at: 1 put: (messageNode arguments first);
+ at: 2 put: (messageNode arguments second);
+ yourself.
+
+ actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:10:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:55:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_two_arguments
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+
+ expectedResult := Dictionary new
+ at: #subclass: put: (messageNode arguments first);
+ at: #category: put: (messageNode arguments second);
+ yourself.
+
+ actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:09:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:55:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_fill_out_definition_ordinary_class
+
+ change definition: 'SomeObject01 subclass:#DummySubclass01
+ instanceVariableNames:''inst01 inst02''
+ classVariableNames:''Cls01 Cls02''
+ poolDictionaries:''pool01''
+ category:''Some-Category01'''.
+
+ change fillOutDefinition.
+
+ self assert: #DummySubclass01 = (change changeClassName).
+ self assert: change privateInClassName isNil.
+ self assert: #SomeObject01 = (change superclassName).
+ self assert: #'Some-Category01' = (change category).
+ self assert: (#(inst01 inst02) asStringCollection) = (change instanceVariableNames).
+ self assert: (#(Cls01 Cls02) asStringCollection) = (change classVariableNames).
+ self assert: (#(pool01) asOrderedCollection) = (change poolDictionaryNames).
+
+ "Created: / 16-11-2014 / 16:12:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 12:40:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_fill_out_definition_private_class_01
+
+ change definition: 'Object subclass:#DummyPrivateClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ privateIn:Object'.
+
+ change fillOutDefinition.
+
+ self assert: #'Object::DummyPrivateClass01' = (change changeClassName).
+ self assert: #Object = (change privateInClassName).
+ self assert: #Object = (change superclassName).
+ self assert: #'' = (change category).
+ self assert: (StringCollection new) = (change instanceVariableNames).
+ self assert: (StringCollection new) = (change classVariableNames).
+ self assert: (OrderedCollection new) = (change poolDictionaryNames).
+
+ "Created: / 16-11-2014 / 15:56:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:08:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_fill_out_definition_private_class_02
+
+ change definition: 'SomeObject01 subclass:#DummyPrivateClass01
+ instanceVariableNames:''inst01 inst02''
+ classVariableNames:''Cls01 Cls02''
+ poolDictionaries:''pool01''
+ privateIn:SomeObject02'.
+
+ change fillOutDefinition.
+
+ self assert: #'SomeObject02::DummyPrivateClass01' = (change changeClassName).
+ self assert: #SomeObject02 = (change privateInClassName).
+ self assert: #SomeObject01 = (change superclassName).
+ self assert: #'' = (change category).
+ self assert: (#(inst01 inst02) asStringCollection) = (change instanceVariableNames).
+ self assert: (#(Cls01 Cls02) asStringCollection) = (change classVariableNames).
+ self assert: (#(pool01) asOrderedCollection) = (change poolDictionaryNames).
+
+ "Created: / 16-11-2014 / 16:08:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:08:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_get_and_set_package
+
+ self assert: change package isNil.
+
+ change package: #some_package01.
+
+ self assert: #some_package01 = (change package).
+
+ "Created: / 17-10-2014 / 09:06:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_message_name
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+
+ expectedResult := false.
+ actualResult := change isValidMessageName: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:15:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_message_name_with_private_class
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'DummyObject01 subclass:#DummyPrivateClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ privateIn:DummyObject02'.
+
+ expectedResult := true.
+ actualResult := change isValidMessageName: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:16:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_subclass_creation_message_for_private_class
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'DummyObject01 subclass:#DummyPrivateClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ privateIn:DummyObject02'.
+
+ expectedResult := true.
+ actualResult := change isValidSubclassCreationMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:23:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_subclass_creation_message_for_private_class_wrong
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'DummyObject01 subclass:DummyPrivateClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ privateIn:DummyObject02'.
+
+ expectedResult := false.
+ actualResult := change isValidSubclassCreationMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:33:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_subclass_creation_message_for_unkown_message
+ | expectedResult actualResult messageNode |
+
+ messageNode := RBParser parseExpression: 'DummyObject01 subclass:#DummyPrivateClass01'.
+
+ expectedResult := false.
+ actualResult := change isValidSubclassCreationMessage: messageNode.
+
+ self assert: expectedResult = actualResult
+
+ "Created: / 16-11-2014 / 15:34:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_primitive_execute_with_package
+
+ | class |
+
+ change package: #some_package01.
+ change primitiveExecute.
+
+ self assertClassExists: className.
+ class := Smalltalk classNamed: className.
+ self assert: #some_package01 = (class package).
+
+ "Created: / 16-10-2014 / 22:49:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 17-10-2014 / 08:10:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_primitive_execute_without_package
+
+ | class |
+
+ change primitiveExecute.
+
+ self assertClassExists: className.
+ class := Smalltalk classNamed: className.
+ self assert: (PackageId noProjectID) = (class package).
+
+ "Created: / 17-10-2014 / 08:11:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomAddMethodChangeTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,254 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomAddMethodChangeTests
+ instanceVariableNames:'class change'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomAddMethodChangeTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomAddMethodChangeTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+ ^ nil
+
+ "Created: / 16-10-2014 / 22:57:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddMethodChangeTests methodsFor:'initialize & release'!
+
+setUp
+ super setUp.
+
+ class := model createClassImmediate: 'DummyTestClass01'.
+ change := AddMethodChange compile: 'selector_01 ^ 1' in: class.
+
+ "Modified: / 17-10-2014 / 09:31:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddMethodChangeTests methodsFor:'tests'!
+
+test_as_undo_operation_new_package_nil
+
+ | undo |
+
+ model createMethodImmediate: class
+ protocol: 'a protocol'
+ source: 'selector_01 ^ 555'
+ package: #some_package01.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+ change package: nil.
+ undo := change execute. "calls internally asUndoOperation"
+
+ self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ undo execute.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ "Created: / 17-10-2014 / 10:39:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_new_package_not_set
+
+ | undo |
+
+ model createMethodImmediate: class
+ protocol: 'a protocol'
+ source: 'selector_01 ^ 555'
+ package: #some_package01.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+ undo := change execute. "calls internally asUndoOperation"
+
+ self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ undo execute.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ "Created: / 17-10-2014 / 10:43:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_old_package_different_from_new_package
+
+ | undo |
+
+ model createMethodImmediate: class
+ protocol: 'a protocol'
+ source: 'selector_01 ^ 555'
+ package: #some_package02.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+ change package: #some_package01.
+ undo := change execute. "calls internally asUndoOperation"
+
+ self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ undo execute.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+ self assert: #some_package02 = ((class compiledMethodAt: #selector_01) package).
+
+ "Created: / 17-10-2014 / 10:38:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_old_package_nil
+
+ | undo |
+
+ model createMethodImmediate: class
+ protocol: 'a protocol'
+ source: 'selector_01 ^ 555'
+ package: nil.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+ change package: #some_package01.
+ undo := change execute. "calls internally asUndoOperation"
+
+ self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ undo execute.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+ self assert: (PackageId noProjectID) = ((class compiledMethodAt: #selector_01) package).
+
+ "Created: / 17-10-2014 / 10:37:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_old_package_same_as_new
+
+ | undo |
+
+ model createMethodImmediate: class
+ protocol: 'a protocol'
+ source: 'selector_01 ^ 555'
+ package: #some_package01.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+ change package: #some_package01.
+ undo := change execute. "calls internally asUndoOperation"
+
+ self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ undo execute.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ "Created: / 17-10-2014 / 10:08:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_old_package_same_as_new_with_redo
+
+ | undo redo |
+
+ model createMethodImmediate: class
+ protocol: 'a protocol'
+ source: 'selector_01 ^ 555'
+ package: #some_package01.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+ change package: #some_package01.
+ undo := change execute. "calls internally asUndoOperation"
+
+ self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ redo := undo execute.
+
+ self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ redo execute.
+
+ self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+ self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+ "Created: / 17-10-2014 / 22:14:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_get_and_set_package
+
+ self assert: change package isNil.
+
+ change package: #some_package01.
+
+ self assert: #some_package01 = (change package).
+
+ "Created: / 17-10-2014 / 09:35:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddMethodChangeTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomBrowserChangeManager.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,74 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomChangeManager subclass:#CustomBrowserChangeManager
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomBrowserChangeManager class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Implementation of global Browser refactory changes
+ - so you could see them for example in Browser - Operations menu.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomBrowserChangeManager methodsFor:'performing-changes'!
+
+performChange: aRefactoringChange
+
+ RefactoryChangeManager instance performChange: aRefactoringChange
+
+ "Created: / 31-05-2014 / 13:20:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomBrowserContext.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,182 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomContext subclass:#CustomBrowserContext
+ instanceVariableNames:'state'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomBrowserContext class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomBrowserContext class methodsFor:'instance creation'!
+
+perspective: perspective state: state
+ ^ self new perspective: perspective state: state
+
+ "Created: / 26-01-2014 / 11:00:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomBrowserContext methodsFor:'accessing'!
+
+perspective:perspectiveArg state:stateArg
+ perspective := perspectiveArg.
+ state := stateArg.
+
+ "Created: / 26-01-2014 / 11:00:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomBrowserContext methodsFor:'accessing-selection'!
+
+selectedClassCategories
+
+ ^ state selectedCategories value
+
+ "Modified: / 05-08-2014 / 21:35:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClasses
+ "Returns a set of classes currently selected in
+ the browser"
+
+ ^ state selectedClasses value ? #() collect:[ :cls | self asRBClass: cls ]
+
+ "Created: / 26-01-2014 / 22:06:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 14-11-2014 / 20:08:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 29-12-2014 / 09:43:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedCodes
+ | codeSelection currentMethod codeView |
+
+ currentMethod := state theSingleSelectedMethod.
+ codeView := state codeView.
+
+ (codeView isNil or: [ currentMethod isNil ]) ifTrue: [
+ ^ nil
+ ].
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ selectedInterval: codeView selectedInterval;
+ currentSourceCode: codeView contentsAsString;
+ selectedMethod: currentMethod;
+ selectedClass: currentMethod mclass;
+ selectedSelector: currentMethod selector.
+
+
+ ^ Array with: codeSelection
+
+ "Created: / 18-08-2014 / 21:34:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 18-08-2014 / 23:51:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethods
+
+ ^ state selectedMethods value ? #() collect:[ :m | self asRBMethod: m ]
+
+ "Modified: / 14-11-2014 / 20:17:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 29-12-2014 / 10:10:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedPackages
+
+ ^ state packageFilter value
+
+ "Modified: / 05-08-2014 / 21:38:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedProtocols
+ "Returns a collection of method protocols which are visible and selected in the Browser."
+
+ |protocols allIncluded|
+
+ protocols := state selectedProtocols value.
+ "Support to return all protocols when all protocol ('* all *') is selected in the Browser.
+ This is a little duplicate as in Tools::NewSystemBowser >> selectedProtocolsDo: ,
+ but using this method would require a referece to the Browser and furthermore is marked as private."
+ allIncluded := protocols ? #()
+ includes:(Tools::BrowserList nameListEntryForALL).
+ allIncluded ifTrue:[
+ protocols := Set new.
+ self selectedClasses do:[:class |
+ protocols addAll:class categories
+ ]
+ ].
+ ^ protocols
+
+ "Modified: / 19-11-2014 / 08:45:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedVariables
+
+ ^ state variableFilter value
+
+ "Modified: / 17-05-2014 / 13:29:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomBrowserContext methodsFor:'testing'!
+
+isInteractiveContext
+ "Return true, if this generator/refactoring context is interactive,
+ i.e., if it may interact with user (like asking for class name or
+ similar) or not.
+
+ Generally speaking, only top-level context is interactive an only
+ if generator/refactoring was triggerred from menu.
+ "
+ ^ true
+
+ "Created: / 16-09-2014 / 09:23:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomBrowserContext class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomBrowserContextTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,168 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomBrowserContextTests
+ instanceVariableNames:'state'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomBrowserContextTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomBrowserContextTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+ ^ nil
+
+ "Created: / 28-10-2014 / 19:17:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomBrowserContextTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ state := Tools::NavigationState new.
+ context := CustomBrowserContext perspective: CustomPerspective new state: state
+
+ "Modified: / 25-01-2015 / 16:08:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomBrowserContextTests methodsFor:'tests'!
+
+test_selected_classes_empty
+
+ self assert: state selectedClasses value isNil.
+ self assert: (context selectedClasses) = #()
+
+ "Modified: / 29-12-2014 / 10:17:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_method_protocols_all
+ | expectedProtocols actualProtocols class |
+
+ class := model createClassImmediate: #DummyClassForTestsCase01.
+ model createMethodImmediate: class protocol: 'protocol_01' source: 'sel_01 ^ 1'.
+ model createMethodImmediate: class protocol: 'protocol_02' source: 'sel_02 ^ 2'.
+
+ expectedProtocols := Set new
+ add: #protocol_01;
+ add: #protocol_02;
+ yourself.
+
+ state selectedProtocols setValue: (Array with: 'protocol_01' with: (Tools::BrowserList nameListEntryForALL)).
+ state selectedClasses setValue: (Array with: class).
+
+ actualProtocols := context selectedProtocols.
+
+ self assert: expectedProtocols = actualProtocols.
+
+ "Created: / 28-10-2014 / 19:21:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_method_protocols_all_two_classes
+ | expectedProtocols actualProtocols class01 class02 |
+
+ class01 := model createClassImmediate: #DummyClassForTestsCase01.
+ model createMethodImmediate: class01 protocol: 'protocol_01' source: 'sel_01 ^ 1'.
+ model createMethodImmediate: class01 protocol: 'protocol_02' source: 'sel_02 ^ 2'.
+
+ class02 := model createClassImmediate: #DummyClassForTestsCase02.
+ model createMethodImmediate: class02 protocol: 'protocol_01' source: 'sel_09 ^ 9'.
+ model createMethodImmediate: class02 protocol: 'protocol_03' source: 'sel_03 ^ 3'.
+
+ expectedProtocols := Set new
+ add: #protocol_01;
+ add: #protocol_02;
+ add: #protocol_03;
+ yourself.
+
+ state selectedProtocols setValue: (Array with: 'protocol_01' with: (Tools::BrowserList nameListEntryForALL)).
+ state selectedClasses setValue: (Array with: class01 with: class02).
+
+ actualProtocols := context selectedProtocols.
+
+ self assert: expectedProtocols = actualProtocols.
+
+ "Created: / 28-10-2014 / 19:26:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-11-2014 / 09:33:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_method_protocols_empty
+ | expectedProtocols actualProtocols |
+
+ expectedProtocols := nil.
+ state selectedProtocols setValue: nil.
+
+ actualProtocols := context selectedProtocols.
+
+ self assert: expectedProtocols = actualProtocols.
+
+ "Created: / 05-11-2014 / 18:55:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_method_protocols_subset
+ | expectedProtocols actualProtocols |
+
+ expectedProtocols := Array with: 'protocol_01' with: 'protocol_02'.
+ state selectedProtocols setValue: expectedProtocols.
+
+ actualProtocols := context selectedProtocols.
+
+ self assert: expectedProtocols = actualProtocols.
+
+ "Modified: / 28-10-2014 / 19:17:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_methods_empty
+
+ self assert: state selectedMethods value isNil.
+ self assert: (context selectedMethods) = #()
+
+ "Modified: / 29-12-2014 / 10:20:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomBrowserEnvironmentTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,93 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomBrowserEnvironmentTests
+ instanceVariableNames:'environment'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomBrowserEnvironmentTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomBrowserEnvironmentTests methodsFor:'initialization & release'!
+
+setUp
+
+ environment := BrowserEnvironment new.
+
+ "Modified: / 05-11-2014 / 21:29:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomBrowserEnvironmentTests methodsFor:'tests'!
+
+test_which_category_includes_existing_class
+ | expectedCategory actualCategory className |
+
+ expectedCategory := self class category.
+
+ className := self class name.
+ actualCategory := environment whichCategoryIncludes: className.
+
+ self assert: expectedCategory = actualCategory.
+
+ "Created: / 05-11-2014 / 21:33:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_which_category_includes_non_existing_class
+ | expectedCategory actualCategory className |
+
+ expectedCategory := nil.
+
+ className := #DummyClassForTestCase01.
+ self assert: (Smalltalk at: className) isNil.
+
+ actualCategory := environment whichCategoryIncludes: className.
+
+ self assert: expectedCategory = actualCategory.
+
+ "Created: / 05-11-2014 / 21:32:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeManager.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomChangeManager
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomChangeManager class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Interface for operations with refactory browser changes needed for CustomCodeGenerator.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomChangeManager class methodsFor:'testing'!
+
+isAbstract
+ ^ self == CustomChangeManager
+! !
+
+!CustomChangeManager methodsFor:'performing-changes'!
+
+performChange: aRefactoringChange
+
+ self subclassResponsibility
+
+ "Created: / 31-05-2014 / 13:02:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeManager class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomChangeNotificationAccessMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomChangeNotificationAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Access Method(s) with Change Notification for selected instance variables'
+
+ "Modified: / 13-07-2014 / 16:39:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Access Method(s) with Change Notification'
+
+ "Modified: / 13-07-2014 / 16:39:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ "Creates access methods with change notification in setter for given context"
+
+ self executeSubGeneratorOrRefactoringClasses:(Array
+ with:CustomSimpleGetterMethodsCodeGenerator
+ with:CustomChangeNotificationSetterMethodsCodeGenerator)
+ inContext:aCustomContext
+
+ "Modified: / 13-07-2014 / 16:39:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeNotificationAccessMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomChangeNotificationAccessMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomChangeNotificationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomChangeNotificationAccessMethodsCodeGenerator new
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_change_notification_access_methods_generated_with_comments
+ | expectedGetterSource expectedSetterSource |
+
+ userPreferences
+ generateCommentsForGetters: true;
+ generateCommentsForSetters: true.
+
+ expectedGetterSource := 'instanceVariable
+ "return the instance variable ''instanceVariable'' (automatically generated)"
+
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ "set the value of the instance variable ''instanceVariable'' and send a change notification (automatically generated)"
+
+ (instanceVariable ~~ something) ifTrue:[
+ instanceVariable := something.
+ self changed:#instanceVariable.
+ ].'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+ "Created: / 13-07-2014 / 16:45:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_notification_access_methods_generated_without_comments
+ | expectedGetterSource expectedSetterSource |
+
+ userPreferences
+ generateCommentsForGetters: false;
+ generateCommentsForSetters: false.
+
+ expectedGetterSource := 'instanceVariable
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ (instanceVariable ~~ something) ifTrue:[
+ instanceVariable := something.
+ self changed:#instanceVariable.
+ ].'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+ "Created: / 13-07-2014 / 16:47:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,130 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomChangeNotificationSetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomChangeNotificationSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Setter methods with Change Notification for selected instance variables'
+
+ "Modified: / 06-07-2014 / 13:48:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Setters')
+
+ "Created: / 22-08-2014 / 18:54:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Setter Method(s) with Change Notification'
+
+ "Modified: / 06-07-2014 / 13:47:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns setter method with change notification for given class and variable name"
+
+ | methodName comment argName |
+
+ methodName := self methodNameFor: aName.
+ argName := self argNameForMethodName: methodName.
+ comment := ''.
+
+ userPreferences generateCommentsForSetters ifTrue:[
+ | varType |
+
+ varType := self varTypeOf: aName class: aClass.
+ comment := '"set the value of the %1 variable ''%2'' and send a change notification (automatically generated)"'.
+ comment := comment bindWith: varType with: aName.
+ ].
+
+ ^ self sourceCodeGenerator
+ source: '`@methodName
+ `"comment
+
+ (`variableName ~~ `argName) ifTrue:[
+ `variableName := `argName.
+ self changed: `#variableName.
+ ].';
+ replace: '`@methodName' with: (methodName, ': ', argName) asSymbol;
+ replace: '`argName' with: argName asString;
+ replace: '`variableName' with: aName asString;
+ replace: '`#variableName' with: ($#, aName asSymbol);
+ replace: '`"comment' with: comment;
+ newSource.
+
+ "Modified: / 19-09-2014 / 22:16:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeNotificationSetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,111 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomChangeNotificationSetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomChangeNotificationSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomChangeNotificationSetterMethodsCodeGenerator new
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_change_notification_setter_method_generated_with_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: true.
+
+ expectedSource := 'instanceVariable:something
+ "set the value of the instance variable ''instanceVariable'' and send a change notification (automatically generated)"
+
+ (instanceVariable ~~ something) ifTrue:[
+ instanceVariable := something.
+ self changed:#instanceVariable.
+ ].'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+ "Created: / 06-07-2014 / 13:55:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_notification_setter_method_generated_without_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: false.
+
+ expectedSource := 'instanceVariable:something
+ (instanceVariable ~~ something) ifTrue:[
+ instanceVariable := something.
+ self changed:#instanceVariable.
+ ].'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+ "Created: / 06-07-2014 / 14:05:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_instance_variable_present
+ | expectedVariables actualVariables |
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+
+ expectedVariables := #('instanceVariable').
+ actualVariables := (Smalltalk at: #DummyClassForGeneratorTestCase) instanceVariableNames.
+
+ self assert: expectedVariables = actualVariables
+
+ "Created: / 30-11-2014 / 19:16:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomClassQuery.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,90 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomClassQuery
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Helpers'
+!
+
+!CustomClassQuery class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Helper class for retrieving additional informations from classes.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomClassQuery methodsFor:'queries'!
+
+methodForSuperclassSelector: aSelector class: aClass
+ "retrieve method under given selector in class
+ superclass or in superclass superclass until method is found
+ or nil is reached"
+
+ | superclass |
+
+ superclass := aClass superclass.
+ [ superclass notNil ] whileTrue: [
+ | method |
+
+ method := superclass compiledMethodAt: aSelector asSymbol.
+ method notNil ifTrue: [
+ ^ method
+ ].
+ superclass := superclass superclass.
+ ].
+
+ ^ nil
+
+ "Created: / 15-06-2014 / 14:58:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 07-10-2014 / 19:50:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomClassQueryTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomClassQueryTests
+ instanceVariableNames:'classQuery model mockSuperClass mockClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Helpers-Tests'
+!
+
+!CustomClassQueryTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomClassQueryTests methodsFor:'initialization & release'!
+
+setUp
+
+ classQuery := CustomClassQuery new.
+ model := CustomNamespace new.
+ mockSuperClass := model createClassImmediate: 'MockSuperClassForTestCase' superClassName: 'Object'.
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: (mockSuperClass new className).
+
+ "Modified: / 09-10-2014 / 09:33:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ model undoChanges
+
+ "Modified: / 19-10-2014 / 14:56:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomClassQueryTests methodsFor:'tests'!
+
+test_method_from_superclass_not_found_01
+ | method |
+
+ method := classQuery methodForSuperclassSelector: 'someNonExistingMethod:withParam:' class: Object.
+ self assert: method isNil.
+
+ "Created: / 07-10-2014 / 19:54:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_from_superclass_not_found_02
+ | method |
+
+ method := classQuery methodForSuperclassSelector: 'someNonExistingMethod:withParam:' class: self class.
+ self assert: method isNil.
+
+ "Created: / 07-10-2014 / 19:54:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_from_superclass_retrieved
+ | method |
+
+ self assert: (classQuery methodForSuperclassSelector: 'initialize' class: Object) isNil.
+
+ "/ Instance method
+ model createMethodImmediate: mockSuperClass protocol: 'instance-protocol' source: 'instanceMethod: aParam
+ self shouldImplement'.
+
+ method := classQuery methodForSuperclassSelector: #instanceMethod: class: mockClass.
+ self assert: 'instance-protocol' = method category.
+
+ self assert: 'instanceMethod:aParam' = method methodDefinitionTemplate.
+
+ "/ Class method
+ model createMethodImmediate: mockSuperClass class protocol: 'class-protocol' source: 'classMethod: aParam
+ self shouldImplement'.
+
+ method := classQuery methodForSuperclassSelector: 'classMethod:' class: mockClass class.
+ self assert: 'class-protocol' = method category.
+ self assert: 'classMethod:aParam' = method methodDefinitionTemplate.
+
+ "Created: / 14-04-2014 / 18:12:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 15-06-2014 / 16:17:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,79 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoring subclass:#CustomCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGenerator class methodsFor:'testing'!
+
+isAbstract
+ ^ self == CustomCodeGenerator
+
+ "Created: / 26-01-2014 / 21:38:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isCustomCodeGenerator
+ ^ true
+! !
+
+!CustomCodeGenerator methodsFor:'testing'!
+
+isCustomCodeGenerator
+ ^ true
+! !
+
+!CustomCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorClassGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,122 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomNewClassGenerator subclass:#CustomCodeGeneratorClassGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomCodeGeneratorClassGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGeneratorClassGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Generates template class for code generator'
+
+ "Modified: / 29-03-2014 / 19:38:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #(Generators)
+
+ "Created: / 22-08-2014 / 18:48:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'New Code Generator'
+
+ "Modified: / 29-03-2014 / 19:21:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 22-08-2014 / 18:50:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGenerator methodsFor:'accessing - ui'!
+
+defaultClassName
+
+ ^ 'CustomXXXCodeGenerator'
+
+ "Created: / 09-11-2014 / 01:13:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newClassNameLabel
+
+ ^ 'Enter class name for new generator'
+
+ "Created: / 09-11-2014 / 01:14:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGenerator methodsFor:'executing - private'!
+
+buildForClass: aClass
+
+ aClass
+ superclassName: #'SmallSense::CustomCodeGenerator';
+ category: self class category.
+
+ "Created: / 09-11-2014 / 01:15:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 20:55:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorClassGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,98 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeGeneratorClassGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomCodeGeneratorClassGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGeneratorClassGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+ ^ CustomCodeGeneratorClassGenerator new
+
+ "Created: / 27-09-2014 / 11:27:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-11-2014 / 23:17:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGeneratorTests methodsFor:'tests'!
+
+test_code_generator_class_created
+
+ | newGenerator testClassName |
+
+ testClassName := #SmallSense::CustomCodeGeneratorForTestCase.
+
+ self assertClassNotExists: testClassName.
+
+ generatorOrRefactoring dialog answer: testClassName forSelector: #requestClassName:initialAnswer:.
+
+ generatorOrRefactoring executeInContext: CustomBrowserContext new.
+
+ newGenerator := Smalltalk classNamed: testClassName.
+
+ self assertClassExists: testClassName.
+ self assert: (newGenerator includesSelector: #buildInContext:).
+ self assert: (newGenerator class includesSelector: #buildInContext:) not.
+ self assert: (newGenerator includesSelector: #availableInContext:) not.
+ self assert: (newGenerator class includesSelector: #availableInContext:).
+
+ "Created: / 31-03-2014 / 23:20:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-11-2014 / 23:22:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 20:49:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,663 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomCodeGeneratorOrRefactoring
+ instanceVariableNames:'compositeChangeCollector compositeChangeNesting userPreferences
+ confirmChanges dialog changeManager model refactoryBuilder
+ formatter resources'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+!
+
+subGeneratorOrRefactoringOf:aCodeGeneratorOrRefactoring
+ "Returns and initializes new instance of code generator or refactoring
+ to be used inside another code generator or refactoring."
+ | nestingCount |
+
+ nestingCount := aCodeGeneratorOrRefactoring compositeChangeNesting.
+ nestingCount isNil ifTrue:[ nestingCount := 0 ].
+
+ ^ self new
+ model:aCodeGeneratorOrRefactoring model;
+ refactoryBuilder:aCodeGeneratorOrRefactoring refactoryBuilder;
+ userPreferences:aCodeGeneratorOrRefactoring userPreferences;
+ dialog:aCodeGeneratorOrRefactoring dialog;
+ changeManager:aCodeGeneratorOrRefactoring changeManager;
+ compositeChangeCollector:aCodeGeneratorOrRefactoring compositeChangeCollector;
+ compositeChangeNesting:(1 + nestingCount);
+ yourself
+
+ "Created: / 19-04-2014 / 10:15:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 13-10-2014 / 20:32:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ self subclassResponsibility
+
+ "Created: / 01-12-2013 / 00:18:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #()
+
+ "Created: / 01-12-2013 / 00:21:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 05-08-2014 / 13:23:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ self subclassResponsibility
+
+ "Created: / 01-12-2013 / 00:18:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'enumerating'!
+
+generatorsAndRefactoringsDo: aOneArgBlock
+ "Evaluates a block through all generator or refactoring classes (actually all my subclasses)."
+
+ self allSubclassesDo: aOneArgBlock
+
+ "Created: / 28-12-2014 / 11:44:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'executing'!
+
+executeInContext: aCustomContext
+ ^ self new executeInContext: aCustomContext
+
+ "Created: / 26-01-2014 / 13:42:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+executeInContextWithWaitCursor: aCustomContext
+ ^ self new executeInContextWithWaitCursor: aCustomContext
+
+ "Created: / 10-08-2014 / 09:34:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'private'!
+
+canUseRefactoringSupport
+ "check if refactory browser stuff is avaliable"
+
+ ^ RefactoryChangeManager notNil
+ and:[RefactoryChangeManager isLoaded
+ and:[UserPreferences current useRefactoringSupport]]
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'queries'!
+
+availableForProgrammingLanguages
+ "Returns list of programming language instances for which this generator / refactoring works.
+ (SmalltalkLanguage instance, JavaLanguage instance, GroovyLanguage instance, etc.)
+
+ See also availableForProgrammingLanguagesInContext:withPerspective:"
+
+ "We are assuming here that majority will be written for Smalltalk."
+ ^ {SmalltalkLanguage instance}
+
+ "Created: / 22-12-2014 / 20:12:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableForProgrammingLanguagesInContext: aCustomContext
+ "Returns true if generator / refactoring works for programming languages
+ of codebase elements (classes, methods, etc.) in CustomContext instance.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomMenuBuilder for details."
+
+ | languages perspective |
+
+ perspective := aCustomContext perspective.
+ perspective isNil ifTrue: [
+ "Rather no quess if perspective is missing"
+ ^ true
+ ].
+
+ languages := self availableForProgrammingLanguages.
+
+ perspective isCodeViewPerspective ifTrue: [
+ ^ aCustomContext selectedCodes ? #() anySatisfy: [ :codeSelection |
+ | method |
+
+ method := codeSelection selectedMethod.
+
+ method notNil and: [ languages includes: method programmingLanguage ]
+ ].
+ ].
+
+ perspective isMethodPerspective ifTrue: [
+ aCustomContext selectedMethods isEmptyOrNil ifTrue: [ ^ true ].
+
+ ^ aCustomContext selectedMethods anySatisfy: [ :method |
+ method notNil and: [ languages includes: method programmingLanguage ]
+ ].
+ ].
+
+ (perspective isClassPerspective
+ or: [ perspective isInstanceVariablePerspective ]
+ or: [ perspective isProtocolPerspective ]) ifTrue: [
+
+ aCustomContext selectedClasses isEmptyOrNil ifTrue: [ ^ true ].
+
+ ^ aCustomContext selectedClasses anySatisfy: [ :class |
+ class notNil and: [ languages includes: class programmingLanguage ]
+ ].
+ ].
+
+ "For other perspectives (package, class category, namespace) no guess"
+ ^ true
+
+ "Created: / 22-12-2014 / 20:34:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-12-2014 / 09:31:32 / root"
+ "Modified: / 24-01-2015 / 18:24:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInContext: aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ self subclassResponsibility
+
+ "Created: / 01-12-2013 / 00:13:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ ^ self subclassResponsibility
+
+ "Created: / 26-01-2014 / 13:03:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'testing'!
+
+isAbstract
+ ^ self == CustomCodeGeneratorOrRefactoring
+
+ "Created: / 26-01-2014 / 21:38:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isCustomCodeGenerator
+ ^ false
+!
+
+isCustomRefactoring
+ ^ false
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'accessing'!
+
+changeManager
+
+ ^ changeManager
+
+ "Created: / 31-05-2014 / 13:29:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+changeManager: aChangeManager
+
+ changeManager := aChangeManager
+
+ "Created: / 31-05-2014 / 13:30:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+compositeChangeCollector
+
+ ^ compositeChangeCollector
+
+ "Created: / 19-04-2014 / 10:18:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+compositeChangeCollector: aCompositeChangeCollector
+
+ compositeChangeCollector := aCompositeChangeCollector
+
+ "Created: / 19-04-2014 / 10:18:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+compositeChangeNesting
+
+ ^ compositeChangeNesting
+
+ "Created: / 11-05-2014 / 14:01:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+compositeChangeNesting: aNumber
+
+ compositeChangeNesting := aNumber
+
+ "Created: / 11-05-2014 / 14:01:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+dialog
+
+ ^ dialog
+
+ "Created: / 11-05-2014 / 00:27:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+dialog: aDialog
+
+ dialog := aDialog
+
+ "Created: / 11-05-2014 / 00:27:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter
+
+ ^ formatter
+
+ "Created: / 19-09-2014 / 22:18:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter: aSourceCodeFormatter
+
+ formatter := aSourceCodeFormatter
+
+ "Created: / 19-09-2014 / 22:18:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+model
+ ^model
+
+ "Created: / 23-08-2014 / 00:13:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+model: aModel
+
+ model := aModel
+
+ "Created: / 23-08-2014 / 00:13:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 09-10-2014 / 10:17:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+refactoryBuilder
+
+ ^ refactoryBuilder
+
+ "Modified (format): / 23-08-2014 / 00:14:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+refactoryBuilder: aRefactoryBuilder
+
+ refactoryBuilder := aRefactoryBuilder.
+
+ "Modified (format): / 23-08-2014 / 00:14:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+sourceCodeGenerator
+
+ ^ model sourceCodeGenerator
+
+ "Created: / 19-09-2014 / 20:56:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 07-10-2014 / 22:47:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+userPreferences
+
+ ^ userPreferences
+
+ "Created: / 09-06-2014 / 21:49:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+userPreferences: aUserPreferences
+
+ userPreferences := aUserPreferences
+
+ "Created: / 09-06-2014 / 21:49:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'bulk changes'!
+
+executeCollectedChangesNamed:name
+ "
+ Same as CodeGeneratorTool >> executeCollectedChangesNamed:,
+ but with custom RefactoryChangeManager and custom Dialog
+ "
+
+ compositeChangeCollector notNil ifTrue:[
+ compositeChangeNesting := compositeChangeNesting - 1.
+ compositeChangeNesting == 0 ifTrue:[
+ compositeChangeCollector name:name.
+ compositeChangeCollector changesSize == 0 ifTrue:[
+ dialog information: (resources string: 'Nothing generated.').
+ ] ifFalse:[
+ changeManager performChange: compositeChangeCollector
+ ].
+ compositeChangeCollector := nil.
+ self model changes: CompositeRefactoryChange new.
+ ]
+ ]
+
+ "Created: / 31-05-2014 / 11:30:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 10:42:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 25-01-2015 / 14:31:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+startCollectChanges
+ (self canUseRefactoringSupport) ifTrue:[
+ compositeChangeCollector isNil ifTrue:[
+ compositeChangeCollector := model changes.
+ compositeChangeNesting := 0.
+ ].
+ compositeChangeNesting := compositeChangeNesting + 1.
+ ]
+
+ "Modified: / 16-11-2014 / 10:43:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'code generation'!
+
+addChange: aCodeChange
+
+ aCodeChange notNil ifTrue: [
+ compositeChangeCollector addChange: aCodeChange
+ ]
+
+ "Created: / 23-08-2014 / 15:40:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 17-09-2014 / 22:53:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring 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:categoryOrNil skipIfSame:skipIfSame
+ "Install some code for a class.
+ If refactory browser stuff is avaliable the refactory tools are used to support undo
+ (determined by aClass - can be RBClass/RBMetaclass instance or real class)"
+
+ |compiler selector oldMethod isSame category|
+
+ isSame := false.
+ category := categoryOrNil ? (Compiler defaultMethodCategory).
+
+ skipIfSame ifTrue:[
+ compiler := aClass compilerClass new.
+ compiler parseMethod:theCode in:aClass ignoreErrors:true ignoreWarnings:true.
+
+ selector := compiler selector.
+ selector notNil ifTrue:[
+ oldMethod := aClass compiledMethodAt:selector.
+ isSame := (oldMethod notNil and:[oldMethod source = theCode]).
+ isSame ifTrue:[^ self ].
+ oldMethod notNil ifTrue:[
+ category := categoryOrNil ? (oldMethod category).
+ ].
+ ].
+ ].
+
+ aClass compile: theCode classified: category.
+
+ "Modified: / 21-08-2006 / 18:39:06 / cg"
+ "Modified (format): / 21-01-2012 / 10:40:59 / cg"
+ "Modified (comment): / 08-02-2015 / 19:40:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'executing'!
+
+executeInContext: aCustomContext
+ | context |
+
+ context := aCustomContext copyWithModel: self model.
+
+ self startCollectChanges.
+
+ context isInteractiveContext ifTrue:[
+ self configureInContext: context
+ ].
+
+ self validateInContext: context.
+ self buildInContext: context.
+
+ self executeCollectedChangesNamed: self class description.
+
+ "Created: / 19-03-2014 / 18:45:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-09-2014 / 11:04:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 21:07:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+executeInContextWithWaitCursor: aCustomContext
+ "Much like executeInContext: but with loading cursor animation"
+
+ | wg executor |
+
+ wg := WindowGroup activeGroup.
+ wg isNil ifTrue:[
+ executor := [:whatToDo | whatToDo value ]
+ ] ifFalse:[
+ executor := [:whatToDo | wg withWaitCursorDo: [ whatToDo value ] ]
+ ].
+
+ executor value:[
+ self executeInContext: aCustomContext
+ ]
+
+ "Created: / 07-08-2014 / 23:17:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+executeSubGeneratorOrRefactoringClasses:aSubGeneratorOrRefactoringClasses inContext:aCustomContext
+ "For each code generator or refactoring class initializes an instance
+ and executes it."
+
+ aSubGeneratorOrRefactoringClasses do:[ :class |
+ (class subGeneratorOrRefactoringOf:self)
+ executeInContext:aCustomContext
+ ]
+
+ "Created: / 08-07-2014 / 18:31:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 13-10-2014 / 20:25:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'executing - private'!
+
+buildInContext:aCustomContext
+ "Should generate code or perform custom refactoring."
+
+ ^ self subclassResponsibility
+
+ "Created: / 16-09-2014 / 09:14:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 13-10-2014 / 17:21:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+configureInContext:aCustomContext
+ "Perform neccessary configuration for given context, such as
+ computing default values for parameters. This may interact with
+ user by means of opening a dialog.
+
+ This method is called only for interactive contexts. When using
+ non interactively, a caller must do the configuration itself by means
+ of accessors."
+
+ "/ To be overridden by subclasses
+
+ "Created: / 16-09-2014 / 07:24:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 16-09-2014 / 11:00:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+validateInContext: aCustomContext
+
+ "/ To be overridden by subclasses
+
+ "Created: / 16-09-2014 / 09:45:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring 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.
+ "Translated dialogs have to be in part of browser, so use browser resources"
+ resources := Tools::NewSystemBrowser classResources.
+
+ self initializeFormatter;
+ initializeChangeManager;
+ initializeModel;
+ initializeRefactoryBuilder;
+ initializeDialog.
+
+ "Created: / 17-03-2014 / 22:27:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-02-2015 / 20:17:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeChangeManager
+ changeManager := CustomBrowserChangeManager new.
+
+ "Created: / 09-06-2014 / 22:56:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeDialog
+ dialog := CustomUserDialog new.
+
+ "Created: / 09-06-2014 / 22:57:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeFormatter
+ formatter := CustomRBLocalSourceCodeFormatter new
+
+ "Created: / 18-09-2014 / 23:12:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeModel
+ model := (CustomNamespace new)
+ formatter:formatter;
+ changeManager:changeManager;
+ yourself
+
+ "Created: / 09-06-2014 / 22:56:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 10:41:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeRefactoryBuilder
+ refactoryBuilder := (CustomRefactoryBuilder new)
+ formatter:formatter;
+ changeManager:changeManager;
+ model:model;
+ yourself
+
+ "Created: / 23-08-2014 / 00:05:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 10:41:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'private'!
+
+canUseRefactoringSupport
+ "check if refactory browser stuff is avaliable"
+
+ ^ self class canUseRefactoringSupport
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'testing'!
+
+isCustomCodeGenerator
+ ^ false
+!
+
+isCustomRefactoring
+ ^ false
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoringTestCase.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,366 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomCodeGeneratorOrRefactoringTestCase
+ instanceVariableNames:'context model refactoryBuilder generatorOrRefactoring classes
+ changeManager userPreferences mock formatter dialog'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomCodeGeneratorOrRefactoringTestCase class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'accessing'!
+
+generatorOrRefactoring
+ "Should return an instance of CustomCodeGenerator or CustomRefactoring subclass"
+
+ ^ self subclassResponsibility
+
+ "Created: / 27-05-2014 / 19:16:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 23-08-2014 / 11:38:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'asserting'!
+
+assertClassExists: aClassName
+
+ self assert: (Smalltalk classNamed: aClassName asString) isNil not
+
+ "Created: / 15-06-2014 / 16:42:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertClassMethodSource: aSourceCode atSelector: aSelector
+ "Assert that source code is same at given selector for first generated class"
+
+ | className class |
+
+ className := classes first name.
+ class := Smalltalk classNamed: className.
+
+ ^ self assertClassMethodSource: aSourceCode atSelector: aSelector forClass: class
+
+ "Created: / 11-07-2014 / 20:11:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-10-2014 / 18:58:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertClassMethodSource: expectedSource atSelector: aSelector forClass: aClass
+ "Assert that source code is same at given selector for given class"
+
+ | actualSource |
+
+ actualSource := aClass theMetaclass sourceCodeAt: aSelector asSymbol.
+
+ ^ self assertSource: expectedSource sameAs: actualSource
+
+ "Created: / 11-07-2014 / 20:09:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertClassNotExists: aClassName
+
+ self assert: (Smalltalk classNamed: aClassName asString) isNil
+
+ "Created: / 15-06-2014 / 16:42:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertMethodCount: aNumber inClass: aClass
+ | realClass |
+
+ realClass := Smalltalk at: (aClass theNonMetaclass name asSymbol).
+
+ self assert: aNumber = (realClass methodDictionary size).
+
+ "Created: / 26-09-2014 / 10:48:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertMethodSource: aSourceCode atSelector: aSelector
+ "Assert that source code is same at given selector for first generated class"
+
+ | className class |
+
+ className := classes first name.
+ class := Smalltalk at: className.
+
+ ^ self assertMethodSource: aSourceCode atSelector: aSelector forClass: class
+
+ "Created: / 27-05-2014 / 20:06:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 26-09-2014 / 00:15:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertMethodSource: expectedSource atSelector: aSelector forClass: aClass
+ "Assert that source code is same at given selector for given class"
+
+ | actualSource |
+
+ actualSource := aClass sourceCodeAt: aSelector asSymbol.
+
+ ^ self assertSource: expectedSource sameAs: actualSource
+
+ "Created: / 27-05-2014 / 20:08:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertSource: expectedSource sameAs: actualSource
+
+ self assert: (Change isSource: expectedSource sameSourceAs: actualSource)
+
+ "Created: / 25-05-2014 / 22:18:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-07-2014 / 11:31:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'code generation helpers'!
+
+createClass
+ "Returns new class change with some name"
+
+ | class |
+
+ class := model createClass
+ name: #DummyClassForGeneratorTestCase;
+ compile;
+ yourself.
+
+ classes add: class.
+
+ ^ class
+
+ "Created: / 29-05-2014 / 23:22:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 09-10-2014 / 10:34:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'context templates'!
+
+classWithInstanceVariable
+ | class |
+
+ class := self createClass.
+ class instanceVariableNames: (Array with: 'instanceVariable'); compile.
+
+ context selectedClasses: (Array with: class).
+
+ ^ class
+
+ "Created: / 29-05-2014 / 00:33:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-11-2014 / 19:17:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classWithThreeInstanceVariables
+ | class |
+
+ class := self createClass.
+ class instanceVariableNames: (Array with: 'instanceVariable_01' with: 'instanceVariable_02' with: 'instanceVariable_03'); compile.
+
+ context selectedClasses: (Array with: class).
+ context selectedVariables: (class instanceVariableNames).
+
+ ^ class
+
+ "Created: / 13-07-2014 / 21:56:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-11-2014 / 19:18:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classWithTwoInstanceVariables
+ | class |
+
+ class := self createClass.
+ class instanceVariableNames: (Array with: 'instanceVariable_01' with: 'instanceVariable_02'); compile.
+
+ context selectedClasses: (Array with: class).
+ context selectedVariables: (class instanceVariableNames).
+
+ ^ class
+
+ "Created: / 13-07-2014 / 21:45:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-11-2014 / 19:18:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'executing'!
+
+createContext: contextTemplateName
+ "Creates context by given template name
+ (produces more readable code than just method call)"
+
+ self perform: contextTemplateName asSymbol
+
+ "Created: / 27-07-2014 / 12:27:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+executeGeneratorInContext: contextTemplateName
+ "Executes generator in context created by given name"
+
+ self perform: contextTemplateName asSymbol.
+ generatorOrRefactoring executeInContext: context
+
+ "Created: / 27-05-2014 / 20:03:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-05-2014 / 23:38:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'initialization & release'!
+
+defaultUserPreferences
+
+ userPreferences
+ generateComments: true;
+ generateCommentsForAspectMethods: true;
+ generateCommentsForGetters: true;
+ generateCommentsForSetters: true
+
+ "Created: / 09-06-2014 / 22:36:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUp
+ Screen current isNil ifTrue:[
+ Smalltalk openDisplay.
+ Screen current isNil ifTrue:[
+ self assert: false description: 'Tests need display connection'.
+ ]
+ ].
+
+ classes := OrderedCollection new.
+ mock := CustomMock new.
+ dialog := CustomSilentDialog new.
+
+ context := CustomSubContext new.
+
+ changeManager := CustomLocalChangeManager new.
+ self setUpBuilders.
+
+ userPreferences := UserPreferences new.
+ self defaultUserPreferences.
+ generatorOrRefactoring := self generatorOrRefactoring.
+
+ self setUpTestFormatter.
+
+ generatorOrRefactoring notNil ifTrue: [
+ self setUpGeneratorOrRefactoring: generatorOrRefactoring
+ ].
+
+ "Created: / 27-05-2014 / 19:16:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 14:39:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUpBuilders
+
+ model := CustomNamespace new.
+ model changeManager: changeManager.
+
+ refactoryBuilder := CustomRefactoryBuilder new.
+ refactoryBuilder changeManager: changeManager.
+ refactoryBuilder model: model.
+
+ "Created: / 23-08-2014 / 15:57:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-10-2014 / 19:49:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUpGeneratorOrRefactoring: aGeneratorOrRefactoring
+
+ aGeneratorOrRefactoring
+ formatter: formatter;
+ model: model;
+ refactoryBuilder: refactoryBuilder;
+ changeManager: changeManager;
+ userPreferences: userPreferences;
+ dialog: dialog
+
+ "Created: / 23-08-2014 / 15:59:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-10-2014 / 11:03:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUpTestFormatter
+
+ formatter := CustomRBLocalSourceCodeFormatter new.
+ formatter
+ tabIndent: 4;
+ spaceAroundTemporaries: false;
+ emptyLineAfterTemporaries: true;
+ emptyLineAfterMethodComment: true;
+ spaceAfterReturnToken: true;
+ spaceAfterKeywordSelector: false;
+ spaceAfterBlockStart: true;
+ spaceBeforeBlockEnd: true;
+ cStyleBlocks: true;
+ blockArgumentsOnNewLine: false;
+ maxLengthForSingleLineBlocks: 4;
+ periodAfterLastStatementPolicy: #keep.
+ "
+ EmptyLineBeforeFinalMethodComment := true.
+ SpaceAroundLiteralArrayElements := true.
+ STXStyleMethodComments := true.
+ "
+ model formatter: formatter.
+ refactoryBuilder formatter: formatter
+
+ "Created: / 28-08-2014 / 23:29:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 31-08-2014 / 17:23:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ changeManager undoChanges.
+ mock unmockAll
+
+ "Created: / 27-05-2014 / 19:26:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-10-2014 / 14:56:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'running'!
+
+runCase
+ "Run the case and do not add any mess into the changes file (st.chg)."
+
+ Class withoutUpdatingChangesDo: [
+ super runCase
+ ]
+
+ "Created: / 30-11-2014 / 17:02:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,154 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomTestCaseCodeGenerator subclass:#CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ ^ 'Creates a new test case for custom code generator/refactoring'
+
+ "Modified: / 23-08-2014 / 19:50:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-09-2014 / 11:33:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Generators')
+
+ "Created: / 22-08-2014 / 18:50:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ ^ 'New Code Generator Testcase'
+
+ "Modified: / 23-08-2014 / 19:50:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 22-08-2014 / 18:50:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ | classes |
+
+ classes := aCustomContext selectedClasses.
+ ^ classes notEmpty
+ and:[ classes allSatisfy: [:e | e inheritsFrom: CustomCodeGeneratorOrRefactoring ] ].
+
+ "Created: / 15-09-2014 / 15:19:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultTestSuperName
+ ^ 'CustomCodeGeneratorOrRefactoringTestCase'
+
+ "Created: / 16-09-2014 / 10:32:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator methodsFor:'executing - private'!
+
+generateTestCaseCodeFor:aTestClass forClassUnderTest:aClass
+ | source className package |
+
+ super generateTestCaseCodeFor:aTestClass forClassUnderTest:aClass.
+ className := aClass theNonMetaClass name.
+
+ package := PackageId noProjectID.
+ samePackageAsTestedClass ifTrue: [
+ package := aClass package
+ ].
+
+ source := 'test_code_generated
+ | expectedSource |
+
+ expectedSource := ''instanceVariable
+ ^ instanceVariable''.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable'.
+
+ model createMethod
+ class: aTestClass;
+
+ protocol: 'tests';
+ source: source;
+ package: package;
+ compile.
+
+ model createMethod
+ class: aTestClass;
+
+ protocol: 'accessing';
+ source: 'generatorOrRefactoring
+ ^ `className new';
+ replace: '`className' with: className asString;
+ package: package;
+ compile
+
+ "Created: / 16-09-2014 / 10:40:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 31-01-2015 / 18:39:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoringTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,492 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeGeneratorOrRefactoringTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomCodeGeneratorOrRefactoringTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGeneratorOrRefactoringTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ | generatorMock |
+
+ generatorMock := mock mockOf: CustomCodeGeneratorOrRefactoring.
+ generatorMock class compileMockMethod: 'description ^ ''''. '.
+ ^ generatorMock
+
+ "Created: / 10-11-2014 / 22:04:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-11-2014 / 23:46:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTests methodsFor:'tests'!
+
+test_all_my_non_abstract_implementors_have_filled_label_and_description
+
+ CustomCodeGeneratorOrRefactoring allSubclassesDo:[ :subclass |
+ "Include only non abstract and non mock classes"
+ (subclass isAbstract or: [ (subclass includesSelector: #compileMockMethod:) ]) ifFalse:[
+ self assert: subclass label notEmptyOrNil.
+ self assert: subclass description notEmptyOrNil
+ ]
+ ]
+
+ "Created: / 18-10-2014 / 13:38:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:02:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages
+ | expectedLanguages actualLanguages |
+
+ expectedLanguages := {SmalltalkLanguage instance}.
+ actualLanguages := generatorOrRefactoring class availableForProgrammingLanguages.
+
+ self assert: expectedLanguages = actualLanguages
+
+ "Modified: / 22-12-2014 / 13:38:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective
+
+ context
+ perspective: CustomPerspective classPerspective;
+ selectedClasses: (Array with: self class).
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 13:43:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective_empty
+
+ context perspective: CustomPerspective classPerspective.
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 13:40:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective_empty_class
+
+ context
+ perspective: CustomPerspective classPerspective;
+ selectedClasses: (Array with: nil).
+
+ self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 24-01-2015 / 18:27:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective_java
+ | class |
+
+ "Prepare model class otherwise we would need real existing java class to test functionality"
+ class := RBClass new
+ realClass: JavaClass new;
+ yourself.
+
+ context
+ perspective: CustomPerspective classPerspective;
+ selectedClasses: (Array with: class).
+
+ self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 13:44:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective_java_and_smalltalk
+ | class |
+
+ "Prepare model class otherwise we would need real existing java class to test functionality"
+ class := RBClass new
+ realClass: JavaClass new;
+ yourself.
+
+ context
+ perspective: CustomPerspective classPerspective;
+ selectedClasses: (Array with: class with: self class).
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 13:53:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_code_view_perspective
+
+ context
+ perspective: CustomPerspective codeViewPerspective;
+ selectedCodes: (Array with:
+ (CustomSourceCodeSelection new
+ selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring);
+ yourself)).
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 12:08:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_code_view_perspective_empty_method
+
+ context
+ perspective: CustomPerspective codeViewPerspective;
+ selectedCodes: (Array with: CustomSourceCodeSelection new).
+
+ self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 12:14:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_method_perspective
+
+ context
+ perspective: CustomPerspective methodPerspective;
+ selectedMethods: (Array with: (self class compiledMethodAt: #generatorOrRefactoring)).
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 12:37:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_method_perspective_and_empty_method
+
+ context
+ perspective: CustomPerspective methodPerspective;
+ selectedMethods: (Array with: nil).
+
+ self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 24-01-2015 / 18:29:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_method_perspective_empty
+
+ context perspective: CustomPerspective methodPerspective.
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 12:38:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_protocol_perspective_empty
+
+ context perspective: CustomPerspective protocolPerspective.
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 13:41:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_with_class_category_perspective
+
+ context perspective: CustomPerspective classCategoryPerspective.
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 13:42:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_with_code_view_perspective
+
+ context perspective: CustomPerspective codeViewPerspective.
+
+ self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 26-12-2014 / 23:09:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 27-12-2014 / 12:04:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_with_package_perspective
+
+ context perspective: CustomPerspective packagePerspective.
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Created: / 27-12-2014 / 13:42:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_sub_context
+
+ self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+ "Modified: / 26-12-2014 / 23:05:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_in_category_skip_if_same_change_reflected_in_model
+ | expectedSource class realClass |
+
+ class := model createClass
+ name: #DummyClass01;
+ compile;
+ yourself.
+
+ expectedSource := 'selector01 ^ 456'.
+
+ generatorOrRefactoring compile: expectedSource
+ forClass: class
+ inCategory: nil
+ skipIfSame: true.
+
+ self assertMethodSource: expectedSource atSelector: #selector01 forClass: class.
+ self assertClassNotExists: #DummyClass01.
+
+ generatorOrRefactoring compileMockMethod: 'buildInContext:context';
+ executeInContext: context.
+
+ realClass := Smalltalk at: #DummyClass01.
+
+ self assertMethodSource: expectedSource atSelector: #selector01 forClass: realClass.
+
+ "Modified: / 08-02-2015 / 19:49:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_in_category_skip_if_same_not_skipped
+ | expectedChangeSize actualChangeSize class |
+
+ class := model createClass
+ name: #DummyClass01;
+ compile;
+ yourself.
+
+ class compile: 'selector01 ^ 456'.
+
+ generatorOrRefactoring compile: 'selector01 ^ 4567'
+ forClass: class
+ inCategory: nil
+ skipIfSame: true.
+
+ expectedChangeSize := 3.
+ actualChangeSize := model changes changesSize.
+
+ self assert: expectedChangeSize = actualChangeSize
+
+ "Created: / 08-02-2015 / 20:03:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_in_category_skip_if_same_real_class
+ | expectedSource class |
+
+ class := model createClassImmediate: #DummyClass01.
+
+ expectedSource := 'selector01 ^ 456'.
+
+ generatorOrRefactoring compile: expectedSource
+ forClass: class
+ inCategory: nil
+ skipIfSame: true.
+
+ self assertMethodSource: expectedSource atSelector: #selector01 forClass: class.
+ self assertClassExists: #DummyClass01.
+
+ "Created: / 08-02-2015 / 19:51:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_in_category_skip_if_same_skipped
+ | expectedChangeSize actualChangeSize class source |
+
+ class := model createClass
+ name: #DummyClass01;
+ compile;
+ yourself.
+
+ source := 'selector01 ^ 456'.
+ class compile: source.
+
+ generatorOrRefactoring compile: source
+ forClass: class
+ inCategory: nil
+ skipIfSame: true.
+
+ expectedChangeSize := 2.
+ actualChangeSize := model changes changesSize.
+
+ self assert: expectedChangeSize = actualChangeSize
+
+ "Created: / 08-02-2015 / 19:59:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_in_context_aborted
+ | dialogBox |
+
+ dialogBox := mock mockOf: DialogBox.
+ dialogBox
+ compileMockMethod: 'open ^ nil';
+ compileMockMethod: 'accepted ^ false'.
+
+ dialog := (mock mockOf: CustomUserDialog)
+ compileMockMethod: 'information:arg ^ nil';
+ dialog: dialogBox;
+ yourself.
+
+ context := CustomBrowserContext new.
+ generatorOrRefactoring
+ dialog: dialog;
+ compileMockMethod: 'buildInContext:aContext ^ dialog open'.
+
+ self should: [
+ generatorOrRefactoring executeInContext: context.
+ ] raise: AbortOperationRequest.
+
+ "/ self assert: generatorOrRefactoring == (generatorOrRefactoring executeInContext: context).
+
+ "Modified: / 25-11-2014 / 21:32:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_in_context_not_aborted
+ | dialogBox |
+
+ dialogBox := mock mockOf: DialogBox.
+ dialogBox
+ compileMockMethod: 'open ^ nil';
+ compileMockMethod: 'accepted ^ true'.
+
+ dialog := (mock mockOf: CustomUserDialog)
+ compileMockMethod: 'information:arg ^ nil';
+ dialog: dialogBox;
+ yourself.
+
+ context := CustomBrowserContext new.
+ generatorOrRefactoring
+ dialog: dialog;
+ compileMockMethod: 'buildInContext:aContext ^ dialog open'.
+
+ self shouldnt: [
+ generatorOrRefactoring executeInContext: context.
+ ] raise: AbortOperationRequest.
+
+ "/ self assert: generatorOrRefactoring == (generatorOrRefactoring executeInContext: context).
+
+ "Created: / 10-11-2014 / 23:35:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 21:33:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_in_context_shared_change_collector_with_correct_change_order
+ "We need to check whether each part of generator/refactoring
+ API writes to the same change collector. If we dont preserve correct
+ change order then wrong result may be produced."
+ | class expectedSource |
+
+ generatorOrRefactoring compileMockMethod: 'buildInContext: aContext
+ | class context |
+
+ class := model createClass
+ name: #DummyClass01;
+ category: ''Some-Category-01'';
+ compile;
+ yourself.
+
+ self compile:''selector_01 ^ 1'' forClass:class inCategory:''protocol01''.
+ class removeMethod:#selector_01.
+ class compile:''selector_02 ^ ''''literal02''''. ''.
+
+ context := CustomSubContext new selectedClasses: (Array with: class); yourself.
+ refactoryBuilder replace:''`#literal'' with:''''''literal525'''''' inContext:context.
+ refactoryBuilder changeCategoryOf:class to:''Some-Category-02''.
+ '.
+
+ generatorOrRefactoring executeInContext: context.
+
+ class := Smalltalk at: #DummyClass01.
+
+ self assert: (class category) = #'Some-Category-02'.
+ self assert: (class sourceCodeAt: #selector_01) isNil.
+
+ expectedSource := 'selector_02
+ ^ ''literal525''.'.
+
+ self assertMethodSource: expectedSource atSelector: #selector_02 forClass: class.
+
+ "Created: / 04-12-2014 / 23:24:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_in_context_with_real_class_and_compile_on_model_class
+ | class modelClass |
+
+ generatorOrRefactoring compileMockMethod: 'buildInContext: aContext
+ aContext selectedClasses do: [ :class |
+ class compile: ''selector_01 ^ 1''.
+ ]'.
+
+ class := model createClassImmediate: #DummyClass01.
+ self assert: class isBehavior.
+
+ context selectedClasses: (Array with: class).
+
+ generatorOrRefactoring executeInContext: context.
+
+ modelClass := generatorOrRefactoring model classNamed: #DummyClass01.
+
+ self assert: (class includesSelector: #selector_01).
+ self assert: (modelClass includesSelector: #selector_01)
+
+ "Created: / 24-11-2014 / 23:43:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 20:41:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_do
+ | expectedGenerators actualGenerators |
+
+ expectedGenerators := CustomCodeGeneratorOrRefactoring allSubclasses.
+ actualGenerators := OrderedCollection streamContents: [ :stream |
+ CustomCodeGeneratorOrRefactoring generatorsAndRefactoringsDo: [ :class |
+ stream nextPut: class
+ ].
+ ].
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Modified: / 24-01-2015 / 18:26:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,109 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomCodeGenerator new
+! !
+
+!CustomCodeGeneratorTests methodsFor:'tests'!
+
+test_execute_sub_generator_classes
+ | subGeneratorClass_01 subGeneratorClass_02 expectedSource_01 expectedSource_02 |
+
+ "/ setup context
+ self classWithInstanceVariable.
+
+ subGeneratorClass_01 := mock mockClassOf: CustomCodeGenerator.
+ subGeneratorClass_02 := mock mockClassOf: CustomCodeGenerator.
+
+ subGeneratorClass_01 compileMockMethod: 'description ''01'' '.
+ subGeneratorClass_01 new compileMockMethod: 'buildInContext: aCustomContext
+
+ aCustomContext selectedClasses do: [ :class |
+ model createMethod
+ class: class;
+ source: ''selector_01 ^ 1'';
+ compile.
+ ]'.
+
+ subGeneratorClass_02 compileMockMethod: 'description ''02'' '.
+ subGeneratorClass_02 new compileMockMethod: 'buildInContext: aCustomContext
+
+ aCustomContext selectedClasses do: [ :class |
+ model createMethod
+ class: class;
+ source: ''selector_02 ^ 2'';
+ compile.
+ ]'.
+
+ generatorOrRefactoring
+ executeSubGeneratorOrRefactoringClasses:(Array with:subGeneratorClass_01
+ with:subGeneratorClass_02)
+ inContext:context.
+
+ expectedSource_01 := 'selector_01
+ ^ 1'.
+
+ expectedSource_02 := 'selector_02
+ ^ 2'.
+
+ self assertMethodSource: expectedSource_01 atSelector: #selector_01.
+ self assertMethodSource: expectedSource_02 atSelector: #selector_02.
+
+ "Created: / 10-07-2014 / 12:11:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 16:06:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorUserPreferencesTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,75 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeGeneratorUserPreferencesTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomCodeGeneratorUserPreferencesTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeGeneratorUserPreferencesTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ nil
+
+ "Modified: / 09-06-2014 / 22:42:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorUserPreferencesTests methodsFor:'tests'!
+
+test_user_preferences_same_for_tests
+
+ self assert: userPreferences generateComments.
+ self assert: userPreferences generateCommentsForAspectMethods.
+ self assert: userPreferences generateCommentsForGetters.
+ self assert: userPreferences generateCommentsForSetters.
+
+ "Created: / 09-06-2014 / 22:29:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:49:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeSelectionRefactoring.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,101 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomRefactoring subclass:#CustomCodeSelectionRefactoring
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomCodeSelectionRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Template class for refactorings which operates on selected source code in the text editor.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomCodeSelectionRefactoring class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ aCustomContext selectedCodes ? #() anySatisfy: [ :selectedCode |
+ selectedCode selectedSourceCode notEmptyOrNil
+ ]
+
+ "Created: / 21-08-2014 / 23:28:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:01:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ ^ aCustomPerspective isCodeViewPerspective
+
+ "Created: / 21-08-2014 / 23:28:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-10-2014 / 10:29:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isAbstract
+ "Return if this class is an abstract class.
+ True is returned here for myself only; false for subclasses.
+ Abstract subclasses must redefine again."
+
+ ^ self == CustomCodeSelectionRefactoring.
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeSelectionToResourceTranslation.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,107 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeSelectionRefactoring subclass:#CustomCodeSelectionToResourceTranslation
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomCodeSelectionToResourceTranslation class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Wraps variable, literal, string or expression code selection
+ with following translation call: resources string:'Some string...'
+ Ie.: when 'Some string...' is selected in the code editor then its
+ replaced by: resources string:'Some string...'
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomCodeSelectionToResourceTranslation class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Wrap code selection with translation call - resources string:'
+
+ "Created: / 21-08-2014 / 23:46:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Selection to Resources Translation'
+
+ "Created: / 21-08-2014 / 23:43:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeSelectionToResourceTranslation methodsFor:'executing'!
+
+buildInContext:aCustomContext
+ "Performs a refactoring within given context scope"
+
+ refactoryBuilder
+ replace:'`@expression'
+ with:'(resources string: (`@expression))'
+ inContext:aCustomContext
+
+ "Created: / 23-08-2014 / 00:16:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 22:57:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeSelectionToResourceTranslation class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeSelectionToResourceTranslationTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,256 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeSelectionToResourceTranslationTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings-Tests'
+!
+
+!CustomCodeSelectionToResourceTranslationTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomCodeSelectionToResourceTranslationTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomCodeSelectionToResourceTranslation new
+! !
+
+!CustomCodeSelectionToResourceTranslationTests methodsFor:'tests'!
+
+test_available_in_code_view_perspective
+ | perspective |
+
+ perspective := CustomPerspective codeViewPerspective.
+
+ self assert: (generatorOrRefactoring class availableInPerspective:perspective).
+
+ "Created: / 15-10-2014 / 08:10:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_empty
+
+ self deny: (generatorOrRefactoring class availableInContext: context).
+
+ "Modified: / 15-10-2014 / 09:32:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_empty_selected_codes
+
+ context selectedCodes: (Array
+ with: CustomSourceCodeSelection new
+ ).
+
+ self deny: (generatorOrRefactoring class availableInContext: context).
+
+ "Created: / 15-10-2014 / 09:37:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 22:53:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_with_selected_codes
+
+ context selectedCodes: (Array
+ with: (CustomSourceCodeSelection new
+ selectedInterval: (1 to: 5);
+ currentSourceCode: 'selector_05 ^ 5';
+ yourself)
+ ).
+
+ self assert: (generatorOrRefactoring class availableInContext: context).
+
+ "Created: / 15-10-2014 / 09:41:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_selection_replaced_by_resource_translation_01
+ | expectedSource originalSource codeSelection class |
+
+ originalSource := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ class := model createClassImmediate: 'DummyClassForTestCase01' instanceVariableNames: 'resources'.
+ model createMethodImmediate: class source: originalSource.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: originalSource;
+ selectedClass: class;
+ selectedInterval: (32 to: 48);
+ selectedMethod: (class compiledMethodAt: #selector);
+ selectedSelector: #selector.
+
+ context selectedCodes: (Array with: codeSelection).
+ generatorOrRefactoring executeInContext: context.
+
+ expectedSource := 'selector
+ self information: (resources string:''Translate this'').
+ ^ self.'.
+
+ self assertMethodSource:expectedSource atSelector:#selector forClass:class
+
+ "Created: / 23-08-2014 / 20:09:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-12-2014 / 20:14:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_selection_replaced_by_resource_translation_02
+ | expectedSource originalSource codeSelection class |
+
+ originalSource := 'selector
+ self information: self theInformation.
+ ^ self.'.
+
+ class := model createClassImmediate: 'DummyClassForTestCase01' instanceVariableNames: 'resources'.
+ model createMethodImmediate: class source: originalSource.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: originalSource;
+ selectedClass: class;
+ selectedInterval: (32 to: 51);
+ selectedMethod: (class compiledMethodAt: #selector);
+ selectedSelector: #selector.
+
+ context selectedCodes: (Array with: codeSelection).
+ generatorOrRefactoring executeInContext: context.
+
+ expectedSource := 'selector
+ self information: (resources string:self theInformation).
+ ^ self.'.
+
+ self assertMethodSource:expectedSource atSelector:#selector forClass:class
+
+ "Created: / 15-10-2014 / 09:45:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-12-2014 / 20:14:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_selection_replaced_by_resource_translation_with_keep_package
+ | expectedSource originalSource codeSelection class method compiledMethod |
+
+ originalSource := 'selector
+ self information: self theInformation.
+ ^ self.'.
+
+ class := model createClassImmediate: 'DummyClassForTestCase01' instanceVariableNames: 'resources'.
+ method := model createMethodImmediate: class source: originalSource.
+ method package: #some_package.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: originalSource;
+ selectedClass: class;
+ selectedInterval: (32 to: 51);
+ selectedMethod: (class compiledMethodAt: #selector);
+ selectedSelector: #selector.
+
+ context selectedCodes: (Array with: codeSelection).
+ generatorOrRefactoring executeInContext: context.
+
+ expectedSource := 'selector
+ self information: (resources string:self theInformation).
+ ^ self.'.
+
+ self assertMethodSource:expectedSource atSelector:#selector forClass:class.
+
+ compiledMethod := class compiledMethodAt: #selector.
+
+ self assert: #some_package = (compiledMethod package).
+
+ "Created: / 16-10-2014 / 21:46:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-12-2014 / 20:14:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_selection_replaced_by_resource_translation_with_wrong_selection
+ | expectedSource originalSource codeSelection class |
+
+ originalSource := 'method: arg
+
+ arg ifNil: [
+ self warn: ''nil''.
+ ]
+ ifNotNil: [ self information: ''info'' ]'.
+
+ class := model createClassImmediate: 'DummyClassForTestCase01' instanceVariableNames: 'resources'.
+ model createMethodImmediate: class source: originalSource.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: originalSource;
+ selectedClass: class;
+ selectedInterval: (8 to: 10);
+ selectedMethod: (class compiledMethodAt: #method:);
+ selectedSelector: #selector.
+
+ context selectedCodes: (Array with: codeSelection).
+ generatorOrRefactoring executeInContext: context.
+
+ expectedSource := 'method: arg
+
+ arg ifNil: [
+ self warn: ''nil''.
+ ]
+ ifNotNil: [ self information: ''info'' ]'.
+
+ self assertMethodSource:expectedSource atSelector:#method: forClass:class
+
+ "Created: / 17-10-2014 / 22:31:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_not_available_in_class_perspective
+ | perspective |
+
+ perspective := CustomPerspective classPerspective.
+
+ self deny: (generatorOrRefactoring class availableInPerspective:perspective).
+
+ "Created: / 15-10-2014 / 08:11:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeSelectionToResourceTranslationTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomContext.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,237 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomContext
+ instanceVariableNames:'model perspective'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomContext class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomContext class methodsFor:'instance creation'!
+
+new
+ "Returns an initialized instance"
+
+ ^ self basicNew initialize.
+
+ "Modified: / 19-11-2014 / 09:36:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContext class methodsFor:'queries'!
+
+isAbstract
+ "Return if this class is an abstract class.
+ True is returned here for myself only; false for subclasses.
+ Abstract subclasses must redefine again."
+
+ ^ self == CustomContext.
+! !
+
+!CustomContext methodsFor:'accessing'!
+
+model
+ "Returns a class model on we operate e.g. RBNamespace, CustomNamespace"
+
+ ^ model
+
+ "Modified (comment): / 19-11-2014 / 10:00:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+model: anRBNamespace
+ "see model"
+
+ model := anRBNamespace
+
+ "Modified (format): / 19-11-2014 / 10:01:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+perspective
+ "see CustomPerspective"
+
+ ^ perspective
+
+ "Modified (comment): / 24-12-2014 / 22:39:02 / root"
+!
+
+perspective: aPerspective
+ "see CustomPerspective"
+
+ perspective := aPerspective
+
+ "Created: / 27-12-2014 / 12:02:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'accessing-selection'!
+
+selectedClassCategories
+ "a collection with selected class categories"
+
+ self subclassResponsibility
+
+ "Created: / 05-05-2014 / 00:13:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClasses
+ "a collection with selected classes"
+
+ self subclassResponsibility
+
+ "Created: / 26-04-2014 / 13:13:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 26-04-2014 / 22:38:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedCodes
+ "a collection with source codes (CustomSourceCodeSelection)
+ with selected interval (exact position in source code) and
+ corresponding class, method, selector."
+
+ self subclassResponsibility
+
+ "Created: / 18-08-2014 / 21:28:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethods
+ "a collection with selected methods"
+
+ self subclassResponsibility
+
+ "Created: / 05-05-2014 / 00:12:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedPackages
+ "a collection with selected packages"
+
+ self subclassResponsibility
+
+ "Created: / 05-05-2014 / 00:12:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedProtocols
+ "a collection with selected method protocols"
+
+ self subclassResponsibility
+
+ "Created: / 05-05-2014 / 00:14:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedVariables
+ "a collection with selected variables"
+
+ self subclassResponsibility
+
+ "Created: / 05-05-2014 / 00:14:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'initialization'!
+
+initialize
+
+ model := SmallSense::CustomNamespace onEnvironment: BrowserEnvironment new.
+
+ "Modified: / 19-11-2014 / 09:35:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:07:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'instance creation'!
+
+copyWithModel: aModel
+ "Returs shallow copy with custom class model. It is useful
+ if we need to keep object immutability when we receive it
+ as method parameter. Setting just model could have side effect,
+ because the sender probably does not expect object to be modified,
+ but only read."
+
+ ^ self copy model: aModel; yourself
+
+ "Created: / 25-11-2014 / 19:46:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'private'!
+
+asRBClass: cls
+ "For given real class, return a corresponding RBClass"
+
+ ^ Object isMetaclass
+ ifTrue:[ model metaclassNamed: cls theNonMetaclass name ]
+ ifFalse:[ model classNamed: cls name ]
+
+ "Created: / 14-11-2014 / 19:26:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 19-11-2014 / 09:39:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+asRBMethod: aMethod
+ | rbClass |
+
+ rbClass := self asRBClass: aMethod mclass.
+ ^ rbClass methodFor: aMethod selector
+
+ "Created: / 14-11-2014 / 20:17:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'testing'!
+
+isInteractiveContext
+ "Return true, if this generator/refactoring context is interactive,
+ i.e., if it may interact with user (like asking for class name or
+ similar) or not.
+
+ Generally speaking, only top-level context is interactive an only
+ if generator/refactoring was triggerred from menu.
+ "
+ ^ false
+
+ "Created: / 16-09-2014 / 09:22:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomContext class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomContextTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,113 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomContextTests
+ instanceVariableNames:'context model'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomContextTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomContextTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ model := CustomNamespace new.
+ context := CustomContext new
+ model: model;
+ yourself
+
+ "Modified: / 19-11-2014 / 10:01:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContextTests methodsFor:'tests'!
+
+test_as_rb_class_class
+ | expectedClass actualClass |
+
+ expectedClass := model classNamed: self class name.
+ actualClass := context asRBClass: self class.
+
+ self deny: expectedClass isMeta.
+ self assert: expectedClass == actualClass.
+ self assert: (actualClass realClass) == (self class).
+
+ "Created: / 19-11-2014 / 10:12:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_rb_class_metaclass
+ | expectedMetaclass actualMetaclass class |
+
+ expectedMetaclass := model metaclassNamed: self class name.
+ actualMetaclass := context asRBClass: self class class.
+ class := context asRBClass: self class.
+
+ self assert: expectedMetaclass isMeta.
+ self deny: class isMeta.
+
+ self deny: expectedMetaclass == class.
+ self assert: expectedMetaclass == actualMetaclass.
+ self assert: (expectedMetaclass realClass) == (self class class).
+
+ "Modified: / 19-11-2014 / 10:13:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_copy_with_model
+ | contextCopy newModel |
+
+ newModel := CustomNamespace new.
+ contextCopy := context copyWithModel: newModel.
+
+ self deny: context == contextCopy.
+ self deny: (context model) == newModel.
+ self assert: (context model) == model.
+ self assert: (contextCopy model) == newModel.
+
+ "Modified: / 25-11-2014 / 19:53:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomDefaultGetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,128 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomDefaultGetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomDefaultGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomDefaultGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+ ^ 'Getter methods for default variable value in metaclass'
+
+ "Created: / 30-06-2014 / 11:14:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Getters')
+
+ "Created: / 22-08-2014 / 18:54:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+ ^ 'Getter Method(s) for default variable value'
+
+ "Created: / 30-06-2014 / 11:15:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDefaultGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns getter method source code for default variable value"
+
+ | comment |
+
+ comment := ''.
+
+ userPreferences generateCommentsForGetters ifTrue:[
+ comment := '"default value for the ''%1'' instance variable (automatically generated)"'.
+ comment := comment bindWith: aName.
+ ].
+
+ ^ self sourceCodeGenerator
+ source: '`@methodName
+ `"comment
+
+ self shouldImplement.
+ ^ nil';
+ replace: '`@methodName' with: (self defaultMethodNameFor: aName) asSymbol;
+ replace: '`"comment' with: comment;
+ newSource.
+
+ "Created: / 30-06-2014 / 10:49:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-09-2014 / 22:34:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDefaultGetterMethodsCodeGenerator methodsFor:'protected'!
+
+methodClass: aClass
+ "Assure that method is generated only for metaclass."
+
+ ^ aClass theMetaclass
+
+ "Created: / 30-06-2014 / 11:11:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDefaultGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomDefaultGetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,96 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomDefaultGetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomDefaultGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomDefaultGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomDefaultGetterMethodsCodeGenerator new
+! !
+
+!CustomDefaultGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_default_getter_method_generated_with_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: true.
+
+ expectedSource := 'defaultInstanceVariable
+ "default value for the ''instanceVariable'' instance variable (automatically generated)"
+
+ self shouldImplement.
+ ^ nil'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertClassMethodSource: expectedSource atSelector: #defaultInstanceVariable
+
+ "Created: / 30-06-2014 / 13:31:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-07-2014 / 20:11:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_default_getter_method_generated_without_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: false.
+
+ expectedSource := 'defaultInstanceVariable
+ self shouldImplement.
+ ^ nil'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertClassMethodSource: expectedSource atSelector: #defaultInstanceVariable
+
+ "Created: / 30-06-2014 / 11:31:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-07-2014 / 20:11:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomDialog.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,209 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomDialog
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-UI'
+!
+
+!CustomDialog class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ A simple factory for user dialogs.
+
+ Note: in future, API of this class will be merged into DialogBox and
+ CustomDialog and subclasses will vanish.
+
+ [author:]
+ Jan Vrany <jan.vrany@fit.cvut.cz>
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+ [instance variables:]
+
+ [class variables:]
+
+ [see also:]
+
+"
+! !
+
+!CustomDialog class methodsFor:'testing'!
+
+isAbstract
+ ^ self == CustomDialog
+! !
+
+!CustomDialog methodsFor:'common dialogs'!
+
+requestClassName: label initialAnswer:initial
+
+ | holder |
+
+ holder := ValueHolder with: initial.
+ self addClassNameEntryOn: holder labeled: 'Class' validateBy: nil.
+ self addAbortAndOkButtons.
+ self open ifTrue:[
+ ^ holder value
+ ]
+
+ "
+ CustomUserDialog new requestClassName: 'Select class' initialAnswer: 'Array'.
+ "
+
+ "Created: / 10-05-2014 / 15:33:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 15-09-2014 / 16:26:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 21:10:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDialog methodsFor:'construction-adding'!
+
+addAbortAndOkButtons
+ ^ self subclassResponsibility
+
+ "Created: / 15-09-2014 / 16:20:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addButtons
+ self addAbortAndOkButtons
+
+ "Created: / 15-09-2014 / 18:56:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addCheckBoxOn: aValueModel labeled: aString
+ | checkbox |
+
+ checkbox := CheckBox new.
+ checkbox model: aValueModel.
+ checkbox label: aString.
+
+ ^ self addComponent: checkbox labeled: nil.
+
+ "Created: / 15-09-2014 / 18:11:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addComponent:aView
+ "Add given component. Component is automatically stretched to occupy windows' width"
+
+ self subclassResponsibility.
+
+ "Created: / 15-09-2014 / 18:48:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addComponent:aView labeled:labelString
+ "Add a label and some component side-by-side. Returns the component"
+
+ self subclassResponsibility
+
+ "Created: / 15-09-2014 / 15:43:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addInputFieldOn: aValueModel labeled: aString validatedBy: aBlock
+ | field |
+
+ field := EditField new.
+ field immediateAccept: true.
+ field model: aValueModel.
+
+ ^ self addComponent: field labeled: aString
+
+ "Created: / 15-09-2014 / 15:52:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addSeparator
+ "Add horizontal separator (line)"
+ ^ self addComponent: Separator new
+
+ "Created: / 15-09-2014 / 18:52:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomDialog methodsFor:'construction-utilities'!
+
+addClassCategoryEntryOn: aValueModel labeled: aString validateBy: aBlock
+
+ ^ (self addInputFieldOn: aValueModel labeled: aString validatedBy: aBlock)
+ entryCompletionBlock: [:text | DoWhatIMeanSupport classCategoryCompletion: text inEnvironment: Smalltalk ];
+ yourself
+
+ "Created: / 16-09-2014 / 10:13:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addClassNameEntryOn: aValueModel labeled: aString validateBy: aBlock
+
+ ^ (self addInputFieldOn: aValueModel labeled: aString validatedBy: aBlock)
+ entryCompletionBlock: (DoWhatIMeanSupport classNameEntryCompletionBlock);
+ yourself
+
+ "Created: / 15-09-2014 / 15:43:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addSelectorNameEntryOn: aValueModel labeled: aString validateBy: aBlock
+
+ ^ (self addInputFieldOn: aValueModel labeled: aString validatedBy: aBlock)
+ entryCompletionBlock: [:text | DoWhatIMeanSupport selectorCompletion:text inEnvironment:Smalltalk];
+ yourself
+
+ "Created: / 15-10-2014 / 08:44:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDialog methodsFor:'opening'!
+
+open
+ self subclassResponsibility
+
+ "Created: / 15-09-2014 / 16:23:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomDialog methodsFor:'user interaction & notifications'!
+
+information: aString
+
+ self subclassResponsibility
+
+ "Created: / 02-06-2014 / 22:01:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomInspectorTabCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,168 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomInspectorTabCodeGenerator
+ instanceVariableNames:'tabLabel tabPriority'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomInspectorTabCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomInspectorTabCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ ^ 'Generates a new method defining an inspector tab for Inspector2'
+
+ "Modified: / 25-11-2014 / 00:02:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ ^ 'Inspector tab definition'
+
+ "Modified: / 25-11-2014 / 00:02:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomInspectorTabCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ ^ true
+
+ "Modified: / 24-11-2014 / 23:50:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ ^ aCustomPerspective isClassPerspective
+
+ "Modified: / 25-11-2014 / 00:01:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomInspectorTabCodeGenerator methodsFor:'accessing'!
+
+tabLabel
+ ^ tabLabel
+!
+
+tabLabel:aString
+ tabLabel := aString.
+!
+
+tabPriority
+ ^ tabPriority
+!
+
+tabPriority:anInteger
+ tabPriority := anInteger.
+! !
+
+!CustomInspectorTabCodeGenerator methodsFor:'executing - private'!
+
+buildInContext:aCustomContext
+ aCustomContext selectedClasses do:[:cls |
+ self buildInContext: aCustomContext forClass: cls
+ ]
+
+ "Modified: / 25-11-2014 / 00:42:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+buildInContext: aCustomContext forClass: anRBClass
+ | selector |
+
+ selector := String streamContents: [:s | tabLabel asCollectionOfWordsDo:[:w | s nextPutAll: (w select:[:c | c isAlphaNumeric ]) asUppercaseFirst ] ].
+
+ model
+ compile: 'inspector2Tab',selector,'
+ <inspector2Tab>
+
+ ^ (self newInspector2Tab)
+ label:',tabLabel storeString,';
+ priority:',tabPriority storeString,';
+ "/ view: [ ... ];
+ "/ application: [ ... ];
+ "/ text: [ ... ];
+ yourself
+ '
+ in: anRBClass
+ classified: 'inspecting'.
+
+ "Created: / 25-11-2014 / 00:42:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+configureInContext:aCustomContext
+ "Perform neccessary configuration for given context, such as
+ computing default values for parameters. This may interact with
+ user by means of opening a dialog.
+
+ This method is called only for interactive contexts. When using
+ non interactively, a caller must do the configuration itself by means
+ of accessors."
+
+ "/ To be overridden by subclasses
+
+ | labelHolder priorityHolder |
+
+ tabLabel := 'New Tab Label'.
+ tabPriority := 50.
+
+ labelHolder := (AspectAdaptor forAspect:#tabLabel) subject:self.
+ priorityHolder := (AspectAdaptor forAspect:#tabPriority) subject:self.
+
+ dialog
+ addInputFieldOn: labelHolder
+ labeled: 'Tab label:'
+ validatedBy: nil.
+
+ dialog
+ addInputFieldOn: (TypeConverter onNumberValue: priorityHolder minValue: 1 maxValue: 100)
+ labeled: 'Tab priority:'
+ validatedBy: nil.
+
+ dialog addButtons.
+ dialog open.
+
+ "Created: / 25-11-2014 / 00:51:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomIsAbstractCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,121 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomIsAbstractCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomIsAbstractCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomIsAbstractCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Mark class as abstract (by implementing class method #isAbstract)'
+
+ "Created: / 20-03-2014 / 01:31:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Mark class as abstract'
+
+ "Created: / 20-03-2014 / 01:32:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomIsAbstractCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ aCustomContext selectedClasses notEmptyOrNil
+
+ "Created: / 20-03-2014 / 01:34:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ ^ aCustomPerspective isClassPerspective
+
+ "Created: / 20-03-2014 / 01:33:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomIsAbstractCodeGenerator methodsFor:'executing'!
+
+buildInContext:aCustomContext
+ | classes |
+
+ classes := aCustomContext selectedClasses.
+ classes do:[:class |
+ | metaclass className |
+
+ metaclass := class theMetaclass.
+ className := class theNonMetaclass name.
+
+ (metaclass includesSelector: #isAbstract) ifFalse:[
+ self compile: ('isAbstract
+ ^ self == %1' bindWith: className) forClass: metaclass inCategory: 'testing'
+ ].
+ ]
+
+ "Created: / 16-09-2014 / 07:20:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 17:23:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomIsAbstractCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,135 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomIsAbstractCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomIsAbstractCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomIsAbstractCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomIsAbstractCodeGenerator new
+! !
+
+!CustomIsAbstractCodeGeneratorTests methodsFor:'tests'!
+
+test_available_in_context
+
+ self deny: (generatorOrRefactoring class availableInContext:context).
+
+ context selectedClasses: (Array with: self class).
+
+ self assert: (generatorOrRefactoring class availableInContext:context).
+
+ "Modified (format): / 15-11-2014 / 15:51:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_class
+
+ self assert: (generatorOrRefactoring class availableInPerspective: CustomPerspective classPerspective)
+
+ "Modified: / 15-11-2014 / 15:52:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_method_exists
+ | expectedSource metaclass class |
+
+ metaclass := model createClass
+ name: #DummyClass01;
+ compile;
+ theMetaclass.
+
+ metaclass compile: 'isAbstract ^ false'.
+
+ expectedSource := 'isAbstract ^ false'.
+
+ context selectedClasses: (Array with: metaclass).
+ generatorOrRefactoring executeInContext: context.
+
+ class := Smalltalk at: #DummyClass01.
+ self assertClassMethodSource:expectedSource atSelector:#isAbstract forClass:class
+
+ "Created: / 16-11-2014 / 17:25:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_method_generated
+ |expectedSource|
+
+ expectedSource := 'isAbstract
+ ^ self == DummyClassForGeneratorTestCase'.
+
+ self executeGeneratorInContext:#classWithInstanceVariable.
+
+ self assertClassMethodSource:expectedSource atSelector:#isAbstract
+
+ "Created: / 15-11-2014 / 15:53:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 15-11-2014 / 19:32:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_method_generated_for_metaclass
+ | expectedSource metaclass class |
+
+ metaclass := model createClass
+ name: #DummyClass01;
+ compile;
+ theMetaclass.
+
+ expectedSource := 'isAbstract
+ ^ self == DummyClass01'.
+
+ context selectedClasses: (Array with: metaclass).
+ generatorOrRefactoring executeInContext: context.
+
+ class := Smalltalk at: #DummyClass01.
+ self assertClassMethodSource:expectedSource atSelector:#isAbstract forClass:class
+
+ "Created: / 16-11-2014 / 17:17:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,99 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomSimpleSetterMethodsCodeGenerator subclass:#CustomJavaScriptSimpleSetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomJavaScriptSimpleSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Same purpose like superclass, but for STX JavaScript language.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGenerator class methodsFor:'queries'!
+
+availableForProgrammingLanguages
+
+ ^ {STXJavaScriptLanguage instance}
+
+ "Created: / 31-01-2015 / 18:16:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns simple setter for given STX JavaScript class and variable name."
+
+ | methodName comment argName |
+
+ methodName := aName.
+ argName := self argNameForMethodName: methodName.
+ comment := ''.
+
+ userPreferences generateCommentsForSetters ifTrue:[
+ | varType |
+
+ varType := self varTypeOf: aName class: aClass.
+ comment := '
+ // set the value of the %1 variable ''%2'' (automatically generated)'.
+ comment := comment bindWith: varType with: aName.
+ ].
+
+ ^ methodName, '(', argName, ') {', comment, '
+ ', aName, ' = ', argName, ';
+}'.
+
+ "Created: / 31-01-2015 / 18:15:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,133 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests
+ instanceVariableNames:'javaScriptClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomJavaScriptSimpleSetterMethodsCodeGenerator new
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests methodsFor:'initialization & release'!
+
+setUp
+ | classDefinition |
+
+ super setUp.
+
+ classDefinition := 'public class DummyJavaStriptClass01 extends Object {
+ var instVar01;
+}'.
+
+ Class withoutUpdatingChangesDo: [
+ JavaScriptCompiler evaluate: classDefinition notifying: nil compile: nil
+ ].
+
+ javaScriptClass := Smalltalk at: #DummyJavaStriptClass01.
+
+ "Modified: / 01-02-2015 / 16:22:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ Class withoutUpdatingChangesDo: [
+ javaScriptClass removeFromSystem
+ ].
+ "super tearDown."
+ "Call of undoing changes produces error relevant
+ to parsing JavaScript source code as Smalltalk code."
+ "changeManager undoChanges."
+ mock unmockAll
+
+ "Modified: / 01-02-2015 / 16:21:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_simple_setter_generated_with_comment
+ | expectedSource |
+
+ userPreferences generateComments: true.
+
+ context selectedClasses: {javaScriptClass}.
+
+ expectedSource := 'instVar01(something) {
+ // set the value of the instance variable ''instVar01'' (automatically generated)
+ instVar01 = something;
+}'.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertMethodSource: expectedSource atSelector: #'instVar01:' forClass: javaScriptClass
+
+ "Created: / 01-02-2015 / 16:24:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_simple_setter_generated_without_comment
+ | expectedSource |
+
+ userPreferences generateComments: false.
+
+ context selectedClasses: {javaScriptClass}.
+
+ expectedSource := 'instVar01(something) {
+ instVar01 = something;
+}'.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertMethodSource: expectedSource atSelector: #'instVar01:' forClass: javaScriptClass
+
+ "Created: / 01-02-2015 / 16:26:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,138 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomJavaSimpleSetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomJavaSimpleSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomJavaSimpleSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Generates setter methods for instance variables of Java Class'
+
+ "Created: / 01-02-2015 / 20:42:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Setter Method(s)'
+
+ "Created: / 01-02-2015 / 20:43:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomJavaSimpleSetterMethodsCodeGenerator class methodsFor:'queries'!
+
+availableForProgrammingLanguages
+ "Returns list of programming language instances for which this generator / refactoring works.
+ (SmalltalkLanguage instance, JavaLanguage instance, GroovyLanguage instance, etc.)
+
+ See also availableForProgrammingLanguagesInContext:withPerspective:"
+
+ ^ {JavaLanguage instance}
+
+ "Created: / 01-02-2015 / 20:44:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInContext: aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ aCustomContext selectedClasses notEmptyOrNil
+
+ "Created: / 01-02-2015 / 20:40:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective: aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ ^ aCustomPerspective isClassPerspective
+
+ "Created: / 01-02-2015 / 20:41:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomJavaSimpleSetterMethodsCodeGenerator methodsFor:'executing - private'!
+
+buildInContext: aCustomContext
+ "Prototype generator for Java language - proper way should be usage of some Java parser"
+
+ self warn: 'Experimenatal generator, may not work as expected.'.
+
+ aCustomContext selectedClasses do: [ :class |
+ class instanceVariableNames do: [ :varName |
+ | setter type newDefinition endOfClass |
+
+ type := (class realClass typeOfField: varName) asString.
+ setter := '
+ public ', type, ' ', varName, '(', type, ' ', varName, ') {
+ this.', varName, ' = ', varName, ';
+ }
+'.
+ newDefinition := class realClass definition.
+ endOfClass := newDefinition lastIndexOf: $}.
+ newDefinition := (newDefinition copyTo: endOfClass - 1), setter, (newDefinition copyFrom: endOfClass).
+ JavaCompiler compile: newDefinition
+ ]
+ ]
+
+ "Created: / 01-02-2015 / 17:58:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 02-02-2015 / 22:20:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomLazyInitializationAccessMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomLazyInitializationAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomLazyInitializationAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Access Method(s) with Lazy Initialization in Getter for selected instance variables'
+
+ "Modified: / 08-07-2014 / 18:10:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Access Method(s) with Lazy Initialization in Getter'
+
+ "Modified: / 08-07-2014 / 18:10:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLazyInitializationAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ "Creates access methods with lazy initialization in getter for given context"
+
+ self executeSubGeneratorOrRefactoringClasses:(Array
+ with:CustomLazyInitializationGetterMethodsCodeGenerator
+ with:CustomChangeNotificationSetterMethodsCodeGenerator)
+ inContext:aCustomContext
+
+ "Modified: / 08-07-2014 / 18:37:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLazyInitializationAccessMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,134 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomLazyInitializationAccessMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomLazyInitializationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomLazyInitializationAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomLazyInitializationAccessMethodsCodeGenerator new
+! !
+
+!CustomLazyInitializationAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_lazy_initialization_access_methods_generated_with_comments
+ | expectedGetterSource expectedSetterSource expectedDefaultSource |
+
+ userPreferences
+ generateCommentsForGetters: true;
+ generateCommentsForSetters: true.
+
+ expectedGetterSource := 'instanceVariable
+ "return the instance instance variable ''instanceVariable'' with lazy instance creation (automatically generated)"
+
+ instanceVariable isNil ifTrue:[
+ instanceVariable := self class defaultInstanceVariable.
+ ].
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ "set the value of the instance variable ''instanceVariable'' and send a change notification (automatically generated)"
+
+ (instanceVariable ~~ something) ifTrue:[
+ instanceVariable := something.
+ self changed:#instanceVariable.
+ ].'.
+
+ expectedDefaultSource := 'defaultInstanceVariable
+ "default value for the ''instanceVariable'' instance variable (automatically generated)"
+
+ self shouldImplement.
+ ^ nil'.
+
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:.
+ self assertClassMethodSource: expectedDefaultSource atSelector: #defaultInstanceVariable
+
+ "Created: / 08-07-2014 / 18:43:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-07-2014 / 20:11:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_lazy_initialization_access_methods_generated_without_comments
+ | expectedGetterSource expectedSetterSource expectedDefaultSource |
+
+ userPreferences
+ generateCommentsForGetters: false;
+ generateCommentsForSetters: false.
+
+ expectedGetterSource := 'instanceVariable
+ instanceVariable isNil ifTrue:[
+ instanceVariable := self class defaultInstanceVariable.
+ ].
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ (instanceVariable ~~ something) ifTrue:[
+ instanceVariable := something.
+ self changed:#instanceVariable.
+ ].'.
+
+ expectedDefaultSource := 'defaultInstanceVariable
+ self shouldImplement.
+ ^ nil'.
+
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:.
+ self assertClassMethodSource: expectedDefaultSource atSelector: #defaultInstanceVariable
+
+ "Created: / 08-07-2014 / 19:37:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-07-2014 / 20:11:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,136 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomLazyInitializationGetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomLazyInitializationGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Getter methods with Lazy Initialization in Getter for selected instance variables'
+
+ "Created: / 29-06-2014 / 19:12:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Getters')
+
+ "Created: / 22-08-2014 / 18:56:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Getter Method(s) with Lazy Initialization'
+
+ "Created: / 29-06-2014 / 19:16:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 06-07-2014 / 23:14:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns getter with lazy initialization method source code for given class and variable name"
+
+ | methodName comment |
+
+ methodName := self methodNameFor: aName.
+ comment := ''.
+
+ userPreferences generateCommentsForGetters ifTrue:[
+ | varType |
+
+ varType := self varTypeOf: aName class: aClass.
+ comment := '"return the %1 instance variable ''%2'' with lazy instance creation (automatically generated)"'.
+ comment := comment bindWith: varType with: aName.
+ ].
+
+ ^ self sourceCodeGenerator
+ source: '`@methodName
+ `"comment
+
+ `variableName isNil ifTrue:[
+ `variableName := self class `@defaultMethodName.
+ ].
+ ^ `variableName';
+ replace: '`@methodName' with: methodName asSymbol;
+ replace: '`@defaultMethodName' with: (self defaultMethodNameFor: aName) asSymbol;
+ replace: '`variableName' with: aName asString;
+ replace: '`"comment' with: comment;
+ newSource.
+
+ "Created: / 24-06-2014 / 23:24:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-09-2014 / 22:35:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ | generator |
+
+ generator := CustomDefaultGetterMethodsCodeGenerator subGeneratorOrRefactoringOf:self.
+ generator executeInContext: aCustomContext.
+
+ super buildInContext: aCustomContext
+
+ "Created: / 30-06-2014 / 18:00:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLazyInitializationGetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,121 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomLazyInitializationGetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomLazyInitializationGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomLazyInitializationGetterMethodsCodeGenerator new
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_lazy_initialization_getter_method_generated_with_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: true.
+
+ expectedSource := 'instanceVariable
+ "return the instance instance variable ''instanceVariable'' with lazy instance creation (automatically generated)"
+
+ instanceVariable isNil ifTrue:[
+ instanceVariable := self class defaultInstanceVariable.
+ ].
+ ^ instanceVariable'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+ "Created: / 30-06-2014 / 18:03:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_lazy_initialization_getter_method_generated_with_default_method
+ | expectedGetterSource expectedDefaultSource |
+
+ userPreferences generateCommentsForGetters: false.
+
+ expectedGetterSource := 'instanceVariable
+ instanceVariable isNil ifTrue:[
+ instanceVariable := self class defaultInstanceVariable.
+ ].
+ ^ instanceVariable'.
+
+ expectedDefaultSource := 'defaultInstanceVariable
+ self shouldImplement.
+ ^ nil'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertClassMethodSource: expectedDefaultSource atSelector: #defaultInstanceVariable
+
+ "Created: / 30-06-2014 / 18:06:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-07-2014 / 20:11:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_lazy_initialization_getter_method_generated_without_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: false.
+
+ expectedSource := 'instanceVariable
+ instanceVariable isNil ifTrue:[
+ instanceVariable := self class defaultInstanceVariable.
+ ].
+ ^ instanceVariable'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+ "Created: / 30-06-2014 / 10:37:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLocalChangeManager.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,117 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomChangeManager subclass:#CustomLocalChangeManager
+ instanceVariableNames:'executedChanges'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomLocalChangeManager class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Unlike CustomBrowserChangeManager this implementation should not affect
+ global Browser changes collector, Browser menus and the change file (st.chg).
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomLocalChangeManager class methodsFor:'instance creation'!
+
+new
+
+ ^ self basicNew initialize
+
+ "Created: / 31-05-2014 / 19:34:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManager methodsFor:'initialization'!
+
+initialize
+
+ executedChanges := OrderedCollection new.
+
+ "Created: / 31-05-2014 / 19:31:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManager methodsFor:'performing-changes'!
+
+performChange: aRefactoringChange
+ "Applies code change (add/change/remove class/method ...) to the system"
+
+ Class withoutUpdatingChangesDo:[
+ executedChanges add: aRefactoringChange execute
+ ]
+
+ "Modified: / 30-11-2014 / 18:21:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+undoChanges
+ "undo all changes made by performChange: method"
+
+ Class withoutUpdatingChangesDo:[
+ executedChanges reversed do: [ :change |
+ change execute
+ ]
+ ].
+
+ executedChanges removeAll
+
+ "Created: / 19-10-2014 / 14:59:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-11-2014 / 15:40:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManager class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLocalChangeManagerTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,124 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomLocalChangeManagerTests
+ instanceVariableNames:'changeManager'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomLocalChangeManagerTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomLocalChangeManagerTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ changeManager := CustomLocalChangeManager new.
+
+ "Modified: / 30-11-2014 / 17:32:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+ super tearDown.
+
+ (Smalltalk at: #DummyClass01) notNil ifTrue: [
+ Class withoutUpdatingChangesDo: [
+ (Smalltalk at: #DummyClass01) removeFromSystem
+ ]
+ ]
+
+ "Created: / 30-11-2014 / 17:40:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManagerTests methodsFor:'private'!
+
+lastChangeInRefactoryChangeManagerAt: aSelector
+
+ ^ [
+ RefactoryChangeManager instance perform: aSelector
+ ] on: Collection emptyCollectionSignal do: [
+ nil
+ ]
+
+ "Created: / 30-11-2014 / 18:09:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManagerTests methodsFor:'tests'!
+
+test_perform_change_with_nothing_external_modified
+ | expectedUndo expectedRedo actualUndo actualRedo expectedChangeContents actualChangeContents |
+
+ expectedUndo := self lastChangeInRefactoryChangeManagerAt: #undoChange.
+ expectedRedo := self lastChangeInRefactoryChangeManagerAt: #redoChange.
+ expectedChangeContents := ObjectMemory nameForChanges asFilename contents.
+
+ self assert: (Smalltalk at: #DummyClass01) isNil.
+
+ changeManager performChange: (AddClassChange definition: 'Object subclass:#DummyClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:''''
+ ').
+
+ self assert: (Smalltalk at: #DummyClass01) notNil.
+
+ changeManager undoChanges.
+
+ self assert: (Smalltalk at: #DummyClass01) isNil.
+
+ actualUndo := self lastChangeInRefactoryChangeManagerAt: #undoChange.
+ actualRedo := self lastChangeInRefactoryChangeManagerAt: #redoChange.
+ actualChangeContents := ObjectMemory nameForChanges asFilename contents.
+
+ self assert: expectedRedo == actualRedo.
+ self assert: expectedUndo == actualUndo.
+ self assert: expectedChangeContents = actualChangeContents.
+
+ "Modified: / 30-11-2014 / 18:20:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomManager.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,229 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomManager
+ instanceVariableNames:'generatorsOrRefactoringsProvider'
+ classVariableNames:'Current'
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomManager class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Starting point for accessing generators and refactoring classes.
+ Class method 'current' provides current system setup.
+ Instance methods basically returns or iterates some subset of generators or refactoring classes.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomManager class methodsFor:'initialization'!
+
+initialize
+ "Invoked at system start or when the class is dynamically loaded."
+
+ Current := self new
+
+ "Modified: / 25-01-2014 / 14:54:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 28-12-2014 / 12:12:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+! !
+
+!CustomManager class methodsFor:'accessing'!
+
+current
+ "Returns my global instance within system"
+
+ ^ Current
+
+ "Created: / 25-01-2014 / 14:55:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 28-12-2014 / 12:12:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager methodsFor:'accessing'!
+
+generatorsAndRefactorings
+ "Returns all generators and refactorings from generatorsOrRefactoringsProvider"
+
+ ^ OrderedCollection streamContents:[ :s |
+ self generatorsAndRefactoringsDo: [ :each |
+ s nextPut: each .
+ ]
+ ]
+
+ "Created: / 25-01-2014 / 15:02:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 28-12-2014 / 11:55:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsForContext: aCustomContext
+ "Returns generators and refactorings available for given context"
+
+ ^ OrderedCollection streamContents:[ :s |
+ self generatorsAndRefactoringsForContext: aCustomContext do: [ :each |
+ s nextPut: each .
+ ]
+ ]
+
+ "Created: / 25-01-2014 / 15:06:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 28-12-2014 / 11:57:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsForPerspective: aCustomPerspective
+ "Returns generators and refactorings available for given perspective"
+
+ ^ OrderedCollection streamContents:[ :s |
+ self generatorsAndRefactoringsForPerspective: aCustomPerspective do: [ :each |
+ s nextPut: each .
+ ]
+ ]
+
+ "Created: / 26-01-2014 / 13:18:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 26-01-2014 / 23:35:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 28-12-2014 / 11:57:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsSelect: aBlock
+ "Returns generators and refactorings classes for which the block returns true"
+
+ ^ OrderedCollection streamContents:[ :stream |
+ self generatorsAndRefactoringsDo: [ :each |
+ (aBlock value: each) ifTrue: [
+ stream nextPut: each
+ ]
+ ]
+ ]
+
+ "Created: / 28-12-2014 / 13:03:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsOrRefactoringsProvider
+ "Returns an iterator (implements generatorsAndRefactoringsDo:) from where generators or refactorings will be taken."
+
+ ^ generatorsOrRefactoringsProvider
+
+ "Modified (comment): / 28-12-2014 / 12:05:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsOrRefactoringsProvider: aProvider
+ "see generatorsOrRefactoringsProvider"
+
+ generatorsOrRefactoringsProvider := aProvider
+
+ "Modified (comment): / 28-12-2014 / 12:06:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager methodsFor:'enumerating'!
+
+generatorsAndRefactoringsDo: aBlock
+ "Evaluates a block on all installed generator and refactoring classes.
+ NOTE: the block gets the generator/refactoring class. not an instance."
+
+ generatorsOrRefactoringsProvider generatorsAndRefactoringsDo: [ :each |
+ each isAbstract ifFalse:[
+ aBlock value: each
+ ].
+ ]
+
+ "Created: / 25-01-2014 / 15:01:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 26-01-2014 / 13:17:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 28-12-2014 / 11:52:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsForContext: aCustomContext do: aBlock
+ "Evaluates a block on generator and refactoring classes available for given context"
+
+ self generatorsAndRefactoringsDo: [ :each |
+ (each availableInContext: aCustomContext) ifTrue:[
+ aBlock value: each
+ ].
+ ]
+
+ "Created: / 25-01-2014 / 15:03:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 28-12-2014 / 12:08:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsForPerspective: aCustomPerspective do: aBlock
+ "Evaluates a block on generator and refactoring classes available for given perspective"
+
+ self generatorsAndRefactoringsDo: [ :each |
+ (each availableInPerspective: aCustomPerspective) ifTrue:[
+ aBlock value: each
+ ].
+ ]
+
+ "Created: / 26-01-2014 / 13:18:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 28-12-2014 / 12:08:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager methodsFor:'initialization'!
+
+initialize
+ "Invoked when a new instance is created."
+
+ generatorsOrRefactoringsProvider := CustomCodeGeneratorOrRefactoring
+
+ "Modified: / 28-12-2014 / 11:53:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
+
+CustomManager initialize!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomManagerTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,303 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomManagerTests
+ instanceVariableNames:'mock provider manager generatorClassMock'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomManagerTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomManagerTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ mock := CustomMock new.
+ provider := mock mockOf: OrderedCollection.
+ provider compileMockMethod: 'generatorsAndRefactoringsDo: aBlock
+ self do: aBlock'.
+
+ manager := CustomManager new.
+ manager generatorsOrRefactoringsProvider: provider.
+
+ generatorClassMock := mock mockClassOf: Object.
+ mock createMockGetters: generatorClassMock forSelectors:
+ {'label'. 'isAbstract'. 'availableInContext:'. 'availableInPerspective:'}.
+
+ "Modified: / 28-12-2014 / 15:34:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ mock unmockAll.
+
+ super tearDown.
+
+ "Modified: / 28-12-2014 / 13:15:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManagerTests methodsFor:'private'!
+
+addGenerator: aLabel
+ "Creates initialized code generator mock and adds it to managers generators"
+ | generator |
+
+ generator := generatorClassMock new
+ objectAttributeAt: #isAbstract put: false;
+ objectAttributeAt: #label put: aLabel;
+ objectAttributeAt: #availableInContext: put: true;
+ objectAttributeAt: #availableInPerspective: put: true;
+ yourself.
+
+ manager generatorsOrRefactoringsProvider add: generator.
+
+ ^ generator
+
+ "Created: / 28-12-2014 / 14:12:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 28-12-2014 / 15:36:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+collectionOfLabels: aCollection
+ "Returns collection of labels from given collection"
+
+ ^ OrderedCollection streamContents: [ :stream |
+ aCollection do: [ :each |
+ stream nextPut: each label
+ ]
+ ]
+
+ "Created: / 28-12-2014 / 14:23:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManagerTests methodsFor:'tests'!
+
+test_current
+
+ self assert: manager class current notNil
+
+ "Modified: / 28-12-2014 / 13:17:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings
+ | expectedGenerators actualGenerators |
+
+ expectedGenerators := OrderedCollection with: 'Generator_01' with: 'Generator_02'.
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ actualGenerators := self collectionOfLabels: manager generatorsAndRefactorings.
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Modified: / 28-12-2014 / 14:23:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_do
+ | expectedGenerators actualGenerators |
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ expectedGenerators := OrderedCollection with: provider first
+ with: provider last.
+
+ actualGenerators := OrderedCollection streamContents: [ :stream |
+ manager generatorsAndRefactoringsDo: [ :generator |
+ stream nextPut: generator
+ ].
+ ].
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Modified: / 28-12-2014 / 18:04:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_for_context
+ | expectedGenerators actualGenerators |
+
+ expectedGenerators := OrderedCollection with: 'Generator_02'.
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ provider first objectAttributeAt: #availableInContext: put: false.
+
+ actualGenerators := self collectionOfLabels: (manager
+ generatorsAndRefactoringsForContext: nil).
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Modified: / 28-12-2014 / 15:38:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_for_context_do
+ | expectedGenerators actualGenerators |
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ expectedGenerators := OrderedCollection with: provider first.
+ provider last objectAttributeAt: #availableInContext: put: false.
+
+ actualGenerators := OrderedCollection streamContents: [ :stream |
+ manager generatorsAndRefactoringsForContext: nil do: [ :generator |
+ stream nextPut: generator
+ ].
+ ].
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Modified: / 28-12-2014 / 18:08:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_for_perspective
+ | expectedGenerators actualGenerators |
+
+ expectedGenerators := OrderedCollection with: 'Generator_01'.
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ provider second objectAttributeAt: #availableInPerspective: put: false.
+
+ actualGenerators := self collectionOfLabels: (manager
+ generatorsAndRefactoringsForPerspective: nil).
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Modified: / 28-12-2014 / 17:07:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_for_perspective_do
+ | expectedGenerators actualGenerators |
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ expectedGenerators := OrderedCollection with: provider first.
+ provider last objectAttributeAt: #availableInPerspective: put: false.
+
+ actualGenerators := OrderedCollection streamContents: [ :stream |
+ manager generatorsAndRefactoringsForPerspective: nil do: [ :generator |
+ stream nextPut: generator
+ ].
+ ].
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Modified: / 28-12-2014 / 18:08:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_select_01
+ | expectedGenerators actualGenerators |
+
+ expectedGenerators := OrderedCollection with: 'Generator_01'.
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ provider second objectAttributeAt: #availableInPerspective: put: false.
+
+ actualGenerators := self collectionOfLabels: (manager
+ generatorsAndRefactoringsSelect: [ :generator |
+ generator availableInPerspective: nil
+ ]).
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Modified (comment): / 28-12-2014 / 17:54:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_select_02
+ | expectedGenerators actualGenerators |
+
+ expectedGenerators := OrderedCollection new.
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ provider second objectAttributeAt: #availableInPerspective: put: false.
+
+ actualGenerators := self collectionOfLabels: (manager
+ generatorsAndRefactoringsSelect: [ :generator |
+ false
+ ]).
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Created: / 28-12-2014 / 17:55:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_select_03
+ | expectedGenerators actualGenerators |
+
+ expectedGenerators := OrderedCollection with: 'Generator_01' with: 'Generator_02'.
+
+ self addGenerator: 'Generator_01';
+ addGenerator: 'Generator_02'.
+
+ provider second objectAttributeAt: #availableInPerspective: put: false.
+
+ actualGenerators := self collectionOfLabels: (manager
+ generatorsAndRefactoringsSelect: [ :generator |
+ true
+ ]).
+
+ self assert: expectedGenerators = actualGenerators
+
+ "Created: / 28-12-2014 / 17:55:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManagerTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMenuBuilder.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,380 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomMenuBuilder
+ instanceVariableNames:'perspective menu submenuLabel afterMenuItemLabelled
+ generatorOrRefactoringFilter resources navigationState manager
+ errorPrinter'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-UI'
+!
+
+!CustomMenuBuilder class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Injects menu item with submenu filled with generators or refactorings to the given menu.
+ Basically helps to extend system browser (NewSystemBrowser) context menu (for example
+ the menu which pop-ups after right-click on the class list).
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomMenuBuilder class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+! !
+
+!CustomMenuBuilder class methodsFor:'building'!
+
+buildMenuForContext:context filter: filter
+ ^ self new buildMenuForContext:context filter: filter
+
+ "Created: / 26-08-2014 / 10:12:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilder methodsFor:'accessing'!
+
+afterMenuItemLabelled
+ "Returns menu item label after which will be placed
+ new menu item with generators or refactorings"
+
+ ^ afterMenuItemLabelled
+
+ "Modified (comment): / 28-12-2014 / 23:22:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+afterMenuItemLabelled:aLabel
+ "see afterMenuItemLabeled"
+
+ afterMenuItemLabelled := aLabel
+
+ "Modified (comment): / 28-12-2014 / 23:20:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+errorPrinter
+ "Returns printer (like Transcript) which should print/show errors while menu building.
+ Better to print errors silently than destroy IDE functionality with recurring errors."
+
+ ^ errorPrinter
+
+ "Modified (comment): / 01-02-2015 / 19:38:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+errorPrinter: aPrinter
+ "see errorPrinter"
+
+ errorPrinter := aPrinter.
+
+ "Modified (comment): / 01-02-2015 / 19:38:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorOrRefactoringFilter
+ "Returns one argument block which is used to filter generators or refactorings"
+
+ ^ generatorOrRefactoringFilter
+
+ "Modified (comment): / 28-12-2014 / 23:23:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorOrRefactoringFilter: aOneArgBlock
+ "see generatorOrRefactoringFilter"
+
+ generatorOrRefactoringFilter := aOneArgBlock
+
+ "Modified (comment): / 28-12-2014 / 23:25:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+groupsSortBlock
+ "Returns a block used to sort generator or refactoring groups"
+
+ ^ [ :a :b |
+ a size = b size ifTrue: [
+ | i |
+
+ i := 1.
+
+ [ i < a size and: [ (a at:i) = (b at:i) ] ] whileTrue: [
+ i := i + 1
+ ].
+
+ (a at:i) < (b at:i)
+ ] ifFalse: [
+ a size < b size
+ ]
+ ]
+
+ "Created: / 28-12-2014 / 20:56:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+manager
+ "Returns generator or refactoring manager which is used to access them.
+ See CustomManager for more details."
+
+ ^ manager
+
+ "Modified (comment): / 28-12-2014 / 23:26:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+manager: aManager
+ "see manager"
+
+ manager := aManager
+
+ "Modified (comment): / 28-12-2014 / 23:27:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+menu
+ "Returns menu (instance of class Menu) in which is created new
+ menu item with submenu filled with generators or refactorings"
+
+ ^ menu
+
+ "Modified (comment): / 28-12-2014 / 23:28:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+menu: aMenu
+ "see menu"
+
+ menu := aMenu
+
+ "Modified (comment): / 28-12-2014 / 23:28:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+navigationState
+ "see Tools::NavigationState"
+
+ ^ navigationState
+
+ "Modified (comment): / 28-12-2014 / 23:29:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+navigationState: aNavigationState
+ "see Tools::NavigationState"
+
+ navigationState := aNavigationState
+
+ "Created: / 28-12-2014 / 10:09:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 28-12-2014 / 23:29:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+perspective
+ "see CustomPerspective"
+
+ ^ perspective
+
+ "Modified (comment): / 28-12-2014 / 23:30:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+perspective: aCustomPerspective
+ "see CustomPerspective"
+
+ perspective := aCustomPerspective
+
+ "Modified (comment): / 28-12-2014 / 23:30:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+resources
+ "Used to translate menu labels (resources string:)"
+
+ ^ resources
+
+ "Modified (comment): / 28-12-2014 / 23:31:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+resources: someResources
+ "see resources"
+
+ resources := someResources
+
+ "Modified (comment): / 28-12-2014 / 23:32:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+submenuLabel
+ "Returns label of menu item which contains submenu with generators or refactorings"
+
+ ^ submenuLabel
+
+ "Modified (comment): / 28-12-2014 / 23:33:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+submenuLabel: aLabel
+ "see submenuLabel"
+
+ submenuLabel := aLabel
+
+ "Modified (comment): / 28-12-2014 / 23:33:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilder methodsFor:'building'!
+
+buildMenu
+ | item context submenuChannel |
+
+ (menu isNil or: [ perspective isNil ]) ifTrue: [
+ self error: 'Attributes named menu and perspective are required.'
+ ].
+
+ item := MenuItem label: (resources string: submenuLabel).
+ context := SmallSense::CustomBrowserContext
+ perspective: perspective
+ state: navigationState.
+
+ submenuChannel := [ self buildMenuForContext: context filter: generatorOrRefactoringFilter ].
+ "Do not show empty context menu"
+ submenuChannel value hasItems ifTrue: [
+ item submenuChannel: submenuChannel.
+ self
+ placeMenuItem: item
+ afterMenuItemLabeled: afterMenuItemLabelled
+ forMenu: menu
+ ]
+
+ "Created: / 27-12-2014 / 17:20:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:57:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:07:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+buildMenuForContext: context filter: filter
+ | submenu generatorsAndRefactorings groups groupsMap |
+
+ submenu := Menu new.
+ generatorsAndRefactorings := manager generatorsAndRefactoringsSelect: [ :generatorOrRefactoring |
+ [ (generatorOrRefactoring availableInPerspective: context perspective)
+ and: [ filter value: generatorOrRefactoring ]
+ and: [ generatorOrRefactoring availableForProgrammingLanguagesInContext: context ]
+ and: [ generatorOrRefactoring label notNil ]
+ ] on: Error do: [ :error |
+ errorPrinter showCR: 'An error occured when selecting code generators/refactorings.'.
+ errorPrinter showCR: 'Class: ', generatorOrRefactoring name, ' Error: ', error asString.
+ false
+ ].
+ ].
+
+ "/ Now, group them by group.
+ groupsMap := Dictionary new.
+ groups := OrderedCollection new.
+ generatorsAndRefactorings do:[:each |
+ | group |
+
+ group := each group.
+ (groupsMap includesKey: group) ifTrue:[
+ (groupsMap at: group) add: each.
+ ] ifFalse:[
+ groupsMap at: group put: (OrderedCollection with: each).
+ groups add: group.
+ ].
+ ].
+
+ groups sort: self groupsSortBlock.
+
+ groups do:[:name |
+ | items |
+
+ items := groupsMap at: name.
+ items sort:[ :a :b | a label < b label ].
+ items do:[:each |
+ | item |
+
+ item := MenuItem label: (resources string: each label)
+ itemValue:[ each executeInContextWithWaitCursor: context ].
+ item enabled:[ each availableInContext: context ].
+ submenu addItem:item.
+ ].
+ ] separatedBy:[
+ submenu addSeparator.
+ ].
+
+ ^ submenu
+
+ "Created: / 26-08-2014 / 10:13:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-02-2015 / 20:18:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+placeMenuItem: aMenuItem afterMenuItemLabeled: aLabel forMenu: aMenu
+ "Places a menu item after another menu item identified by label
+ within given menu."
+ | index |
+
+ index := aMenu indexOfMenuItemForWhich:[:each | each label = aLabel ].
+ index ~~ 0 ifTrue:[
+ "Labeled item found"
+ aMenu addItem: aMenuItem beforeIndex: index + 1.
+ ] ifFalse:[
+ aMenu addItem: aMenuItem.
+ ].
+
+ "Created: / 27-12-2014 / 18:45:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilder methodsFor:'initialization'!
+
+initialize
+ "Invoked when a new instance is created."
+
+ menu := Menu new.
+ submenuLabel := 'Unknown menu label'.
+ generatorOrRefactoringFilter := [ :generatorOrRefactoring | true ].
+ resources := self class classResources.
+ manager := SmallSense::CustomManager current.
+ errorPrinter := Transcript
+
+ "Modified: / 01-02-2015 / 19:31:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:07:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilder class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMenuBuilderTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,601 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomMenuBuilderTests
+ instanceVariableNames:'builder menu provider manager mock generatorClassMock resources'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-UI-Tests'
+!
+
+!CustomMenuBuilderTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomMenuBuilderTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ menu := Menu labels: 'Label_01
+Label_02
+Label_03' values: nil.
+
+ mock := CustomMock new.
+
+ provider := mock mockOf: OrderedCollection.
+ provider compileMockMethod: 'generatorsAndRefactoringsDo: aBlock
+ self do: aBlock'.
+
+ manager := CustomManager new.
+ manager generatorsOrRefactoringsProvider: provider.
+
+ builder := CustomMenuBuilder new.
+ builder manager: manager.
+
+ generatorClassMock := mock mockClassOf: Object.
+ mock createMockGetters: generatorClassMock forSelectors: {
+ 'label'. 'group'. 'name'. 'isAbstract'. 'availableInContext:'.
+ 'availableInPerspective:'. 'availableForProgrammingLanguagesInContext:'
+ }.
+
+ resources := mock mockOf: Object.
+ resources compileMockMethod: 'string:aString ^ ''Translated '', aString'.
+
+ "Modified: / 01-02-2015 / 20:00:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ mock unmockAll.
+
+ super tearDown.
+
+ "Modified: / 28-12-2014 / 22:02:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilderTests methodsFor:'private'!
+
+addGenerator: aLabel group: aGroup
+ "Creates initialized code generator mock and adds it to managers generators"
+ | generator |
+
+ generator := generatorClassMock new
+ objectAttributeAt: #isAbstract put: false;
+ objectAttributeAt: #label put: aLabel;
+ objectAttributeAt: #name put: 'Unknown class name';
+ objectAttributeAt: #group put: aGroup;
+ objectAttributeAt: #availableInContext: put: true;
+ objectAttributeAt: #availableInPerspective: put: true;
+ objectAttributeAt: #availableForProgrammingLanguagesInContext: put: true;
+ yourself.
+
+ manager generatorsOrRefactoringsProvider add: generator.
+
+ ^ generator
+
+ "Created: / 28-12-2014 / 22:10:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 01-02-2015 / 20:01:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+menuItemLabels
+ "Helper which returns labels from menu item as collection as string.
+ We are comparing labels, because menu items are not comparable -
+ MenuItem label: 'Label' not equals MenuItem label: 'Label'"
+
+ ^ (OrderedCollection streamContents: [ :stream |
+ menu itemsDo: [ :item |
+ stream nextPut: item label.
+ item submenuChannel notNil ifTrue: [
+ stream nextPut: (OrderedCollection streamContents: [ :innerStream |
+ item submenuChannel value itemsDo: [ :innerItem |
+ innerStream nextPut: innerItem label
+ ]
+ ]) asArray
+ ]
+ ]
+ ]) asArray
+
+ "Created: / 28-12-2014 / 10:41:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 28-12-2014 / 23:17:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilderTests methodsFor:'tests'!
+
+test_build_menu_empty
+ | expectedMenu actualMenu |
+
+ expectedMenu := {'Label_01'. 'Label_02'. 'Label_03'}.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'SomeLabel';
+ buildMenu.
+
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Modified: / 28-12-2014 / 22:41:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_for_context_filter
+ | expectedMenu actualMenu |
+
+ (self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #(Group_02);
+ addGenerator: 'Generator_03' group: #();
+ addGenerator: 'Generator_04' group: #(Group_01);
+ addGenerator: 'Generator_05' group: #(Group_01 Subgroup_01);
+ addGenerator: 'Generator_06' group: #(Group_01);
+ addGenerator: 'Generator_07' group: #(Group_01 Subgroup_01))
+ objectAttributeAt: #availableInContext: put: false. "To have at least one generator not avilable for context"
+
+ "Not present generators"
+ (self addGenerator: 'Generator_08' group: #())
+ objectAttributeAt: #availableForProgrammingLanguagesInContext: put: false.
+ (self addGenerator: 'Generator_09' group: #())
+ objectAttributeAt: #availableInPerspective: put: false.
+ self addGenerator: 'Generator_10' group: #().
+
+ menu := builder buildMenuForContext: CustomSubContext new filter: [ :generator |
+ generator label ~= 'Generator_10'
+ ].
+
+ expectedMenu := {
+ 'Generator_01'.
+ 'Generator_03'.
+ '-'.
+ 'Generator_04'.
+ 'Generator_06'.
+ '-'.
+ 'Generator_02'.
+ '-'.
+ 'Generator_05'.
+ 'Generator_07'.
+ }.
+
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Modified (comment): / 28-12-2014 / 22:35:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators
+ | expectedMenu actualMenu navigationState |
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Translated BunchOfGenerators'.
+ {'Translated Generator_01'. 'Translated Generator_03'}.
+ 'Label_03'.
+ }.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #();
+ addGenerator: 'Generator_03' group: #().
+
+ "Create some methods which actually uses context and perspective to be sure that they are correctly created"
+ provider last
+ compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
+ compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == CustomMenuBuilderTests name'.
+
+ navigationState := Tools::NavigationState new.
+ navigationState selectedClasses value: {CustomMenuBuilderTests}.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'BunchOfGenerators';
+ afterMenuItemLabelled: 'Label_02';
+ generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring label ~= 'Generator_02' ];
+ navigationState: navigationState;
+ resources: resources;
+ buildMenu.
+
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu.
+
+ (menu menuItemAt: 3) submenuChannel value itemsDo: [ :item |
+ self assert: item enabled value
+ ].
+
+ "Created: / 28-12-2014 / 22:48:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:08:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 21:09:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_empty_builder
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #();
+ addGenerator: 'Generator_03' group: #().
+
+ "Create some methods which actually uses context and perspective to be sure that they are correctly created"
+ provider last
+ compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
+ compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == #CustomMenuBuilderTests'.
+
+ self should: [
+ builder buildMenu
+ ] raise: Error suchThat: [ :error |
+ (error description) = 'Attributes named menu and perspective are required.'
+ ].
+
+ "Created: / 04-01-2015 / 15:31:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_empty_label
+ | expectedMenu actualMenu navigationState |
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Label_03'.
+ 'Unknown menu label'.
+ {'Generator_01'. 'Generator_02'. 'Generator_03'}
+ }.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #();
+ addGenerator: 'Generator_03' group: #().
+
+ "Create some methods which actually uses context and perspective to be sure that they are correctly created"
+ provider last
+ compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
+ compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == #CustomMenuBuilderTests'.
+
+ navigationState := Tools::NavigationState new.
+ navigationState selectedClasses value: {CustomMenuBuilderTests}.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ buildMenu.
+
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Created: / 04-01-2015 / 15:44:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_with_nil_label
+ | expectedMenu actualMenu printer expectedError actualError |
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #().
+
+ provider last objectAttributeAt: #label put: nil.
+
+ printer := mock mockOf: Object.
+ printer compileMockMethod: 'showCR: message
+ (self objectAttributeAt: #showCR:) add: message';
+ objectAttributeAt: #showCR: put: OrderedCollection new.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'BunchOfGenerators';
+ errorPrinter: printer;
+ buildMenu.
+
+ expectedError := OrderedCollection new.
+
+ actualError := printer objectAttributeAt: #showCR:.
+ self assert: expectedError = actualError.
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Label_03'.
+ 'BunchOfGenerators'.
+ {'Generator_01'}.
+ }.
+
+ actualMenu := self menuItemLabels.
+ self assert: expectedMenu = actualMenu.
+
+ "Created: / 01-02-2015 / 20:25:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_with_should_implement_error
+ | expectedMenu actualMenu printer expectedError actualError |
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #().
+
+ provider last compileMockMethod: 'availableInPerspective: perspective
+ self label = ''Generator_02'' ifTrue: [
+ self shouldImplement
+ ].
+ ^ true'.
+
+ printer := mock mockOf: Object.
+ printer compileMockMethod: 'showCR: message
+ (self objectAttributeAt: #showCR:) add: message';
+ objectAttributeAt: #showCR: put: OrderedCollection new.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'BunchOfGenerators';
+ errorPrinter: printer;
+ buildMenu.
+
+ expectedError := OrderedCollection
+ with: 'An error occured when selecting code generators/refactorings.'
+ with: 'Class: Unknown class name Error: functionality has to be implemented: a ', provider last className, '>>availableInPerspective:'.
+
+ actualError := printer objectAttributeAt: #showCR:.
+ self assert: expectedError = actualError.
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Label_03'.
+ 'BunchOfGenerators'.
+ {'Generator_01'}.
+ }.
+
+ actualMenu := self menuItemLabels.
+ self assert: expectedMenu = actualMenu.
+
+ "Created: / 01-02-2015 / 20:19:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_with_subclass_responsibility_error
+ | expectedMenu actualMenu printer expectedError actualError |
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #().
+
+ provider last compileMockMethod: 'availableInPerspective: perspective
+ self label = ''Generator_02'' ifTrue: [
+ self subclassResponsibility
+ ].
+ ^ true'.
+
+ printer := mock mockOf: Object.
+ printer compileMockMethod: 'showCR: message
+ (self objectAttributeAt: #showCR:) add: message';
+ objectAttributeAt: #showCR: put: OrderedCollection new.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'BunchOfGenerators';
+ errorPrinter: printer;
+ buildMenu.
+
+ expectedError := OrderedCollection
+ with: 'An error occured when selecting code generators/refactorings.'
+ with: 'Class: Unknown class name Error: "availableInPerspective:" method must be reimplemented in subclass'.
+
+ actualError := printer objectAttributeAt: #showCR:.
+ self assert: expectedError = actualError.
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Label_03'.
+ 'BunchOfGenerators'.
+ {'Generator_01'}.
+ }.
+
+ actualMenu := self menuItemLabels.
+ self assert: expectedMenu = actualMenu.
+
+ "Created: / 01-02-2015 / 19:17:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 01-02-2015 / 20:17:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_without_filter
+ | expectedMenu actualMenu navigationState |
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Translated BunchOfGenerators'.
+ {'Translated Generator_01'. 'Translated Generator_02'. 'Translated Generator_03'}.
+ 'Label_03'.
+ }.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #();
+ addGenerator: 'Generator_03' group: #().
+
+ "Create some methods which actually uses context and perspective to be sure that they are correctly created"
+ provider last
+ compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
+ compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == CustomMenuBuilderTests name'.
+
+ navigationState := Tools::NavigationState new.
+ navigationState selectedClasses value: {CustomMenuBuilderTests}.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'BunchOfGenerators';
+ afterMenuItemLabelled: 'Label_02';
+ navigationState: navigationState;
+ resources: resources;
+ buildMenu.
+
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu.
+
+ (menu menuItemAt: 3) submenuChannel value itemsDo: [ :item |
+ self assert: item enabled value
+ ].
+
+ "Created: / 29-12-2014 / 09:33:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:08:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 21:09:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_groups_sort_block
+ | expectedGroups actualGroups |
+
+ actualGroups := {
+ #(Group_09 Subgroup_02 Subsubgroup_02).
+ #(Group_09 Subgroup_01 Subsubgroup_02).
+ #(Group_09 Subgroup_01 Subsubgroup_01).
+ #(Group_01).
+ #(Group_09 Subgroup_01).
+ #(Group_01 Subgroup_01).
+ #(Group_03).
+ #(Group_02 Subgroup_02).
+ #(Group_02 Subgroup_01).
+ #(Group_10).
+ #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
+ #().
+ }.
+
+ "Maybe better order?"
+ "
+ expectedGroups := {
+ #().
+ #(Group_01).
+ #(Group_01 Subgroup_01).
+ #(Group_02 Subgroup_01).
+ #(Group_02 Subgroup_02).
+ #(Group_03).
+ #(Group_09 Subgroup_01).
+ #(Group_09 Subgroup_01 Subsubgroup_01).
+ #(Group_09 Subgroup_01 Subsubgroup_02).
+ #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
+ #(Group_09 Subgroup_02 Subsubgroup_02).
+ #(Group_10)
+ }. "
+
+ expectedGroups := {
+ #().
+ #(Group_01).
+ #(Group_03).
+ #(Group_10).
+ #(Group_01 Subgroup_01).
+ #(Group_02 Subgroup_01).
+ #(Group_02 Subgroup_02).
+ #(Group_09 Subgroup_01).
+ #(Group_09 Subgroup_01 Subsubgroup_01).
+ #(Group_09 Subgroup_01 Subsubgroup_02).
+ #(Group_09 Subgroup_02 Subsubgroup_02).
+ #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
+ }.
+
+ actualGroups sort: builder groupsSortBlock.
+
+ self assert: expectedGroups = actualGroups
+
+ "Modified (format): / 28-12-2014 / 21:54:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_place_menu_item_after_menu_item_labeled_for_menu_item_empty
+ | menuItem expectedMenuItemLabels actualMenuItemLabels |
+
+ menuItem := MenuItem label: 'SomeLabel'.
+
+ expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'Label_03'. 'SomeLabel'}.
+
+ builder placeMenuItem: menuItem afterMenuItemLabeled: nil forMenu: menu.
+
+ actualMenuItemLabels := self menuItemLabels.
+
+ self assert: expectedMenuItemLabels = actualMenuItemLabels
+
+ "Created: / 04-01-2015 / 15:41:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_place_menu_item_after_menu_item_labeled_for_menu_item_found
+ | menuItem expectedMenuItemLabels actualMenuItemLabels |
+
+ menuItem := MenuItem label: 'SomeLabel'.
+
+ expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'SomeLabel'. 'Label_03'}.
+
+ builder placeMenuItem: menuItem afterMenuItemLabeled: 'Label_02' forMenu: menu.
+
+ actualMenuItemLabels := self menuItemLabels.
+
+ self assert: expectedMenuItemLabels = actualMenuItemLabels
+
+ "Modified: / 28-12-2014 / 10:41:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_place_menu_item_after_menu_item_labeled_for_menu_item_not_found
+ | menuItem expectedMenuItemLabels actualMenuItemLabels |
+
+ menuItem := MenuItem label: 'SomeLabel'.
+
+ expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'Label_03'. 'SomeLabel'}.
+
+ builder placeMenuItem: menuItem afterMenuItemLabeled: 'NotExistingLabel' forMenu: menu.
+
+ actualMenuItemLabels := self menuItemLabels.
+
+ self assert: expectedMenuItemLabels = actualMenuItemLabels
+
+ "Created: / 28-12-2014 / 10:45:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilderTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMock.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,316 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomMock
+ instanceVariableNames:'mockedClasses'
+ classVariableNames:'MockCount'
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomMock class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Helper for creating mocked classes.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomMock class methodsFor:'initialization'!
+
+initialize
+ "Invoked at system start or when the class is dynamically loaded."
+
+ "/ please change as required (and remove this comment)
+
+ MockCount := 0.
+
+ "Modified: / 11-05-2015 / 09:25:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomMock class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ MockCount isNil ifTrue: [
+ MockCount := 0
+ ].
+
+ ^ self basicNew initialize.
+
+ "Created: / 15-06-2014 / 19:20:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'accessing'!
+
+mockCount
+ "Returns how many mock has been created ever since"
+
+ ^ MockCount
+
+ "Created: / 22-09-2014 / 23:05:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+variableNameForClassMockedSelectors
+
+ ^ 'MockedClassSelectors'
+
+ "Created: / 11-07-2014 / 10:16:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+variableNameForInstanceMockedSelectors
+
+ ^ 'MockedSelectors'
+
+ "Created: / 11-07-2014 / 10:15:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'code generation'!
+
+createMockClassOf: aClass mockNumber: aNumber
+ "Returns generated mock subclass of given class
+ to support custom return values of overriden methods"
+
+ | mockClass className mockClassName |
+
+ className := aClass theNonMetaclass name.
+ mockClassName := ('CustomMock', aNumber asString, 'Of', className copyReplaceAll: $: with: $_).
+
+ Class withoutUpdatingChangesDo:[
+ | definition |
+
+ definition := className, ' subclass:#''SmallSense::', mockClassName, '''
+ instanceVariableNames:''''
+ classVariableNames:''MockedSelectors MockedClassSelectors''
+ poolDictionaries:''''
+ category:''Interface-Refactoring-Custom-Mocks'''.
+
+ (InteractiveAddClassChange definition: definition) execute.
+
+ mockClass := Smalltalk classNamed: ('SmallSense::', mockClassName) asSymbol.
+
+ self createMockMethodWithSingleValue: mockClass.
+ self createMockMethodWithCompileMethod: mockClass.
+ ].
+
+ ^ mockClass
+
+ "Created: / 15-06-2014 / 19:15:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-02-2015 / 22:46:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-05-2015 / 19:39:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+createMockGetters: aMockClass forSelectors: aSelectors
+ "Generates mock getter method for each name"
+
+ aSelectors do: [ :selector |
+ | getterSource template |
+
+ template := Method methodDefinitionTemplateForSelector: selector asSymbol.
+
+ getterSource := template, ' ^ self objectAttributeAt: #', selector.
+
+ aMockClass compile: getterSource classified: 'mocking' logged: false.
+ ]
+
+ "Created: / 28-12-2014 / 14:58:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMockMethod: aMockClass methodSource: aSource mockedSelectorsVariableName: aMockedSelectorsVariableName
+ "Generates mock method for given mock class
+ to support custom method value/implementation by some value/block
+ (depends on given source)"
+
+ | newSource |
+
+ newSource := aSource copyReplaceAll: '`mockedSelectorsVariableName' with: aMockedSelectorsVariableName.
+ aMockClass compile: newSource classified: 'mocking' logged:false.
+
+ "Created: / 21-09-2014 / 21:51:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-09-2014 / 21:26:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMockMethodWithCompileMethod: aMockClass
+ "Generates mock method for given mock class
+ to support custom method implementation by given method source"
+
+ self
+ createMockMethod: aMockClass theMetaclass
+ methodSource: self compileMockMethodSource
+ mockedSelectorsVariableName: ''.
+
+ self
+ createMockMethod: aMockClass theNonMetaclass
+ methodSource: self compileMockMethodSource
+ mockedSelectorsVariableName: ''.
+
+ "Created: / 23-09-2014 / 22:44:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMockMethodWithSingleValue: aMockClass
+ "Generates mock method for given mock class
+ to support custom return values of overriden methods"
+
+ | instVarName classVarName |
+
+ classVarName := self variableNameForClassMockedSelectors.
+
+ self
+ createMockMethod: aMockClass theMetaclass
+ methodSource: (self singleValueMethodSource: classVarName)
+ mockedSelectorsVariableName: classVarName.
+
+ instVarName := self variableNameForInstanceMockedSelectors.
+
+ self
+ createMockMethod: aMockClass theNonMetaclass
+ methodSource: (self singleValueMethodSource: instVarName)
+ mockedSelectorsVariableName: instVarName.
+
+ "Created: / 21-09-2014 / 21:45:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'code generation - sources'!
+
+compileMockMethodSource
+ "Returns mock method source code which will compile method source."
+
+ ^ 'compileMockMethod: aSourceCode
+
+ self class compile:aSourceCode classified:''mocks'' logged:false'.
+
+ "Created: / 23-09-2014 / 22:31:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+singleValueMethodSource: aMockedSelectorsVariableName
+ "Returns mock method source code for given variable name
+ which holds mocked selectors and its values.
+ These values are constants (within method) like numbers, classes, objects..."
+
+ ^ 'mockSelector: aSelector withReturnValue: aValue
+
+ | classQuery superclassMethod methodDefinitionTemplate |
+
+ `mockedSelectorsVariableName isNil ifTrue: [
+ `mockedSelectorsVariableName := Dictionary new
+ ].
+
+ `mockedSelectorsVariableName at: aSelector asSymbol put: aValue.
+
+ classQuery := CustomClassQuery new.
+ superclassMethod := classQuery methodForSuperclassSelector: aSelector class: self class.
+ methodDefinitionTemplate := superclassMethod methodDefinitionTemplate asString.
+
+ self compileMockMethod: (methodDefinitionTemplate, ''
+ ^ `mockedSelectorsVariableName at: #'', aSelector)'.
+
+ "Created: / 10-07-2014 / 22:23:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-09-2014 / 21:00:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'initialization'!
+
+initialize
+
+ mockedClasses := OrderedCollection new
+
+ "Created: / 15-06-2014 / 19:19:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'mock creation'!
+
+mockClassOf: aClass
+ "Creates a mock class of given class"
+ | mockClass |
+
+ mockClass := self createMockClassOf: aClass mockNumber: MockCount.
+
+ MockCount := MockCount + 1.
+ mockedClasses add: mockClass.
+
+ ^ mockClass
+
+ "Created: / 15-06-2014 / 23:41:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 22-09-2014 / 23:11:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+mockOf: aClass
+ "Creates a mock class instance of given class"
+
+ ^ (self mockClassOf: aClass) new
+
+ "Created: / 15-06-2014 / 23:44:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'mock release'!
+
+unmockAll
+
+ Class withoutUpdatingChangesDo:[
+ mockedClasses do: [ :class |
+ class removeFromSystem
+ ].
+
+ mockedClasses removeAll
+ ]
+
+ "Created: / 15-06-2014 / 19:30:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-09-2014 / 21:47:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
+
+CustomMock initialize!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMockTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,473 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomMockTests
+ instanceVariableNames:'model mock testCompleted'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomMockTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomMockTests methodsFor:'initialization & release'!
+
+setUp
+
+ model := CustomNamespace new.
+ mock := CustomMock new.
+ testCompleted := false.
+
+ "Modified: / 09-10-2014 / 09:34:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ model undoChanges.
+ mock unmockAll
+
+ "Modified: / 19-10-2014 / 14:56:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMockTests methodsFor:'private'!
+
+performTest
+ Class withoutUpdatingChangesDo:[
+ self perform: testSelector sunitAsSymbol
+ ]
+
+ "Created: / 24-09-2014 / 21:30:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMockTests methodsFor:'tests'!
+
+test_class_and_instance_methods_overriden_by_compiled_mock_method
+ | class mockClass |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: (class theMetaclass) protocol: 'p' source: 'aSelector_01: aParam
+ ^ 10'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: aParam
+ ^ 15'.
+
+ self assert: (class aSelector_01: nil) = 10.
+ self assert: (class new aSelector_01: nil) = 15.
+
+ mockClass := mock mockClassOf: class.
+ mockClass compileMockMethod: 'aSelector_01: aParam ^ 20'.
+ mockClass new compileMockMethod: 'aSelector_01: aParam ^ 25'.
+
+ self assert: (mockClass aSelector_01: nil) = 20.
+ self assert: (mockClass new aSelector_01: nil) = 25.
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 23-09-2014 / 22:53:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_methods_overriden_by_compiled_mock_method
+ | class mockClass |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: (class theMetaclass) protocol: 'p' source: 'aSelector_01: aParam
+ ^ 10'.
+ model createMethodImmediate: (class theMetaclass) protocol: 'p' source: 'aSelector_02: aParam
+
+ (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+ ^ false'.
+
+ self assert: (class aSelector_02: nil).
+
+ mockClass := mock mockClassOf: class.
+ mockClass compileMockMethod: 'aSelector_01: aParam ^ 20'.
+
+ self assert: (mockClass aSelector_01: nil) = 20.
+ self assert: (mockClass aSelector_02: nil) not.
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 23-09-2014 / 22:54:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_methods_overriden_by_mock
+ | class mockClass |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: class theMetaclass protocol: 'p' source: 'aSelector_01: aParam
+ ^ 10'.
+ model createMethodImmediate: class theMetaclass protocol: 'p' source: 'aSelector_02: aParam
+
+ (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+ ^ false'.
+
+ self assert: (class aSelector_02: nil).
+
+ mockClass := mock mockClassOf: class.
+ mockClass mockSelector: #aSelector_01: withReturnValue: 20.
+
+ self assert: (mockClass aSelector_01: nil) = 20.
+ self assert: (mockClass aSelector_02: nil) not.
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 10-07-2014 / 19:35:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 22-09-2014 / 23:14:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_mock_getters_for_selectors
+ | expectedSource01 actualSource01 expectedSource02 actualSource02 mockClass |
+
+ mockClass := mock mockClassOf: Object.
+ mock createMockGetters: mockClass forSelectors: {'selector'. 'selector:'}.
+
+ expectedSource01 := 'selector ^ self objectAttributeAt: #selector'.
+ expectedSource02 := 'selector:arg ^ self objectAttributeAt: #selector:'.
+
+ actualSource01 := mockClass sourceCodeAt:#selector.
+ actualSource02 := mockClass sourceCodeAt:#selector:.
+
+ self assert: expectedSource01 = actualSource01.
+ self assert: expectedSource02 = actualSource02.
+
+ "Modified: / 28-12-2014 / 15:29:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method
+ | class mockClassInstance |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: aParam
+ ^ 10'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_02: aParam
+
+ (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+ ^ false'.
+
+ self assert: (class new aSelector_02: nil).
+
+ mockClassInstance := mock mockOf: class.
+ mockClassInstance compileMockMethod: 'aSelector_01: aParam ^ 20'.
+
+ self assert: (mockClassInstance aSelector_01: nil) = 20.
+ self assert: (mockClassInstance aSelector_02: nil) not.
+
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 23-09-2014 / 22:54:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method_value_with_params
+ | class mockClassInstance |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: aParam
+ ^ 10'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_02: aParam
+
+ (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+ ^ false'.
+
+ self assert: (class new aSelector_02: nil).
+
+ mockClassInstance := mock mockOf: class.
+ mockClassInstance compileMockMethod: 'aSelector_01: aParam
+ aParam = 5 ifTrue: [
+ ^ 10
+ ].
+
+ ^ 30'.
+
+ self assert: (mockClassInstance aSelector_01: 5) = 10.
+ self assert: (mockClassInstance aSelector_02: 3) not.
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 23-09-2014 / 22:54:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method_value_with_two_params
+ | class mockClassInstance |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: arg_01 param_02: arg_02
+ ^ 10'.
+
+ self assert: ((class new aSelector_01: 1 param_02: 2) = 10).
+
+ mockClassInstance := mock mockOf: class.
+ mockClassInstance compileMockMethod: 'aSelector_01:arg_01 param_02:arg_02 ^ arg_01 + arg_02'.
+
+ self assert: (mockClassInstance aSelector_01: 3 param_02: 3) = 6.
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 23-09-2014 / 22:54:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method_with_none_params
+ | class mockClassInstance |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_01
+ ^ 10'.
+
+ self assert: (class new aSelector_01 = 10).
+
+ mockClassInstance := mock mockOf: class.
+ mockClassInstance compileMockMethod: 'aSelector_01 ^ 30'.
+
+ self assert: (mockClassInstance aSelector_01) = 30.
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 23-09-2014 / 22:54:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method_with_three_params
+ | class mockClassInstance |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: arg_01 param_02: arg_02 param_03: arg_03
+ ^ 10'.
+
+ self assert: ((class new aSelector_01: 1 param_02: 2 param_03: 3) = 10).
+
+ mockClassInstance := mock mockOf: class.
+ mockClassInstance compileMockMethod: 'aSelector_01:arg_01 param_02:arg_02 param_03:arg_03
+ ^ arg_01 + arg_02 + arg_03'.
+
+ self assert: (mockClassInstance aSelector_01: 3 param_02: 3 param_03: 3) = 9.
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 23-09-2014 / 22:55:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_mock
+ | class mockClassInstance |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: aParam
+ ^ 10'.
+ model createMethodImmediate: class protocol: 'p' source: 'aSelector_02: aParam
+
+ (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+ ^ false'.
+
+ self assert: (class new aSelector_02: nil).
+
+ mockClassInstance := mock mockOf: class.
+ mockClassInstance mockSelector: #aSelector_01: withReturnValue: 20.
+
+ self assert: (mockClassInstance aSelector_01: nil) = 20.
+ self assert: (mockClassInstance aSelector_02: nil) not.
+
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 15-06-2014 / 20:19:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 22-09-2014 / 23:14:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_mock_count_incremented_when_new_class_created
+ | class mockCount |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+
+ mockCount := mock mockCount.
+
+ mock mockOf: class.
+
+ self assert: (mockCount + 1) = (mock mockCount).
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 22-09-2014 / 23:05:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:19:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_namespace_not_created_for_class_with_namespace
+ "If class name contains also namespace name then it is created along with the class.
+ Assert that namespace is not created, because there is no use for it in temporary class
+ - only leaves mess in the browser."
+ | class expectedNameSpaceCount actualNameSpaceCount |
+
+ [
+ class := model createClassImmediate: 'DummyNameSpace01::DummyClass01'.
+
+ expectedNameSpaceCount := NameSpace allNameSpaces size.
+ self assert: expectedNameSpaceCount > 1.
+
+ mock mockClassOf: class.
+
+ actualNameSpaceCount := NameSpace allNameSpaces size.
+
+ self assert: expectedNameSpaceCount = actualNameSpaceCount.
+
+ testCompleted := true.
+
+ ] ensure: [
+ (Smalltalk at: #DummyNameSpace01) notNil ifTrue: [
+ Class withoutUpdatingChangesDo: [
+ (Smalltalk at: #DummyNameSpace01) removeFromSystem
+ ]
+ ].
+
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 24-01-2015 / 19:22:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:19:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_unmock_all
+ | class mockClass mockClassName |
+
+ [
+ class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+
+ mockClass := mock mockClassOf: class.
+ mockClassName := mockClass name.
+
+ self assert: (Smalltalk at: mockClassName) isNil not.
+ mock unmockAll.
+ self assert: (Smalltalk at: mockClassName) isNil.
+
+ testCompleted := true.
+
+ ] ensure: [
+ "Need to test if test is complete, because in this case
+ sometimes happens that the test terminates and is marked as success."
+ self assert: testCompleted
+ ].
+
+ "Created: / 23-09-2014 / 22:58:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMockTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMultiSetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,161 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomMultiSetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomMultiSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Multi-Setter Method(s) for selected instance variables'
+
+ "Modified: / 13-07-2014 / 19:06:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Getters')
+
+ "Created: / 22-08-2014 / 18:54:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Multi-Setter Method(s)'
+
+ "Modified: / 13-07-2014 / 19:06:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+
+ ^ aCustomContext selectedClasses notEmptyOrNil and: [
+ aCustomContext selectedVariables notEmptyOrNil and: [
+ aCustomContext selectedVariables size >= 2
+ ]
+ ]
+
+ "Created: / 13-07-2014 / 19:14:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+createMultiSetterMethodForVariables: aVariableNames inClass: aClass
+ "Creates multi-setter access method for given variable names and class"
+
+ | setterSelector comment assignVariablesCode |
+
+ setterSelector := ''.
+ comment := ''.
+ assignVariablesCode := ''.
+
+ userPreferences generateCommentsForSetters ifTrue: [
+ comment := '"set instance variables"'.
+ ].
+
+ aVariableNames do: [ :variableName |
+ | argumentName |
+
+ argumentName := variableName asString, 'Arg'.
+
+ setterSelector := setterSelector, variableName asString, ': ', argumentName, ' '.
+ assignVariablesCode := assignVariablesCode, variableName asString, ' := ', argumentName, '. '.
+ ].
+
+ model createMethod
+ class: aClass;
+ protocol: 'accessing';
+ source: '`@setterSelector
+ `"comment
+
+ `@assignVariablesCode
+ ';
+ replace: '`@setterSelector' with: setterSelector asSymbol;
+ replace: '`"comment' with: comment;
+ replace: '`@assignVariablesCode' with: assignVariablesCode;
+ compile.
+
+ "Created: / 13-07-2014 / 20:45:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-10-2014 / 19:00:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ "Creates multi-setter access methods for given context"
+
+ aCustomContext selectedClasses do:[ :class |
+ self
+ createMultiSetterMethodForVariables: aCustomContext selectedVariables
+ inClass: class
+ ].
+
+ "Modified: / 13-07-2014 / 20:45:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMultiSetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,165 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomMultiSetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomMultiSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomMultiSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomMultiSetterMethodsCodeGenerator new
+! !
+
+!CustomMultiSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_available_in_context_for_none_variable_names
+
+ context
+ selectedClasses: (Array with: self class).
+
+ self assert: (generatorOrRefactoring class availableInContext: context) not.
+
+ "Created: / 13-07-2014 / 20:11:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_for_one_variable_name
+
+ context
+ selectedClasses: (Array with: self class);
+ selectedVariables: (Array with: 'var_01').
+
+ self assert: (generatorOrRefactoring class availableInContext: context) not.
+
+ "Created: / 13-07-2014 / 20:08:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_for_three_variable_names
+
+ context
+ selectedClasses: (Array with: self class);
+ selectedVariables: (Array with: 'var_01' with: 'var_02' with: 'var_03').
+
+ self assert: (generatorOrRefactoring class availableInContext: context).
+
+ "Created: / 13-07-2014 / 20:10:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_for_two_variable_names
+
+ context
+ selectedClasses: (Array with: self class);
+ selectedVariables: (Array with: 'var_01' with: 'var_02').
+
+ self assert: (generatorOrRefactoring class availableInContext: context).
+
+ "Created: / 13-07-2014 / 20:09:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_multi_setter_method_generated_with_comments_for_three_variables
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: true.
+
+ expectedSource := 'instanceVariable_01:instanceVariable_01Arg instanceVariable_02:instanceVariable_02Arg instanceVariable_03:instanceVariable_03Arg
+ "set instance variables"
+
+ instanceVariable_01 := instanceVariable_01Arg.
+ instanceVariable_02 := instanceVariable_02Arg.
+ instanceVariable_03 := instanceVariable_03Arg.'.
+
+ self executeGeneratorInContext: #classWithThreeInstanceVariables.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_01:instanceVariable_02:instanceVariable_03:
+
+ "Created: / 13-07-2014 / 21:55:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 22:37:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_multi_setter_method_generated_with_comments_for_two_variables
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: true.
+
+ expectedSource := 'instanceVariable_01:instanceVariable_01Arg instanceVariable_02:instanceVariable_02Arg
+ "set instance variables"
+
+ instanceVariable_01 := instanceVariable_01Arg.
+ instanceVariable_02 := instanceVariable_02Arg.'.
+
+ self executeGeneratorInContext: #classWithTwoInstanceVariables.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_01:instanceVariable_02:
+
+ "Created: / 13-07-2014 / 21:53:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 22:37:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_multi_setter_method_generated_without_comments_for_two_variables
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: false.
+
+ expectedSource := 'instanceVariable_01:instanceVariable_01Arg instanceVariable_02:instanceVariable_02Arg
+ instanceVariable_01 := instanceVariable_01Arg.
+ instanceVariable_02 := instanceVariable_02Arg.'.
+
+ self executeGeneratorInContext: #classWithTwoInstanceVariables.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable_01:instanceVariable_02:
+
+ "Created: / 13-07-2014 / 21:57:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 22:37:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNamespace.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,455 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+RBNamespace subclass:#CustomNamespace
+ instanceVariableNames:'changeManager formatter classModelClass methodModelClass
+ sourceCodeGeneratorClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomNamespace class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomNamespace methodsFor:'accessing'!
+
+at: aClassName
+
+ ^ self classNamed: aClassName asSymbol
+
+ "Created: / 15-11-2014 / 17:30:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+changeManager
+ ^ changeManager
+!
+
+changeManager:something
+ changeManager := something.
+!
+
+classModelClass
+ "Returns class which represents Class in model in which we make changes (add class, rename class ...)."
+
+ ^ classModelClass
+
+ "Modified (comment): / 09-10-2014 / 11:14:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classModelClass: aClass
+ "see classModelClass"
+
+ classModelClass := aClass.
+
+ "Modified (comment): / 09-10-2014 / 11:15:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter
+ ^ formatter
+
+ "Created: / 28-08-2014 / 23:19:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter: aFormatter
+ formatter := aFormatter
+
+ "Created: / 28-08-2014 / 23:19:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodModelClass
+ "Returns class which represents Method in model in which we make changes (add method, change method source ...)."
+
+ ^ methodModelClass
+
+ "Modified (comment): / 09-10-2014 / 11:17:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodModelClass: aClass
+ "see methodModelClass"
+
+ methodModelClass := aClass.
+
+ "Modified (comment): / 09-10-2014 / 11:16:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+putModelClass: aModelClass
+ "Stores model class (e.g. RBClass) in this model so we can work further with
+ the given class and the modifications done to the given class
+ are reflected in this model (represented by CustomNamespace/RBNamespace)."
+ | classIndex name isClassUndefined |
+
+ classIndex := 1.
+ name := aModelClass name.
+ aModelClass isMeta ifTrue: [
+ classIndex := 2.
+ name := aModelClass theNonMetaclass name.
+ ].
+
+ isClassUndefined := true.
+ newClasses at: name ifPresent: [ :classes |
+ isClassUndefined := false.
+ classes at: classIndex put: aModelClass
+ ].
+
+ changedClasses at: name ifPresent: [ :classes |
+ isClassUndefined := false.
+ classes at: classIndex put: aModelClass
+ ].
+
+ isClassUndefined ifTrue: [
+ self error: 'Class has to be defined in the model - see defineClass: .'.
+ ]
+
+ "Created: / 04-11-2014 / 00:03:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-11-2014 / 01:07:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+sourceCodeGenerator
+ "Returns initialized source code generator (CodeGenerator, CustomSourceCodeGenerator)"
+ | sourceCodeGenerator |
+
+ sourceCodeGenerator := self sourceCodeGeneratorClass new.
+ sourceCodeGenerator formatter: formatter.
+ ^ sourceCodeGenerator.
+
+ "Created: / 19-09-2014 / 20:56:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 09-10-2014 / 11:35:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 27-11-2014 / 19:32:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+sourceCodeGeneratorClass
+ "Returns code generator class which supports search & replace in method source code and formatting"
+
+ ^ sourceCodeGeneratorClass
+
+ "Modified (comment): / 09-10-2014 / 11:34:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+sourceCodeGeneratorClass: aClass
+ "see sourceCodeGeneratorClass"
+
+ sourceCodeGeneratorClass := aClass.
+
+ "Modified (comment): / 09-10-2014 / 11:34:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'accessing-classes'!
+
+classNamed: aName
+ "Returns an RBClass instance stored under given class name
+ or nil if nothing found"
+
+ ^ super classNamed: aName asSymbol
+
+ "Created: / 19-11-2014 / 21:19:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+metaclassNamed: aName
+ "Returns an RBMetaclass instance stored under given class name
+ or nil if nothing found"
+
+ ^ super metaclassNamed: aName asSymbol
+
+ "Created: / 19-11-2014 / 21:20:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'changes'!
+
+defineClass: aString
+ "Defines a class withing this model by its definition string.
+ Here is same behaviour as in RBNamespace, but we added private
+ class support."
+ | change |
+
+ change := super defineClass: aString.
+ change privateInClassName notNil ifTrue: [
+ | class |
+
+ class := self classNamed: change changeClassName.
+ class owningClass: (self classNamed: change privateInClassName)
+ ].
+
+ ^ change
+
+ "Created: / 29-11-2014 / 14:39:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'code creation'!
+
+createClass
+ "Much like createMethod, but for class"
+
+ ^ self classModelClass new
+ model: self;
+ superclass: (self classNamed: #Object);
+ instanceVariableNames: #();
+ classVariableNames: #();
+ poolDictionaryNames: #();
+ yourself.
+
+ "Created: / 09-04-2014 / 21:38:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-02-2015 / 22:31:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMethod
+ "
+ Creates, returns method representation
+ so code changes can be created withing this class as one undo change
+ "
+
+ ^ self methodModelClass new
+ model: self;
+ sourceCodeGenerator: self sourceCodeGenerator;
+ yourself.
+
+ "Created: / 09-04-2014 / 23:54:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-02-2015 / 22:32:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'code creation - immediate'!
+
+createClassImmediate: aClassName
+ "Creates class immediately and returns the real class"
+
+ ^ self createClassImmediate: aClassName superClassName: 'Object'
+
+ "Created: / 27-07-2014 / 12:40:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName category: aCategoryName
+ "Creates class immediately and returns the real class"
+
+ ^ self
+ createClassImmediate: aClassName
+ superClassName: 'Object'
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: aCategoryName
+
+ "Created: / 19-10-2014 / 20:55:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName instanceVariableNames: instVarNames
+ "Creates class immediately and returns the real class"
+
+ ^ self
+ createClassImmediate: aClassName
+ superClassName: 'Object'
+ instanceVariableNames: instVarNames
+ classVariableNames: ''
+
+ "Created: / 23-08-2014 / 22:25:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName
+ "Creates class immediately and returns the real class"
+
+ ^ self
+ createClassImmediate: aClassName
+ superClassName: aSuperClassName
+ instanceVariableNames: ''
+ classVariableNames: ''
+
+ "Created: / 15-06-2014 / 15:59:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 23-08-2014 / 22:18:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: instVarNames classVariableNames: classVarNames
+ "Creates class immediately and returns the real class"
+
+ ^ self createClassImmediate: aClassName
+ superClassName: aSuperClassName
+ instanceVariableNames: instVarNames
+ classVariableNames: classVarNames
+ poolDictionaries: ''
+ category: ''
+
+ "Created: / 23-08-2014 / 22:18:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-10-2014 / 20:49:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDict category: category
+ "Creates class immediately and returns the real class"
+
+ ^ self createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDict category: category privateIn: nil
+
+ "Created: / 19-10-2014 / 20:47:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-10-2014 / 21:46:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDict category: category privateIn: privateInClassName
+ "Creates class immediately and returns the real class"
+ | newClassName change |
+
+ newClassName := aClassName.
+
+ privateInClassName isNil ifTrue: [
+ change := (InteractiveAddClassChange definition:
+ aSuperClassName asString, ' subclass:#', aClassName asString, '
+ instanceVariableNames:''', instVarNames asString, '''
+ classVariableNames:''', classVarNames asString, '''
+ poolDictionaries:''', poolDict asString, '''
+ category:''', category asString, '''
+ ')
+ ] ifFalse: [
+ change := (InteractiveAddClassChange definition:
+ aSuperClassName asString, ' subclass:#', aClassName asString, '
+ instanceVariableNames:''', instVarNames asString, '''
+ classVariableNames:''', classVarNames asString, '''
+ poolDictionaries:''', poolDict asString, '''
+ privateIn:', privateInClassName asString, '
+ ').
+
+ newClassName := privateInClassName asString, '::', aClassName asString.
+ ].
+
+ changeManager performChange: change.
+
+ ^ Smalltalk classNamed: newClassName
+
+ "Created: / 30-10-2014 / 21:28:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 02-11-2014 / 16:30:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName privateIn: privateInClassName
+ "Creates class immediately and returns the real class"
+
+ ^ self createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: '' privateIn: privateInClassName
+
+ "Created: / 30-10-2014 / 21:47:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMethodImmediate: aClass protocol: aProtocol source: aSource
+ "Much like createClassImmediate:superClassName:, but for method"
+
+ ^ self createMethodImmediate: aClass protocol: aProtocol source: aSource package: nil
+
+ "Created: / 15-06-2014 / 16:06:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 17-10-2014 / 09:58:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMethodImmediate: aClass protocol: aProtocol source: aSource package: aPackageId
+ "Much like createClassImmediate:superClassName:, but for method"
+
+ | selector change |
+
+ change := InteractiveAddMethodChange compile: aSource in: aClass classified: aProtocol.
+
+ (aPackageId notNil and: [ (change class canUnderstand: #package:) ]) ifTrue: [
+ change package: aPackageId
+ ].
+
+ changeManager performChange: change.
+
+ selector := (Parser parseMethodSpecification: aSource) selector.
+ ^ aClass compiledMethodAt: selector
+
+ "Created: / 17-10-2014 / 09:53:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 02-11-2014 / 16:17:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMethodImmediate: aClass source: aSource
+ "Much like createClassImmediate:superClassName:, but for method"
+
+ ^ self createMethodImmediate: aClass protocol: 'protocol' source: aSource
+
+ "Created: / 23-08-2014 / 20:17:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'compiling'!
+
+execute
+ "Performs code changes ( add method, add class, rename class... )
+ so they take in effect ( method is added, class is renamed, ... )
+ with respect to current change manager implementatin - see CustomChangeManager subclasses."
+
+ changeManager performChange: changes
+
+ "Created: / 27-04-2014 / 16:30:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 21-09-2014 / 22:34:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 19-10-2014 / 14:30:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+undoChanges
+ "redo all changes made by execute method"
+
+ changeManager undoChanges
+
+ "Created: / 19-10-2014 / 14:56:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'initialization'!
+
+initialize
+ "Invoked when a new instance is created."
+
+ super initialize.
+ changeManager := SmallSense::CustomLocalChangeManager new.
+ formatter := SmallSense::CustomRBLocalSourceCodeFormatter new.
+ classModelClass := RBClass.
+ methodModelClass := RBMethod.
+ sourceCodeGeneratorClass := CustomSourceCodeGenerator.
+
+ "Created: / 09-04-2014 / 23:44:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-02-2015 / 22:33:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:08:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'testing'!
+
+isNamespace
+ ^ true
+
+ "Created: / 15-11-2014 / 17:29:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNamespaceTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,979 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomNamespaceTests
+ instanceVariableNames:'refactoryChangeManager'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomNamespaceTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomNamespaceTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ nil
+
+ "Modified: / 31-05-2014 / 22:48:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespaceTests methodsFor:'initialization & release'!
+
+setUp
+
+ super setUp.
+ refactoryChangeManager := RefactoryChangeManager instance.
+
+ "Created: / 16-04-2014 / 21:39:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 31-05-2014 / 22:45:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespaceTests methodsFor:'private'!
+
+lastUndoChange
+
+ refactoryChangeManager undoableOperations isEmpty ifTrue: [
+ ^ nil
+ ] ifFalse: [
+ ^ refactoryChangeManager undoChange
+ ].
+
+ "Created: / 16-04-2014 / 21:40:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 31-05-2014 / 19:53:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespaceTests methodsFor:'tests'!
+
+test_all_class_var_names
+ | class actualClassVars expectedClassVars |
+
+ class := model createClass
+ name: #MockClassForTestCase;
+ classVariableNames: #('ClassVar1' 'ClassVar2');
+ yourself.
+
+ expectedClassVars := (Object allClassVarNames, (Array with: #ClassVar1 with: #ClassVar2)).
+ actualClassVars := class theNonMetaclass allClassVarNames.
+
+ self assert: expectedClassVars = actualClassVars
+
+ "Created: / 20-06-2014 / 22:35:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 09-10-2014 / 10:47:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_at_class_found
+ | expectedClass actualClass |
+
+ expectedClass := model createClass
+ name: #DummyClass01;
+ compile;
+ yourself.
+
+ actualClass := model at: #DummyClass01.
+
+ self assert: expectedClass = actualClass
+
+ "Modified: / 16-11-2014 / 17:08:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_at_class_missing
+ | expectedClass actualClass |
+
+ expectedClass := nil.
+
+ actualClass := model at: #DummyClass01.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 16-11-2014 / 17:08:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_changes_empty_as_default
+
+ self assert: model changes size == 0
+
+ "Created: / 22-07-2014 / 22:52:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:23:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_and_class_method_generated_as_one_undo_change
+ | className class lastUndoChange |
+
+ lastUndoChange := self lastUndoChange.
+
+ className := #MockClassForTestingOneUndoChange.
+
+ self assertClassNotExists: className.
+
+ model := CustomNamespace new.
+ model changeManager: refactoryChangeManager.
+
+ class := model createClass
+ name: className;
+ compile;
+ yourself.
+
+ self assertClassNotExists: className.
+
+ model createMethod
+ class: class theMetaclass;
+ protocol: 'a protocol';
+ source: 'aSelector
+ ^ nil';
+ compile.
+
+ self assertClassNotExists: className.
+ self assert: lastUndoChange = (self lastUndoChange).
+
+ model execute.
+
+ self assertClassExists: className.
+ self deny: lastUndoChange = (self lastUndoChange).
+ self assert: ((Smalltalk classNamed: className) class includesSelector: #aSelector).
+ self assert: ((Smalltalk classNamed: className) includesSelector: #aSelector) not.
+
+ refactoryChangeManager undoOperation.
+
+ self assertClassNotExists: className.
+ self assert: lastUndoChange = (self lastUndoChange).
+
+ "Created: / 17-04-2014 / 23:54:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 14:40:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_and_instance_method_generated_as_one_undo_change
+ | className class lastUndoChange |
+
+ lastUndoChange := self lastUndoChange.
+
+ className := #MockClassForTestingOneUndoChange.
+
+ self assertClassNotExists: className.
+
+ model := CustomNamespace new.
+ model changeManager: refactoryChangeManager.
+
+ class := model createClass
+ name: className;
+ compile;
+ yourself.
+
+ self assertClassNotExists: className.
+
+ model createMethod
+ class: class;
+ protocol: 'a protocol';
+ source: 'aSelector
+ ^ nil';
+ compile.
+
+ self assertClassNotExists: className.
+ self assert: lastUndoChange = (self lastUndoChange).
+
+ model execute.
+
+ self assertClassExists: className.
+ self deny: lastUndoChange = (self lastUndoChange).
+ self assert: ((Smalltalk classNamed: className) includesSelector: #aSelector).
+
+ refactoryChangeManager undoOperation.
+
+ self assertClassNotExists: className.
+ self assert: lastUndoChange = (self lastUndoChange).
+
+ "Created: / 17-04-2014 / 23:54:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 14:40:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_comment_in_method_generated
+ | class generatedSource expectedSource |
+
+ class := self class.
+
+ model createMethod
+ class: self class;
+ protocol: 'a protocol';
+ source: 'aSelector
+ "a comment"
+ ^ nil';
+ compile.
+
+ self assert: (class includesSelector: #aSelector) not.
+
+ model execute.
+
+ generatedSource := (class sourceCodeAt: #aSelector).
+ expectedSource := 'aSelector
+ "a comment"
+
+ ^ nil'.
+
+ self assert: (class includesSelector: #aSelector).
+ self assert: (generatedSource includesSubString: '"a comment"').
+ self assertSource: expectedSource sameAs: generatedSource
+
+ "Created: / 27-04-2014 / 15:57:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 26-08-2014 / 23:42:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 09-10-2014 / 23:06:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate
+ | mockClass |
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase'.
+
+ self assert: mockClass new className = 'MockClassForTestCase'.
+ self assert: mockClass superclass new className = 'Object'.
+ self assert: mockClass instanceVariableString = ''.
+ self assert: mockClass classVariableString = ''.
+ self assert: mockClass poolDictionaries = ''.
+ self assert: mockClass category = ''.
+
+ "Created: / 15-06-2014 / 17:27:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 27-07-2014 / 12:42:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_object_changes_kept
+ | expectedId actualId mockClass |
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase01'.
+ expectedId := mockClass identityHash.
+ mockClass package: #some_package.
+
+ model createClassImmediate: 'MockClassForTestCase02'.
+ self assertClassExists: #MockClassForTestCase02.
+
+ actualId := (Smalltalk at: #MockClassForTestCase01) identityHash.
+
+ self assert: expectedId = actualId.
+ self assert: (Smalltalk at: #MockClassForTestCase01) package = #some_package.
+
+ "Created: / 02-11-2014 / 16:27:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_super_class_name_instance_variable_names_class_variable_names_pool_dictionaries_category_private_in_private_class
+ | mockClass |
+
+ mockClass := model
+ createClassImmediate: 'MockClassForTestCase'
+ superClassName: 'Object'
+ instanceVariableNames: 'instVar'
+ classVariableNames: 'ClassVar'
+ poolDictionaries: 'pollDict01'
+ category: 'Some-Category01'
+ privateIn: 'Object'.
+
+ self assert: mockClass name = 'Object::MockClassForTestCase'.
+ self assert: mockClass superclass name = 'Object'.
+ self assert: mockClass instanceVariableString = 'instVar'.
+ self assert: mockClass classVariableString = 'ClassVar'.
+ self assert: mockClass poolDictionaries = 'pollDict01'.
+ self assert: mockClass category = Object category.
+ self assert: (mockClass owningClass name) = 'Object'.
+
+ "Modified: / 31-10-2014 / 00:19:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_super_class_name_private_in
+ | mockClass |
+
+ mockClass := model
+ createClassImmediate: 'MockClassForTestCase'
+ superClassName: 'Object'
+ privateIn: 'Object'.
+
+ self assert: mockClass name = 'Object::MockClassForTestCase'.
+ self assert: mockClass superclass name = 'Object'.
+ self assert: mockClass instanceVariableString = ''.
+ self assert: mockClass classVariableString = ''.
+ self assert: mockClass poolDictionaries = ''.
+ self assert: mockClass category = Object category.
+ self assert: (mockClass owningClass name) = 'Object'.
+
+ "Modified: / 31-10-2014 / 00:20:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_category
+ | mockClass |
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase' category: 'Some-Category01'.
+
+ self assert: mockClass new className = 'MockClassForTestCase'.
+ self assert: mockClass superclass new className = 'Object'.
+ self assert: mockClass instanceVariableString = ''.
+ self assert: mockClass classVariableString = ''.
+ self assert: mockClass poolDictionaries = ''.
+ self assert: mockClass category = 'Some-Category01'.
+
+ "Modified: / 19-10-2014 / 20:56:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_given_super_class_name
+ | mockClass |
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+
+ self assert: mockClass new className = 'MockClassForTestCase'.
+ self assert: mockClass superclass new className = 'Object'.
+ self assert: mockClass instanceVariableString = ''.
+ self assert: mockClass classVariableString = ''.
+ self assert: mockClass poolDictionaries = ''.
+ self assert: mockClass category = ''.
+
+ "Created: / 27-07-2014 / 12:42:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_instance_and_class_variables
+ | mockClass |
+
+ mockClass := model
+ createClassImmediate: 'MockClassForTestCase'
+ superClassName: 'Object'
+ instanceVariableNames: 'instVar'
+ classVariableNames: 'ClassVar'.
+
+ self assert: mockClass new className = 'MockClassForTestCase'.
+ self assert: mockClass superclass new className = 'Object'.
+ self assert: mockClass instanceVariableString = 'instVar'.
+ self assert: mockClass classVariableString = 'ClassVar'.
+ self assert: mockClass poolDictionaries = ''.
+ self assert: mockClass category = ''.
+
+ "Created: / 23-08-2014 / 22:24:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_instance_variables
+ | mockClass |
+
+ mockClass := model
+ createClassImmediate: 'MockClassForTestCase'
+ instanceVariableNames: 'instVar'.
+
+ self assert: mockClass new className = 'MockClassForTestCase'.
+ self assert: mockClass superclass new className = 'Object'.
+ self assert: mockClass instanceVariableString = 'instVar'.
+ self assert: mockClass classVariableString = ''.
+ self assert: mockClass poolDictionaries = ''.
+ self assert: mockClass category = ''.
+
+ "Created: / 23-08-2014 / 22:26:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_super_class_name_instance_variable_names_class_variable_names_pool_dictionaries_category
+ | mockClass |
+
+ mockClass := model
+ createClassImmediate: 'MockClassForTestCase'
+ superClassName: 'Object'
+ instanceVariableNames: 'instVar'
+ classVariableNames: 'ClassVar'
+ poolDictionaries: 'pollDict01'
+ category: 'Some-Category01'.
+
+ self assert: mockClass new className = 'MockClassForTestCase'.
+ self assert: mockClass superclass new className = 'Object'.
+ self assert: mockClass instanceVariableString = 'instVar'.
+ self assert: mockClass classVariableString = 'ClassVar'.
+ self assert: mockClass poolDictionaries = 'pollDict01'.
+ self assert: mockClass category = 'Some-Category01'.
+
+ "Modified (comment): / 19-10-2014 / 20:53:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_is_stored_in_model_when_compiled
+ | class classFromModel |
+
+ class := model createClass
+ name: #MockClassForTestCase;
+ compile;
+ yourself.
+
+ class compile: 'selector_01 ^ 1'.
+
+ classFromModel := model classNamed: #MockClassForTestCase.
+
+ self assert: class == classFromModel.
+ self assert: (classFromModel includesSelector: #selector_01).
+
+ "Created: / 03-11-2014 / 22:47:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_then_access_metaclass
+ | class |
+
+ class := model createClass.
+ class name: 'SomeClass'.
+ class superclassName: self class name.
+ "The compile method creates the change object and registers
+ the class in the model (RBNamespace/CustomNamespace)"
+ class compile.
+
+ self assert: class theMetaClass notNil.
+ self assert: class theMetaClass theNonMetaClass == class
+
+ "Created: / 14-11-2014 / 23:53:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 19-11-2014 / 21:32:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_with_instance_variable
+ | expectedVariables actualVariables |
+
+ model createClass
+ name: #DummyClass01;
+ instanceVariableNames: (Array with: 'instanceVariable');
+ compile.
+
+ model execute.
+
+ expectedVariables := #('instanceVariable').
+ actualVariables := (Smalltalk at: #DummyClass01) instanceVariableNames.
+
+ self assert: expectedVariables = actualVariables
+
+ "Created: / 30-11-2014 / 19:11:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_with_name_as_string
+ | class |
+
+ class := model createClass
+ name: 'SomeClass';
+ superclassName: self class name;
+ compile;
+ yourself.
+
+ self assert: class == (model classNamed: #SomeClass).
+ self assert: class == (model classNamed: 'SomeClass').
+ self assert: (class theMetaclass) == (model metaclassNamed: #SomeClass).
+ self assert: (class theMetaclass) == (model metaclassNamed: 'SomeClass').
+
+ "Created: / 19-11-2014 / 21:02:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_with_superclass_name_as_string
+ | superclass |
+
+ model createClass
+ name: 'SomeClass';
+ superclassName: 'Object';
+ compile.
+
+ superclass := model classNamed: 'Object'.
+
+ self assert: superclass == (model classNamed: #Object).
+ self assert: superclass == (model classNamed: 'Object').
+ self assert: (superclass theMetaclass) == (model metaclassNamed: #Object).
+ self assert: (superclass theMetaclass) == (model metaclassNamed: 'Object').
+
+ "Created: / 23-11-2014 / 21:15:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_within_given_package
+ | class package |
+
+ package := self class package.
+ self assert: package size > 3.
+
+ model createClass
+ name: #MockClassForTestCase;
+ package: package;
+ compile.
+
+ model execute.
+
+ class := Smalltalk classNamed: 'MockClassForTestCase'.
+
+ self assert: class new className = 'MockClassForTestCase'.
+ self assert: class superclass new className = 'Object'.
+ self assert: class instanceVariableString = ''.
+ self assert: class classVariableString = ''.
+ self assert: class poolDictionaries = ''.
+ self assert: class category = '** As yet undefined **'.
+ self assert: class package = package.
+
+ "Created: / 30-08-2014 / 20:35:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 09-10-2014 / 23:23:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_without_given_package
+ | class package |
+
+ package := self class package.
+ self assert: package size > 3.
+
+ model createClass
+ name: #MockClassForTestCase;
+ compile.
+
+ model execute.
+
+ class := Smalltalk classNamed: 'MockClassForTestCase'.
+
+ self assert: class new className = 'MockClassForTestCase'.
+ self assert: class superclass new className = 'Object'.
+ self assert: class instanceVariableString = ''.
+ self assert: class classVariableString = ''.
+ self assert: class poolDictionaries = ''.
+ self assert: class category = '** As yet undefined **'.
+ self deny: class package = package.
+
+ "Created: / 30-08-2014 / 20:57:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 14:41:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_immediate
+ | mockClass expectedSource actualSource |
+
+ expectedSource := 'instanceMethod:aParam
+ ^ self'.
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+ model createMethodImmediate: mockClass protocol: 'a protocol' source: expectedSource.
+
+ actualSource := (mockClass sourceCodeAt: #instanceMethod:).
+
+ self assertSource: expectedSource sameAs: actualSource.
+ self assert: (mockClass compiledMethodAt: #instanceMethod:) category = 'a protocol'
+
+ "Created: / 15-06-2014 / 17:28:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-06-2014 / 21:59:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_immediate_object_changes_kept
+ | expectedId actualId mockClass method |
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+ method := model createMethodImmediate: mockClass protocol: 'a protocol' source: 'selector_01 ^ 11'.
+ expectedId := method identityHash.
+ method package: #some_package.
+ model createMethodImmediate: mockClass protocol: 'a protocol' source: 'selector_02 ^ 22'.
+ actualId := (mockClass compiledMethodAt:#selector_01) identityHash.
+
+ self assert: expectedId = actualId.
+ self assert: ((mockClass compiledMethodAt:#selector_01) package) = #some_package.
+
+ "Created: / 02-11-2014 / 16:12:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_immediate_protocol_source_package
+ | expectedSource actualSource mockClass |
+
+ expectedSource := 'instanceMethod:aParam
+ ^ self'.
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+ model createMethodImmediate: mockClass
+ protocol: 'a protocol'
+ source: expectedSource
+ package: #some_package01.
+
+ actualSource := (mockClass sourceCodeAt: #instanceMethod:).
+
+ self assertSource: expectedSource sameAs: actualSource.
+ self assert: (mockClass compiledMethodAt: #instanceMethod:) category = 'a protocol'.
+ self assert: (mockClass compiledMethodAt: #instanceMethod:) package = #some_package01.
+
+ "Modified: / 17-10-2014 / 10:02:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_immediate_with_preset_protocol
+ | mockClass expectedSource actualSource |
+
+ expectedSource := 'instanceMethod:aParam
+ ^ self'.
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+ model createMethodImmediate: mockClass source: expectedSource.
+
+ actualSource := (mockClass sourceCodeAt: #instanceMethod:).
+
+ self assertSource: expectedSource sameAs: actualSource.
+ self assert: (mockClass compiledMethodAt: #instanceMethod:) category = 'protocol'
+
+ "Created: / 23-08-2014 / 21:48:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_within_given_package
+ | mockClass package method |
+
+ package := self class package.
+ self assert: package size > 3.
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+ model createMethod
+ class: mockClass;
+ protocol: 'a protocol';
+ package: package;
+ source: 'selector ^ 123';
+ compile.
+
+ model execute.
+
+ method := (mockClass compiledMethodAt: #selector).
+
+ self assert: method package = package
+
+ "Created: / 30-08-2014 / 18:45:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 00:02:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_without_given_package
+ | mockClass package method |
+
+ package := self class package.
+ self assert: package size > 3.
+
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+ model createMethod
+ class: mockClass;
+ protocol: 'a protocol';
+ source: 'selector ^ 123';
+ compile.
+
+ model execute.
+
+ method := (mockClass compiledMethodAt: #selector).
+
+ self deny: method package = package.
+
+ "Created: / 30-08-2014 / 18:46:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 14:41:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_define_class_with_private_class
+ | expectedClass actualClass |
+
+ expectedClass := model createClass
+ name: #DummyClass01;
+ compile;
+ yourself.
+
+ model defineClass: 'DummyClass01 subclass:#DummyPrivate01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ privateIn:DummyClass01'.
+
+ actualClass := (model classNamed: #'DummyClass01::DummyPrivate01') owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Modified: / 25-01-2015 / 13:12:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_define_class_without_private_class
+ | expectedClass actualClass |
+
+ expectedClass := nil.
+
+ model defineClass: 'Object subclass:#DummyClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:'''''.
+
+ actualClass := (model classNamed: #DummyClass01) owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 14:51:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_empty_class_definition_string
+ | expectedDefinition actualDefinition |
+
+ expectedDefinition := 'Object subclass: #''Unknown Class''
+ instanceVariableNames: ''''
+ classVariableNames: ''''
+ poolDictionaries: ''''
+ category: ''** As yet undefined **'''.
+
+ actualDefinition := model createClass definitionString.
+
+ self assertSource: expectedDefinition sameAs: actualDefinition.
+
+ "Created: / 10-10-2014 / 15:41:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_empty_class_in_changes
+
+ model createClass compile.
+ self assert:(model changes changesSize) = 1.
+
+ "Created: / 22-07-2014 / 22:22:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 15:48:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_namespace
+
+ self assert: model isNamespace
+
+ "Modified: / 16-11-2014 / 17:09:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_source_builded
+ | method expectedSource actualSource |
+
+ method := model createMethod
+ source: '`@methodName
+ ^ `variableName';
+ replace: '`@methodName' with: #selector;
+ replace: '`variableName' with: 'aName';
+ yourself.
+
+ expectedSource := 'selector
+ ^ aName'.
+
+ actualSource := method newSource.
+
+ self assertSource: expectedSource sameAs: actualSource
+
+ "Created: / 18-05-2014 / 17:14:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 26-08-2014 / 23:40:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 15:56:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_source_builded_with_comment
+ | method buildedSource expectedSource |
+
+ method := model createMethod
+ source: '`@methodName
+
+ `"comment
+
+ ^ `variableName';
+ replace: '`@methodName' with: #selector;
+ replace: '`variableName' with: 'aName';
+ replace: '`"comment' with: '"a comment"';
+ yourself.
+
+ buildedSource := method newSource.
+ expectedSource := 'selector
+ "a comment"
+
+ ^ aName'.
+
+ self assertSource: expectedSource sameAs: buildedSource
+
+ "Created: / 19-05-2014 / 18:57:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 26-08-2014 / 23:55:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 15:56:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_source_with_original_formatting
+ | method originalSource actualSource expectedSource |
+
+ originalSource := 'methodName
+
+ `variableName do: [ each | each call ].'.
+
+ expectedSource := 'methodName
+
+ collection do: [ each | each call ].'.
+
+ model formatter: CustomNoneSourceCodeFormatter new.
+ method := model createMethod
+ source: originalSource;
+ replace: '`variableName' with: 'collection';
+ yourself.
+
+ actualSource := method newSource.
+
+ self assertSource: expectedSource sameAs: actualSource.
+
+ "Created: / 22-07-2014 / 23:04:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 15:57:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_nil_changes_not_in_change_collector
+
+ self should: [
+ model createMethod compile.
+ ] raise: Error.
+
+ self assert: model changes changesSize = 0.
+
+ "Created: / 22-07-2014 / 22:16:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 16:00:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_changed_class
+ |class|
+
+ model createNewClassFor: self class. "Actually creates class modification"
+
+ class := RBClass new
+ model: model;
+ name: self class name;
+ yourself.
+
+ model putModelClass: class.
+
+ self assert: class == (model classNamed: class name).
+
+ "Created: / 04-11-2014 / 00:50:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_changed_metaclass
+ |class|
+
+ model createNewClassFor: self class. "Actually creates class modification"
+
+ class := RBMetaclass new
+ model: model;
+ name: self class name;
+ yourself.
+
+ model putModelClass: class.
+
+ self assert: class == (model metaclassNamed: class name).
+
+ "Created: / 04-11-2014 / 01:10:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_new_class
+ |class|
+
+ class := RBClass new
+ model: model;
+ name: #DummyClassForTestCase01;
+ superclassName: #Object;
+ instVarNames: #();
+ classVariableNames: #();
+ poolDictionaryNames: #();
+ yourself.
+
+ model defineClass: class definitionString.
+ model putModelClass: class.
+
+ self assert: class == (model classNamed: #DummyClassForTestCase01).
+
+ "Created: / 04-11-2014 / 00:25:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_new_metaclass
+ |class metaclass|
+
+ class := RBClass new
+ model: model;
+ name: #DummyClassForTestCase01;
+ superclassName: #Object;
+ instVarNames: #();
+ classVariableNames: #();
+ poolDictionaryNames: #();
+ yourself.
+
+ metaclass := RBMetaclass new
+ model: model;
+ name: #DummyClassForTestCase01;
+ yourself.
+
+ model defineClass: class definitionString.
+ model putModelClass: metaclass.
+
+ self deny: class == (model metaclassNamed: #DummyClassForTestCase01).
+ self assert: metaclass == (model metaclassNamed: #DummyClassForTestCase01).
+
+ "Created: / 04-11-2014 / 00:31:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_undefined_error
+ |class|
+
+ class := RBClass new
+ name: #DummyClassForTestCase01.
+
+ self should: [
+ model putModelClass: class.
+ ] raise: Error
+
+ "Modified (format): / 04-11-2014 / 00:22:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_undo_changes_for_multiple_executes
+ "Note: Methods createClassImmediate and createMethodImmediate have execute call inside"
+
+ |mockSuperClassName mockClassName mockSuperClass|
+
+ mockSuperClassName := 'MockSuperClassForTestCase'.
+ mockClassName := 'MockClassForTestCase'.
+ mockSuperClass := model createClassImmediate:mockSuperClassName
+ superClassName:'Object'.
+ model createClassImmediate:mockClassName
+ superClassName:mockSuperClassName.
+
+ "/ Instance method
+
+ model
+ createMethodImmediate:mockSuperClass
+ protocol:'instance-protocol'
+ source:'instanceMethod: aParam
+ self shouldImplement'.
+
+ "/ Class method
+
+ model
+ createMethodImmediate:mockSuperClass class
+ protocol:'class-protocol'
+ source:'classMethod: aParam
+ self shouldImplement'.
+ self assertClassExists:mockSuperClassName.
+ self assertClassExists:mockClassName.
+ model undoChanges.
+ self assertClassNotExists:mockSuperClassName.
+ self assertClassNotExists:mockClassName.
+
+ "Created: / 15-06-2014 / 16:21:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-10-2014 / 14:57:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespaceTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNewClassGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,185 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomNewClassGenerator
+ instanceVariableNames:'newClassName'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomNewClassGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Template class for generators which needs to create a new class.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomNewClassGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+
+ ^ true
+
+ "Created: / 08-11-2014 / 16:50:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+
+ ^ aCustomPerspective isClassPerspective
+
+ "Created: / 08-11-2014 / 16:50:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isAbstract
+ "Return if this class is an abstract class.
+ True is returned here for myself only; false for subclasses.
+ Abstract subclasses must redefine again."
+
+ ^ self == CustomNewClassGenerator.
+! !
+
+!CustomNewClassGenerator methodsFor:'accessing'!
+
+newClassName
+ "Returns a name of the new class to be created."
+
+ ^ newClassName
+
+ "Created: / 08-11-2014 / 16:58:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 09-11-2014 / 01:20:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newClassName: aClassName
+ "see newClassName"
+
+ newClassName := aClassName.
+
+ "Created: / 08-11-2014 / 16:59:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 09-11-2014 / 01:20:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewClassGenerator methodsFor:'accessing - ui'!
+
+defaultClassName
+ "Returns class name which will be displayed in dialog input box"
+
+ self subclassResponsibility
+
+ "Created: / 08-11-2014 / 16:56:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 09-11-2014 / 01:21:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newClassNameLabel
+ "Returns a label of the dialog for the new class to be created"
+
+ self subclassResponsibility
+
+ "Created: / 08-11-2014 / 16:57:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 09-11-2014 / 01:22:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewClassGenerator methodsFor:'executing - private'!
+
+buildForClass: aClass
+ "Subclass can modify the newly created class in here"
+
+ self subclassResponsibility
+
+ "Created: / 08-11-2014 / 17:06:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 09-11-2014 / 01:24:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+buildInContext:aCustomContext
+ | class |
+
+ class := model createClass
+ name: self newClassName asSymbol;
+ yourself.
+
+ self buildForClass: class.
+
+ class compile.
+
+ self executeSubGeneratorOrRefactoringClasses: (Array
+ with: CustomSubclassResponsibilityCodeGenerator
+ )
+ inContext: (CustomSubContext new
+ selectedClasses: (Array with: class);
+ yourself
+ )
+
+ "Created: / 08-11-2014 / 17:10:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-12-2014 / 18:13:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+configureInContext: aCustomContext
+ | initialClassName counter |
+
+ initialClassName := self defaultClassName.
+ counter := 1.
+ [ (Smalltalk at: initialClassName asSymbol) notNil ] whileTrue:[
+ initialClassName := self defaultClassName , counter printString.
+ counter := counter + 1.
+ ].
+ newClassName := dialog
+ requestClassName: self newClassNameLabel
+ initialAnswer: self defaultClassName.
+
+ "Created: / 08-11-2014 / 17:01:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-11-2014 / 21:24:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomNewClassGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNewClassGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,149 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomNewClassGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomNewClassGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomNewClassGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ |generator|
+
+ generator := mock mockOf: CustomNewClassGenerator.
+ generator class compileMockMethod: 'description ^ ''some description''. '.
+ ^ generator
+
+ "Modified: / 09-11-2014 / 00:36:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewClassGeneratorTests methodsFor:'tests'!
+
+test_available_in_context
+
+ self assert: (generatorOrRefactoring class availableInContext: context)
+
+ "Modified: / 09-11-2014 / 00:17:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective
+
+ self assert: (generatorOrRefactoring class availableInPerspective: CustomPerspective classPerspective)
+
+ "Modified (comment): / 09-11-2014 / 00:18:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract
+
+ self assert: CustomNewClassGenerator isAbstract
+
+ "Modified (comment): / 09-11-2014 / 00:30:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_class_generated
+
+ generatorOrRefactoring
+ compileMockMethod: 'buildForClass: aClass ^ self';
+ newClassName: #DummyClass01.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertClassExists: #DummyClass01.
+
+ "Created: / 09-11-2014 / 00:32:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_class_generated_with_dialog
+
+ dialog := mock mockOf: CustomDialog.
+ dialog compileMockMethod: 'requestClassName: aLabel initialAnswer: anAnswer
+
+ self assert: aLabel = ''some label''.
+ self assert: anAnswer = ''DummyClass01''.
+
+ ^ anAnswer. '.
+
+ generatorOrRefactoring
+ compileMockMethod: 'buildForClass: aClass ^ aClass superclassName: CustomCodeGenerator name';
+ compileMockMethod: 'newClassNameLabel ^ ''some label''. ';
+ compileMockMethod: 'defaultClassName ^ ''DummyClass01''. ';
+ dialog: dialog.
+
+ context := CustomBrowserContext new.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertClassExists: #DummyClass01.
+
+ "Created: / 09-11-2014 / 00:48:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-11-2014 / 23:41:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 21:06:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_new_class_generated_with_subclass_responsibility
+ | expectedSource |
+
+ generatorOrRefactoring
+ compileMockMethod: 'buildForClass: aClass ^ aClass superclassName: CustomCodeGenerator name';
+ newClassName: #DummyClass01.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertClassExists: #DummyClass01.
+
+ expectedSource := 'buildInContext:aCustomContext
+ self shouldImplement'.
+
+ self assertMethodSource: expectedSource atSelector: #buildInContext: forClass: (Smalltalk at: #DummyClass01).
+
+ "Created: / 09-11-2014 / 00:41:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 21:06:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNewSystemBrowserTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,342 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomNewSystemBrowserTests
+ instanceVariableNames:'browser mock menu manager generatorClassMock'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-UI-Tests'
+!
+
+!CustomNewSystemBrowserTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomNewSystemBrowserTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ mock := CustomMock new.
+ menu := Menu labels: 'label' values: nil.
+ browser := (mock mockOf: Tools::NewSystemBrowser).
+ mock createMockGetters: browser class forSelectors: {
+ 'information'. 'theSingleSelectedClass'. 'switchToClass'. 'selectProtocol'
+ }.
+ browser
+ compileMockMethod: 'information: aString
+ self objectAttributeAt: #information put: aString';
+ compileMockMethod: 'theSingleSelectedClass: aClass
+ self objectAttributeAt: #theSingleSelectedClass put: aClass';
+ compileMockMethod: 'createBuffer ^ true';
+ compileMockMethod: 'switchToClass: aClass
+ self objectAttributeAt: #switchToClass put: aClass';
+ compileMockMethod: 'selectProtocol: aProtocol
+ self objectAttributeAt: #selectProtocol put: aProtocol';
+ compileMockMethod: 'customMenuBuilder
+ | builder |
+
+ builder := super customMenuBuilder.
+ builder manager: (self objectAttributeAt: #manager).
+ ^ builder'.
+
+ manager := mock mockOf: Object.
+ manager compileMockMethod: 'generatorsAndRefactoringsSelect: aBlock
+ ^ self objectAttributeAt: #codeGenerators';
+ objectAttributeAt: #codeGenerators put: OrderedCollection new.
+
+ browser objectAttributeAt: #manager put: manager.
+
+ generatorClassMock := mock mockClassOf: Object.
+ mock createMockGetters: generatorClassMock forSelectors: {'label'. 'group'}.
+
+ "Modified: / 24-01-2015 / 20:08:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ mock unmockAll.
+
+ super tearDown.
+
+ "Modified: / 26-12-2014 / 19:17:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewSystemBrowserTests methodsFor:'private'!
+
+addGenerator: aLabel group: aGroup
+ "Creates initialized code generator mock and adds it to managers generators"
+ | generator |
+
+ generator := generatorClassMock new
+ objectAttributeAt: #label put: aLabel;
+ objectAttributeAt: #group put: aGroup;
+ yourself.
+
+ (manager objectAttributeAt: #codeGenerators) add: generator.
+
+ ^ generator
+
+ "Created: / 29-12-2014 / 08:51:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+menuItemLabels
+ "Helper which returns labels from menu item as collection as string.
+ We are comparing labels, because menu items are not comparable -
+ MenuItem label: 'Label' not equals MenuItem label: 'Label'"
+
+ ^ (OrderedCollection streamContents: [ :stream |
+ menu itemsDo: [ :item |
+ stream nextPut: item label.
+ item submenuChannel notNil ifTrue: [
+ stream nextPut: (OrderedCollection streamContents: [ :innerStream |
+ item submenuChannel value itemsDo: [ :innerItem |
+ innerStream nextPut: innerItem label
+ ]
+ ]) asArray
+ ]
+ ]
+ ]) asArray
+
+ "Created: / 29-12-2014 / 08:52:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewSystemBrowserTests methodsFor:'tests'!
+
+test_class_menu_extension_custom_generators
+ | expectedMenu actualMenu |
+
+ menu := Menu labels: 'Generate
+label' values: nil.
+
+ expectedMenu := {'Generate'. 'Generate - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #(Group).
+
+ browser classMenuExtensionCustomGenerators: menu.
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Created: / 29-12-2014 / 08:56:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_menu_extension_custom_refactorings
+ | expectedMenu actualMenu |
+
+ menu := Menu labels: 'Generate
+label' values: nil.
+
+ expectedMenu := {'Generate'. 'Refactor - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #(Group).
+
+ browser classMenuExtensionCustomRefactorings: menu.
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Created: / 29-12-2014 / 09:10:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_menu_extension_navigate_to_test_case_custom_extensions
+ | expectedClass actualClass |
+
+ expectedClass := CustomRBMethodTests.
+ browser theSingleSelectedClass: RBMethod.
+ browser classMenuExtensionNavigateToTestCase: menu.
+ menu lastItem itemValue value. "Call menu item action block"
+ actualClass := browser switchToClass.
+
+ self assert: expectedClass = actualClass.
+ self assert: (browser selectProtocol) == #tests
+
+ "Created: / 26-12-2014 / 18:58:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-01-2015 / 19:53:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_menu_extension_navigate_to_test_case_found
+ | expectedClass actualClass |
+
+ expectedClass := CustomContextTests.
+ browser theSingleSelectedClass: CustomContext.
+ browser classMenuExtensionNavigateToTestCase: menu.
+ menu lastItem itemValue value. "Call menu item action block"
+ actualClass := browser switchToClass.
+
+ self assert: expectedClass = actualClass.
+ self assert: (browser selectProtocol) == #tests
+
+ "Created: / 26-12-2014 / 18:53:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_menu_extension_navigate_to_test_case_not_found
+ | expectedInformation actualInformation |
+
+ expectedInformation := 'Test Case named SmallSense::CustomNewSystemBrowserTestsTests not found'.
+ browser theSingleSelectedClass: CustomNewSystemBrowserTests.
+ browser classMenuExtensionNavigateToTestCase: menu.
+ menu lastItem itemValue value. "Call menu item action block"
+ actualInformation := browser information.
+
+ self assert: expectedInformation = actualInformation
+
+ "Created: / 26-12-2014 / 18:32:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 21:00:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_class_menu_extension_navigate_to_test_case_placed_after_generate
+ | expectedPosition actualPosition foundItem |
+
+ expectedPosition := 3.
+
+ menu := Menu labels: 'Label_01
+Generate
+Label_02' values: nil.
+
+ browser classMenuExtensionNavigateToTestCase: menu.
+ actualPosition := 0.
+ foundItem := false.
+ menu itemsDo: [ :item |
+ foundItem ifFalse: [
+ actualPosition := actualPosition + 1.
+ foundItem := (item label = 'Open Test Case Class').
+ ]
+ ].
+
+ self assert: expectedPosition = actualPosition
+
+ "Created: / 26-12-2014 / 19:01:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_view_menu_extension_custom_refactorings
+ | expectedMenu actualMenu |
+
+ menu := Menu labels: 'Refactor
+label' values: nil.
+
+ expectedMenu := {'Refactor'. 'Refactor - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #(Group).
+
+ browser codeViewMenuExtensionCustomRefactorings: menu.
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Created: / 29-12-2014 / 09:16:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_menu_extension_custom_generators
+ | expectedMenu actualMenu |
+
+ menu := Menu labels: 'Generate
+label' values: nil.
+
+ expectedMenu := {'Generate'. 'Generate - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #(Group).
+
+ browser selectorMenuExtensionCustomGenerators: menu.
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Created: / 29-12-2014 / 09:18:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_menu_extension_custom_refactorings
+ | expectedMenu actualMenu |
+
+ menu := Menu labels: 'Refactor
+label' values: nil.
+
+ expectedMenu := {'Refactor'. 'Refactor - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #(Group).
+
+ browser selectorMenuExtensionCustomRefactorings: menu.
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Created: / 29-12-2014 / 09:26:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_variables_menu_extension_custom_generators
+ | expectedMenu actualMenu |
+
+ menu := Menu labels: 'Generate
+label' values: nil.
+
+ expectedMenu := {'Generate'. 'Generate - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #(Group).
+
+ browser variablesMenuExtensionCustomGenerators: menu.
+ actualMenu := self menuItemLabels.
+
+ self assert: expectedMenu = actualMenu
+
+ "Created: / 29-12-2014 / 09:31:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewSystemBrowserTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNoneSourceCodeFormatter.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,78 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomSourceCodeFormatter subclass:#CustomNoneSourceCodeFormatter
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomNoneSourceCodeFormatter class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Should keep original source code formatting even after code replacements - see CustomSourceCodeGenerator.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomNoneSourceCodeFormatter methodsFor:'formatting'!
+
+formatParseTree:aParseTree
+ "Returns parse tree with (possibly) original/unchanged formatting"
+
+ aParseTree source isNil ifTrue:[
+ "no source - try to build from parse tree "
+ ^ aParseTree formattedCode
+ ] ifFalse: [
+ ^ aParseTree source
+ ]
+
+ "Modified: / 29-08-2014 / 22:26:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNoneSourceCodeFormatterTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,102 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomNoneSourceCodeFormatterTests
+ instanceVariableNames:'formatter'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomNoneSourceCodeFormatterTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomNoneSourceCodeFormatterTests methodsFor:'initialization & release'!
+
+setUp
+
+ formatter := CustomNoneSourceCodeFormatter new
+
+ "Modified: / 31-08-2014 / 15:04:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNoneSourceCodeFormatterTests methodsFor:'tests'!
+
+test_format_parse_tree_source_is_nil
+ | expectedSource actualSource parseTree source |
+
+ source := 'selector ^ 777'.
+ parseTree := RBParser parseMethod: source.
+ parseTree source: nil.
+
+ actualSource := (formatter formatParseTree: parseTree) copyWithRegex: '\s' matchesReplacedWith: ''.
+ expectedSource := 'selector^777'.
+
+ self assert: actualSource = expectedSource.
+
+ "Created: / 31-08-2014 / 15:06:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_format_parse_tree_source_not_nil
+ | expectedSource actualSource parseTree source |
+
+ source := 'selector ^ 777'.
+ parseTree := RBParser parseMethod: source.
+ parseTree source: source.
+
+ actualSource := formatter formatParseTree: parseTree.
+ expectedSource := 'selector ^ 777'.
+
+ self assert: actualSource = expectedSource.
+
+ "Created: / 31-08-2014 / 15:07:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNoneSourceCodeFormatterTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomParseTreeRewriter.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,137 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+ParseTreeSourceRewriter subclass:#CustomParseTreeRewriter
+ instanceVariableNames:'oldSource newSource'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomParseTreeRewriter class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Extension for ParseTreeSourceRewriter so that it work even for expressions and not just methods.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomParseTreeRewriter methodsFor:'accessing'!
+
+executeTree: aParseTree
+ "Like ParseTreeSourceRewriter >> executeTree:, but with
+ additional support for expressions"
+ | oldContext treeFromRewrittenSource |
+
+ oldContext := context.
+ context := (RBSmallDictionary ? Dictionary) new.
+ answer := false.
+ oldSource isNil ifTrue: [
+ oldSource := aParseTree source
+ ].
+
+ oldSource isNil ifTrue: [
+ self error: 'We need the oldSource string to be set'.
+ ].
+
+ "/Rewrite the tree as usual and then (try to) rewrite the original source code
+ tree := self visitNode: aParseTree.
+ replacements notNil ifTrue:[
+ newSource := self executeReplacementsInSource: oldSource.
+ ] ifFalse:[
+ ^answer
+ ].
+ "/DO NOT forget rewrites here!!!!!!"
+
+ "/Now, validates that rewritten parse tree is the same as
+ "/the one we get from the rewritten source:
+ aParseTree isMethod ifTrue: [
+ treeFromRewrittenSource := RBParser parseRewriteMethod: newSource onError:[:error :position|nil].
+ ] ifFalse: [
+ treeFromRewrittenSource := RBParser parseExpression: newSource onError:[:error :position|nil].
+ ].
+ treeFromRewrittenSource = tree ifTrue:[
+ (tree respondsTo: #source:) ifTrue: [
+ tree source: newSource.
+ ].
+ ] ifFalse: [
+ "Better set newSource to nil in order to indicate that something went wrong"
+ newSource := nil.
+ ].
+ context := oldContext.
+ ^answer
+
+ "Created: / 09-12-2014 / 21:16:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-02-2015 / 22:07:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newSource
+ "Returns the source code string after the replacements were executed"
+
+ ^ newSource
+
+ "Modified (comment): / 09-12-2014 / 22:19:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+oldSource
+ "Returns custom old source code string - the code before replacements were made"
+
+ ^ oldSource
+
+ "Modified (comment): / 09-12-2014 / 21:19:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+oldSource: aString
+ "see oldSource"
+
+ oldSource := aString
+
+ "Modified (comment): / 09-12-2014 / 21:19:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomParseTreeRewriterTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,219 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomParseTreeRewriterTests
+ instanceVariableNames:'rewriter'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomParseTreeRewriterTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomParseTreeRewriterTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ rewriter := CustomParseTreeRewriter new
+
+ "Modified: / 10-12-2014 / 22:29:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomParseTreeRewriterTests methodsFor:'tests'!
+
+test_execute_tree_expression_01
+ | parseTree originalSource foundMatch expectedSource actualSource |
+
+ originalSource := 'condition ifTrue: [
+ self doStuff
+ ]'.
+
+ expectedSource := 'condition ifTrue: [
+ self doAnotherStuff
+ ]'.
+
+ parseTree := RBParser parseExpression: originalSource.
+
+ rewriter
+ oldSource: originalSource;
+ replace: 'self doStuff' with: 'self doAnotherStuff'.
+
+ foundMatch := rewriter executeTree: parseTree.
+ self assert: foundMatch.
+
+ actualSource := rewriter newSource.
+
+ self assert: expectedSource = actualSource
+
+ "Modified: / 10-12-2014 / 22:40:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_expression_02
+ | parseTree originalSource foundMatch expectedSource actualSource |
+
+ originalSource := 'condition ifTrue: [
+ self doStuff
+ ]'.
+
+ expectedSource := '''a literal string'''.
+
+ parseTree := RBParser parseExpression: originalSource.
+
+ rewriter
+ oldSource: originalSource;
+ replace: '`@something' with: ' ''a literal string'' '.
+
+ foundMatch := rewriter executeTree: parseTree.
+ self assert: foundMatch.
+
+ actualSource := rewriter newSource.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 10-12-2014 / 22:42:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_expression_new_source_empty
+ | parseTree originalSource foundMatch actualSource |
+
+ originalSource := 'condition ifTrue: [
+ self doStuff
+ ]'.
+
+ parseTree := RBParser parseExpression: originalSource.
+
+ rewriter
+ oldSource: originalSource;
+ replace: '`#literal' with: ' ''a literal string'' '.
+
+ foundMatch := rewriter executeTree: parseTree.
+ self deny: foundMatch.
+
+ actualSource := rewriter newSource.
+
+ self assert: actualSource isNil
+
+ "Created: / 10-12-2014 / 22:46:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:20:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_expression_old_source_error
+ | parseTree originalSource |
+
+ originalSource := 'condition ifTrue: [
+ self doStuff
+ ]'.
+
+ parseTree := RBParser parseExpression: originalSource.
+
+ rewriter replace: '`@something' with: ' ''a literal string'' '.
+
+ self should: [
+ rewriter executeTree: parseTree.
+ ] raise: Error
+
+ "Created: / 10-12-2014 / 22:45:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:20:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_method_01
+ | parseTree originalSource foundMatch expectedSource actualSource |
+
+ originalSource := 'method: arg01
+ arg01 isSomething ifTrue: [
+ self doStuff
+ ]'.
+
+ expectedSource := 'method: arg01
+ arg01 isSomething ifTrue: [
+ self doAnotherStuff
+ ]'.
+
+ parseTree := RBParser parseMethod: originalSource.
+
+ rewriter
+ oldSource: originalSource;
+ replace: 'self doStuff' with: 'self doAnotherStuff'.
+
+ foundMatch := rewriter executeTree: parseTree.
+ self assert: foundMatch.
+
+ actualSource := rewriter newSource.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 10-12-2014 / 22:49:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_method_02
+ | parseTree originalSource foundMatch expectedSource actualSource |
+
+ originalSource := 'method: arg01
+ arg01 isSomething ifTrue: [
+ self doStuff
+ ]'.
+
+ expectedSource := 'method: arg01
+ arg01 isAnotherThing ifTrue: [
+ self doAnotherStuff
+ ]'.
+
+ parseTree := RBParser parseMethod: originalSource.
+
+ rewriter
+ replace: '`@receiver isSomething' with: '`@receiver isAnotherThing';
+ replace: 'self doStuff' with: 'self doAnotherStuff'.
+
+ foundMatch := rewriter executeTree: parseTree.
+ self assert: foundMatch.
+
+ actualSource := rewriter newSource.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 10-12-2014 / 22:53:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomPerspective.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,341 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomPerspective
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+CustomPerspective class instanceVariableNames:'theOneAndOnlyInstance'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
+CustomPerspective subclass:#Class
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#ClassCategory
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#CodeView
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#InstanceVariable
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#Method
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#Namespace
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#Package
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#Protocol
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomPerspective
+!
+
+!CustomPerspective class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Represents a perspective marker from which is pop-up menu invoked.
+
+ When we select for example some class from the class menu in the Browser
+ (the STX IDE) then method isClassPerspective should return true and other
+ perspectives should return false.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomPerspective class methodsFor:'instance creation'!
+
+flushSingleton
+ "flushes the cached singleton"
+
+ theOneAndOnlyInstance := nil
+
+ "
+ self flushSingleton
+ "
+!
+
+instance
+ "returns a singleton"
+
+ theOneAndOnlyInstance isNil ifTrue:[
+ theOneAndOnlyInstance := self basicNew initialize.
+ ].
+ ^ theOneAndOnlyInstance.
+
+ "Created: / 26-01-2014 / 10:57:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+new
+ "returns a singleton"
+
+ ^ self instance.
+
+ "Modified: / 26-01-2014 / 10:57:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomPerspective class methodsFor:'accessing'!
+
+classCategoryPerspective
+ ^ CustomPerspective::ClassCategory instance
+
+ "Created: / 14-10-2014 / 10:11:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classPerspective
+ ^ CustomPerspective::Class instance
+
+ "Created: / 26-01-2014 / 10:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+codeViewPerspective
+ ^ CustomPerspective::CodeView instance
+
+ "Created: / 14-10-2014 / 10:17:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+instanceVariablePerspective
+ ^ CustomPerspective::InstanceVariable instance
+
+ "Created: / 26-01-2014 / 11:00:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+methodPerspective
+ ^ CustomPerspective::Method instance
+
+ "Created: / 24-08-2014 / 11:14:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+namespacePerspective
+ ^ CustomPerspective::Namespace instance
+
+ "Created: / 14-10-2014 / 10:18:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+packagePerspective
+ ^ CustomPerspective::Package instance
+
+ "Created: / 14-10-2014 / 10:18:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+protocolPerspective
+ ^ CustomPerspective::Protocol instance
+
+ "Created: / 14-10-2014 / 10:18:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective class methodsFor:'testing'!
+
+isAbstract
+ ^ self == CustomPerspective
+
+ "Created: / 26-01-2014 / 10:58:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomPerspective methodsFor:'testing'!
+
+isClassCategoryPerspective
+ ^ false
+
+ "Created: / 14-10-2014 / 09:33:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isClassPerspective
+ ^ false
+
+ "Created: / 26-01-2014 / 13:10:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isCodeViewPerspective
+ ^ false
+
+ "Created: / 14-10-2014 / 09:30:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isInstanceVariablePerspective
+ ^ false
+
+ "Created: / 26-01-2014 / 13:10:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isMethodPerspective
+ ^ false
+
+ "Created: / 24-08-2014 / 11:12:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isNamespacePerspective
+ ^ false
+
+ "Created: / 14-10-2014 / 09:32:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isPackagePerspective
+ ^ false
+
+ "Created: / 14-10-2014 / 09:32:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isProtocolPerspective
+ ^ false
+
+ "Created: / 14-10-2014 / 09:29:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Class methodsFor:'testing'!
+
+isClassPerspective
+ ^ true
+
+ "Created: / 26-01-2014 / 13:10:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomPerspective::ClassCategory methodsFor:'testing'!
+
+isClassCategoryPerspective
+ ^ true
+
+ "Created: / 14-10-2014 / 10:09:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::CodeView methodsFor:'testing'!
+
+isCodeViewPerspective
+ ^ true
+
+ "Created: / 14-10-2014 / 10:10:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::InstanceVariable methodsFor:'testing'!
+
+isInstanceVariablePerspective
+ ^ true
+
+ "Created: / 26-01-2014 / 13:10:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Method methodsFor:'testing'!
+
+isMethodPerspective
+ ^ true
+
+ "Created: / 24-08-2014 / 11:13:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Namespace methodsFor:'testing'!
+
+isNamespacePerspective
+ ^ true
+
+ "Created: / 14-10-2014 / 10:10:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Package methodsFor:'testing'!
+
+isPackagePerspective
+ ^ true
+
+ "Created: / 14-10-2014 / 10:10:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Protocol methodsFor:'testing'!
+
+isProtocolPerspective
+ ^ true
+
+ "Created: / 14-10-2014 / 10:10:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomPerspectiveTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,230 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomPerspectiveTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomPerspectiveTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomPerspectiveTests methodsFor:'tests'!
+
+test_all_perspectives_false_as_default
+ | perspective |
+
+ perspective := CustomPerspective new.
+
+ self deny: perspective isClassCategoryPerspective.
+ self deny: perspective isClassPerspective.
+ self deny: perspective isCodeViewPerspective.
+ self deny: perspective isInstanceVariablePerspective.
+ self deny: perspective isMethodPerspective.
+ self deny: perspective isNamespacePerspective.
+ self deny: perspective isPackagePerspective.
+ self deny: perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:47:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_category_perspective
+ |perspective|
+
+ perspective := CustomPerspective classCategoryPerspective.
+ self assert:perspective isClassCategoryPerspective.
+ self deny:perspective isClassPerspective.
+ self deny:perspective isCodeViewPerspective.
+ self deny:perspective isInstanceVariablePerspective.
+ self deny:perspective isMethodPerspective.
+ self deny:perspective isNamespacePerspective.
+ self deny:perspective isPackagePerspective.
+ self deny:perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:49:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_perspective
+ |perspective|
+
+ perspective := CustomPerspective classPerspective.
+ self deny:perspective isClassCategoryPerspective.
+ self assert:perspective isClassPerspective.
+ self deny:perspective isCodeViewPerspective.
+ self deny:perspective isInstanceVariablePerspective.
+ self deny:perspective isMethodPerspective.
+ self deny:perspective isNamespacePerspective.
+ self deny:perspective isPackagePerspective.
+ self deny:perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:50:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_view_perspective
+ | perspective |
+
+ perspective := CustomPerspective codeViewPerspective.
+
+ self deny: perspective isClassCategoryPerspective.
+ self deny: perspective isClassPerspective.
+ self assert: perspective isCodeViewPerspective.
+ self deny: perspective isInstanceVariablePerspective.
+ self deny: perspective isMethodPerspective.
+ self deny: perspective isNamespacePerspective.
+ self deny: perspective isPackagePerspective.
+ self deny: perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:51:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_instance_variable_perspective
+ | perspective |
+
+ perspective := CustomPerspective instanceVariablePerspective.
+
+ self deny: perspective isClassCategoryPerspective.
+ self deny: perspective isClassPerspective.
+ self deny: perspective isCodeViewPerspective.
+ self assert: perspective isInstanceVariablePerspective.
+ self deny: perspective isMethodPerspective.
+ self deny: perspective isNamespacePerspective.
+ self deny: perspective isPackagePerspective.
+ self deny: perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:54:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract
+
+ self assert: CustomPerspective isAbstract.
+
+ "Created: / 14-10-2014 / 11:57:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_variable_perspective
+ | perspective |
+
+ perspective := CustomPerspective methodPerspective.
+
+ self deny: perspective isClassCategoryPerspective.
+ self deny: perspective isClassPerspective.
+ self deny: perspective isCodeViewPerspective.
+ self deny: perspective isInstanceVariablePerspective.
+ self assert: perspective isMethodPerspective.
+ self deny: perspective isNamespacePerspective.
+ self deny: perspective isPackagePerspective.
+ self deny: perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:54:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_namespace_perspective
+ | perspective |
+
+ perspective := CustomPerspective namespacePerspective.
+
+ self deny: perspective isClassCategoryPerspective.
+ self deny: perspective isClassPerspective.
+ self deny: perspective isCodeViewPerspective.
+ self deny: perspective isInstanceVariablePerspective.
+ self deny: perspective isMethodPerspective.
+ self assert: perspective isNamespacePerspective.
+ self deny: perspective isPackagePerspective.
+ self deny: perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:55:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_perspective
+ | perspective |
+
+ perspective := CustomPerspective packagePerspective.
+
+ self deny: perspective isClassCategoryPerspective.
+ self deny: perspective isClassPerspective.
+ self deny: perspective isCodeViewPerspective.
+ self deny: perspective isInstanceVariablePerspective.
+ self deny: perspective isMethodPerspective.
+ self deny: perspective isNamespacePerspective.
+ self assert: perspective isPackagePerspective.
+ self deny: perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:56:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_protocol_perspective
+ | perspective |
+
+ perspective := CustomPerspective protocolPerspective.
+
+ self deny: perspective isClassCategoryPerspective.
+ self deny: perspective isClassPerspective.
+ self deny: perspective isCodeViewPerspective.
+ self deny: perspective isInstanceVariablePerspective.
+ self deny: perspective isMethodPerspective.
+ self deny: perspective isNamespacePerspective.
+ self deny: perspective isPackagePerspective.
+ self assert: perspective isProtocolPerspective.
+
+ "Created: / 14-10-2014 / 11:56:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_singleton
+ | perspective_01 perspective_02 |
+
+ perspective_01 := CustomPerspective new.
+ perspective_02 := CustomPerspective new.
+
+ self assert: perspective_01 == perspective_02.
+
+ CustomPerspective flushSingleton.
+ perspective_02 := CustomPerspective new.
+
+ self deny: perspective_01 == perspective_02.
+
+ "Created: / 14-10-2014 / 12:01:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomPrintCodeSelectionRefactoring.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,82 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeSelectionRefactoring subclass:#CustomPrintCodeSelectionRefactoring
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomPrintCodeSelectionRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomPrintCodeSelectionRefactoring class methodsFor:'accessing-presentation'!
+
+description
+
+ ^ 'Wraps selected source code with Transcript showCR: to be printed out'
+
+ "Modified: / 15-11-2014 / 16:21:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+
+ ^ 'Wrap with Transcript showCR: '
+
+ "Modified: / 15-11-2014 / 16:21:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPrintCodeSelectionRefactoring methodsFor:'executing - private'!
+
+buildInContext:aCustomContext
+
+ refactoryBuilder
+ replace:'`@expression'
+ with:'(Transcript showCR: (`@expression) asString)'
+ inContext:aCustomContext
+
+ "Modified: / 15-11-2014 / 16:36:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBAbstractClassTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,1187 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBAbstractClassTests
+ instanceVariableNames:'rbClass mock model'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRBAbstractClassTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Test extensions in RBAbstractClass.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomRBAbstractClassTests methodsFor:'initialization & release'!
+
+setUp
+
+ mock := CustomMock new.
+ model := CustomNamespace new.
+ model changeManager: CustomLocalChangeManager new.
+ rbClass := mock mockOf: RBAbstractClass.
+ rbClass model: model.
+
+ "Created: / 30-09-2014 / 19:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 02-02-2015 / 22:43:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ model changeManager undoChanges.
+ mock unmockAll
+
+ "Created: / 30-09-2014 / 19:44:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 02-02-2015 / 22:43:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBAbstractClassTests methodsFor:'tests'!
+
+test_all_class_var_names_empty
+ | expectedClassVars actualClassVars |
+
+ rbClass compileMockMethod: 'allClassVariableNames ^ nil'.
+
+ expectedClassVars := #().
+ actualClassVars := rbClass allClassVarNames.
+
+ self assert: expectedClassVars = actualClassVars
+
+ "Created: / 30-09-2014 / 19:40:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_class_var_names_not_empty
+ | expectedClassVars actualClassVars |
+
+ rbClass compileMockMethod: 'allClassVariableNames ^ #(''C1'' ''C2'')'.
+
+ expectedClassVars := #('C1' 'C2').
+ actualClassVars := rbClass allClassVarNames.
+
+ self assert: expectedClassVars = actualClassVars
+
+ "Created: / 30-09-2014 / 19:47:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_superclasses_do_for_object
+ | expectedClassNames actualClassNames |
+
+ rbClass := model classNamed: #Object.
+
+ expectedClassNames := OrderedCollection new.
+ actualClassNames := OrderedCollection new.
+ rbClass allSuperclassesDo: [ :class |
+ actualClassNames add: class name
+ ].
+
+ self assert: expectedClassNames = actualClassNames
+
+ "Created: / 04-10-2014 / 13:21:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-10-2014 / 23:29:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_superclasses_do_for_object_superclass
+ | expectedClassNames actualClassNames |
+
+ rbClass
+ name: #SomeClass;
+ superclass: (model classNamed: #Object).
+
+ expectedClassNames := OrderedCollection new add: #Object; yourself.
+ actualClassNames := OrderedCollection new.
+ rbClass allSuperclassesDo: [ :class |
+ actualClassNames add: class name
+ ].
+
+ self assert: expectedClassNames = actualClassNames
+
+ "Created: / 04-10-2014 / 23:28:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_superclasses_do_with_real_class
+ | expectedClassNames actualClassNames realClass |
+
+ "This actually creates realclass"
+ realClass := mock mockClassOf: Object.
+
+ rbClass
+ name: #SomeClass;
+ superclass: (model classNamed: realClass name asSymbol).
+
+ expectedClassNames := OrderedCollection new
+ add: realClass name asSymbol;
+ add: #Object;
+ yourself.
+
+ actualClassNames := OrderedCollection new.
+ rbClass allSuperclassesDo: [ :class |
+ actualClassNames add: class name
+ ].
+
+ self assert: expectedClassNames = actualClassNames
+
+ "Created: / 04-10-2014 / 23:44:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_superclasses_do_with_two_superclasses
+ | expectedClassNames actualClassNames superclass |
+
+ superclass := RBClass new
+ name: #SomeClass_01;
+ superclass: (model classNamed: #Object);
+ yourself.
+
+ rbClass
+ name: #SomeClass_02;
+ superclass: superclass.
+
+ expectedClassNames := OrderedCollection new
+ add: #SomeClass_01;
+ add: #Object;
+ yourself.
+
+ actualClassNames := OrderedCollection new.
+ rbClass allSuperclassesDo: [ :class |
+ actualClassNames add: class name
+ ].
+
+ self assert: expectedClassNames = actualClassNames
+
+ "Created: / 04-10-2014 / 23:38:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_method_with_all_filled
+ | method compiledMethod change |
+
+ rbClass compileMockMethod: 'isMeta ^ false'.
+
+ method := RBMethod new
+ source: 'selector_01 ^ `#literal';
+ protocol: 'a test protocol';
+ package: 'some_package';
+ model: model;
+ class: self class;
+ method: (self class compiledMethodAt: #test_compile_method_with_all_filled);
+ sourceCodeGenerator: (CustomSourceCodeGenerator new
+ formatter: CustomNoneSourceCodeFormatter new;
+ yourself);
+ replace: '`#literal' with: '1';
+ selector: #selector_01;
+ yourself.
+
+ change := rbClass compileMethod: method.
+
+ self assert: (rbClass includesSelector: #selector_01).
+
+ self assert: 'a test protocol' = (change protocol).
+ self assert: 'some_package' = (change package).
+ self assert: 'selector_01 ^ 1' = (change source).
+
+ compiledMethod := rbClass compiledMethodAt: #selector_01.
+
+ self assert: 'a test protocol' = (compiledMethod protocol).
+ self assert: 'some_package' = (compiledMethod package).
+ self assert: 'selector_01 ^ 1' = (compiledMethod source).
+
+ "Created: / 10-10-2014 / 12:17:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_method_with_real_method
+ | method compiledMethod realMethod change class |
+
+ rbClass compileMockMethod: 'isMeta ^ false'.
+
+ class := mock mockClassOf: Object.
+ class new compileMockMethod: 'selector_01 ^ 1'.
+ realMethod := class compiledMethodAt: #selector_01.
+
+ method := RBMethod
+ for: rbClass
+ fromMethod: realMethod
+ andSelector: #selector_01.
+
+ change := rbClass compileMethod: method.
+
+ self assert: (rbClass includesSelector: #selector_01).
+
+ self assert: (realMethod category) = (change protocol).
+ self assert: (realMethod package) = (change package).
+ self assert: 'selector_01 ^ 1' = (change source).
+
+ compiledMethod := rbClass compiledMethodAt: #selector_01.
+
+ self assert: (realMethod category) = (compiledMethod protocol).
+ self assert: (realMethod package) = (compiledMethod package).
+ self assert: 'selector_01 ^ 1' = (compiledMethod source).
+
+ "Created: / 10-10-2014 / 13:20:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_method_with_source
+ | method change expectedSource actualSource |
+
+ rbClass compileMockMethod: 'isMeta ^ false'.
+
+ method := RBMethod new
+ source: 'selector_01 ^ 1';
+ yourself.
+
+ expectedSource := 'selector_01 ^ 1'.
+ change := rbClass compileMethod: method.
+
+ self assert: expectedSource = (change source).
+
+ actualSource := (rbClass compiledMethodAt: #selector_01) source.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 10-10-2014 / 11:56:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_default
+
+ self assert: Compiler == (rbClass compilerClass)
+
+ "Created: / 16-11-2014 / 16:44:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_java
+ | expectedCompiler actualCompiler |
+
+ rbClass realClass: JavaLanguage new.
+
+ expectedCompiler := JavaCompiler ? JavaCompilerForSmalltalkExtensionsOnly.
+ actualCompiler := rbClass compilerClass.
+
+ self assert: expectedCompiler = actualCompiler
+
+ "Created: / 16-11-2014 / 16:45:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_javascript
+ | expectedCompiler actualCompiler |
+
+ rbClass realClass: STXJavaScriptLanguage new.
+
+ expectedCompiler := JavaScriptCompiler.
+ actualCompiler := rbClass compilerClass.
+
+ self assert: expectedCompiler = actualCompiler
+
+ "Created: / 16-11-2014 / 16:54:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_smalltalk
+
+ rbClass realClass: self class.
+
+ self assert: Compiler == (rbClass compilerClass)
+
+ "Created: / 16-11-2014 / 16:44:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_with_empty_real_class
+ | expectedCompiler actualCompiler |
+
+ expectedCompiler := Object compilerClass.
+ actualCompiler := rbClass compilerClass.
+
+ self assert: expectedCompiler = actualCompiler
+
+ "Created: / 15-11-2014 / 17:02:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:20:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_with_filled_real_class
+ | expectedCompiler actualCompiler |
+
+ expectedCompiler := JavaClass compilerClass.
+
+ rbClass realClass: JavaClass.
+ actualCompiler := rbClass compilerClass.
+
+ self assert: expectedCompiler = actualCompiler
+
+ "Created: / 15-11-2014 / 17:02:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:22:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inherits_from_model_class
+ | class |
+
+ class := model classNamed: #Object.
+ rbClass
+ name: #SomeTestClass01;
+ superclassName: #Object.
+
+ self assert: (rbClass inheritsFrom: class).
+
+ "Created: / 11-10-2014 / 01:09:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 13-10-2014 / 20:47:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inst_and_class_methods_do_with_model_class
+ |expectedMethods actualMethods|
+
+ rbClass
+ compileMockMethod:'isMeta ^ false';
+ compileMockMethod:'theNonMetaclass ^ self';
+ compileMockMethod:'theMetaclass ^ RBMetaclass new'.
+
+ rbClass
+ name:#SomeClass;
+ superclassName:#Object;
+ compile:'selector_01 ^ 1'.
+
+ expectedMethods := OrderedCollection new
+ add:(rbClass compiledMethodAt:#'selector_01');
+ yourself.
+
+ actualMethods := OrderedCollection new.
+
+ rbClass instAndClassMethodsDo:[ :method |
+ actualMethods add:method
+ ].
+
+ self assert:expectedMethods = actualMethods
+
+ "Created: / 01-11-2014 / 21:48:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 02-11-2014 / 10:44:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inst_and_class_methods_do_with_model_subclass_class
+ |expectedMethods actualMethods|
+
+ rbClass := RBClass new
+ model:model;
+ name:#SomeClass;
+ superclassName:#Object;
+ classVariableNames:#();
+ poolDictionaryNames:#();
+ compile;
+ compile:'selector_01 ^ 1';
+ yourself.
+
+ expectedMethods := OrderedCollection new
+ add:(rbClass compiledMethodAt:#'selector_01');
+ yourself.
+
+ actualMethods := OrderedCollection new.
+
+ rbClass instAndClassMethodsDo:[ :method |
+ actualMethods add:method
+ ].
+
+ self assert:expectedMethods = actualMethods
+
+ "Created: / 02-11-2014 / 10:30:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inst_and_class_methods_do_with_model_subclass_class_and_metaclass
+ |expectedMethods actualMethods|
+
+ rbClass := RBClass new
+ model:model;
+ name:#SomeClass;
+ superclassName:#Object;
+ classVariableNames:#();
+ poolDictionaryNames:#();
+ compile;
+ compile:'selector_01 ^ 1';
+ yourself.
+
+ rbClass theMetaclass compile:'selector_02 ^ 2'.
+
+ expectedMethods := OrderedCollection new
+ add:(rbClass compiledMethodAt:#'selector_01');
+ add:(rbClass theMetaclass compiledMethodAt:#'selector_02');
+ yourself.
+
+ actualMethods := OrderedCollection new.
+
+ rbClass instAndClassMethodsDo:[ :method |
+ actualMethods add:method
+ ].
+
+ self assert:expectedMethods = actualMethods
+
+ "Created: / 02-11-2014 / 10:41:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inst_and_class_methods_do_with_real_class
+ |actualSelectors realClass|
+
+ realClass := model classNamed: self class name.
+
+ actualSelectors := OrderedCollection new.
+
+ realClass instAndClassMethodsDo:[ :method |
+ actualSelectors add:method selector
+ ].
+
+ "class method"
+ self assert: (actualSelectors includes:#test_inst_and_class_methods_do_with_real_class).
+
+ "metaclass method"
+ self assert: (actualSelectors includes:#documentation).
+ self deny: (self class includesSelector:#documentation). "to be sure that its just in metaclass"
+
+ "Created: / 02-11-2014 / 11:05:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_custom_value_false
+
+ rbClass := model createClass
+ name: #DummyClass;
+ compile;
+ isAbstract: false;
+ yourself.
+
+ self deny: rbClass isAbstract
+
+ "Created: / 14-12-2014 / 17:03:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-12-2014 / 18:03:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_custom_value_true
+
+ rbClass := model createClass
+ name: #DummyClass;
+ compile;
+ isAbstract: true;
+ yourself.
+
+ self assert: rbClass isAbstract
+
+ "Created: / 14-12-2014 / 17:02:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-12-2014 / 18:03:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_default_value_for_new_class
+
+ self assert: rbClass isAbstract
+
+ "Created: / 14-12-2014 / 17:01:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_guess_from_method
+
+ rbClass
+ compileMockMethod: 'isMeta ^ false';
+ compile: 'selector_01 ^ self subclassResponsibility'.
+
+ self assert: rbClass isAbstract.
+ self assert: (rbClass whichSelectorsReferToSymbol: #subclassResponsibility) notEmptyOrNil
+
+ "Created: / 14-12-2014 / 17:04:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_guess_from_my_name_referenced
+
+ "We need some reference outside the class itself"
+ model createClass
+ name: #DummyClass01;
+ compile;
+ compile: 'selector_01 ^ DummyClass02 new'.
+
+ rbClass
+ compileMockMethod: 'isMeta ^ false';
+ name: #DummyClass02.
+
+ self deny: rbClass isAbstract.
+
+ "Created: / 14-12-2014 / 17:10:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_set_for_both_class_and_metaclass
+
+ rbClass := model createClass
+ name: 'DummyClass';
+ compile;
+ isAbstract: false;
+ yourself.
+
+ self deny: (rbClass theMetaclass isAbstract).
+ self deny: (rbClass theNonMetaclass isAbstract).
+
+ rbClass isAbstract: true.
+
+ self assert: (rbClass theMetaclass isAbstract).
+ self assert: (rbClass theNonMetaclass isAbstract).
+
+ "Created: / 14-12-2014 / 17:44:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_loaded
+
+ self assert: rbClass isLoaded
+
+ "Created: / 15-11-2014 / 17:12:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_model_class
+ | class |
+
+ class := model classNamed: #Object.
+
+ rbClass
+ name: #SomeTestClass01;
+ superclassName: #Object.
+
+ self assert: (rbClass isSubclassOf: class).
+
+ "Created: / 11-10-2014 / 00:57:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_model_class_not_found
+ | class |
+
+ class := RBClass new
+ name: #SomeTestClass02;
+ yourself.
+
+ rbClass
+ name: #SomeTestClass01;
+ superclassName: #Object.
+
+ self deny: (rbClass isSubclassOf: class).
+
+ "Created: / 11-10-2014 / 12:22:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_model_class_two_level_subclass
+ | class |
+
+ class := model classNamed: #Object.
+
+ rbClass
+ name: #SomeTestClass01;
+ superclass: (RBClass new
+ name: #SomeTestClass02;
+ model: model;
+ superclassName: #Object;
+ yourself).
+
+ self assert: (rbClass isSubclassOf: class).
+
+ "Created: / 11-10-2014 / 01:06:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_real_class
+ | class |
+
+ class := Object.
+
+ rbClass
+ name: #SomeTestClass01;
+ superclassName: #Object.
+
+ self assert: (rbClass isSubclassOf: class).
+
+ "Created: / 11-10-2014 / 01:00:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_real_class_two_level_subclass
+ | class |
+
+ class := Object.
+
+ rbClass
+ name: #SomeTestClass01;
+ superclass: (RBClass new
+ name: #SomeTestClass02;
+ model: model;
+ superclassName: #Object;
+ yourself).
+
+ self assert: (rbClass isSubclassOf: class).
+
+ "Created: / 11-10-2014 / 01:05:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_dictionary_add_and_remove_methods
+ | expectedMethodDictionary actualMethodDictionary expectedMethodDictionaryKeys actualMethodDictionaryKeys |
+
+ rbClass compileMockMethod: 'isMeta ^ false'.
+
+ expectedMethodDictionary := MethodDictionary
+ withKeys: (Array with: #selector_01 with: #selector_03)
+ andValues: (Array with: Method new with: Method new).
+
+ rbClass
+ compile: 'selector_01 ^ 1';
+ compile: 'selector_02 ^ 2';
+ compile: 'selector_03 ^ 3';
+ removeMethod: #selector_02.
+
+ actualMethodDictionary := rbClass methodDictionary.
+ expectedMethodDictionaryKeys := expectedMethodDictionary keys asSortedCollection.
+ actualMethodDictionaryKeys := actualMethodDictionary keys asSortedCollection.
+
+ self assert: expectedMethodDictionaryKeys = actualMethodDictionaryKeys
+
+ "Created: / 30-09-2014 / 20:02:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-09-2014 / 21:54:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_dictionary_add_and_remove_methods_source
+ | expectedMethodDictionarySources actualMethodDictionarySources |
+
+ rbClass
+ compileMockMethod: 'isMeta ^ false';
+ compile: 'selector_01 ^ 1';
+ compile: 'selector_02 ^ 2';
+ compile: 'selector_03 ^ 3';
+ removeMethod: #selector_02.
+
+ expectedMethodDictionarySources := OrderedCollection new
+ add: 'selector_01 ^ 1';
+ add: 'selector_03 ^ 3';
+ asSortedCollection.
+
+ actualMethodDictionarySources := OrderedCollection new.
+
+ actualMethodDictionarySources := rbClass methodDictionary collect: [ :method |
+ method source
+ ].
+
+ actualMethodDictionarySources := actualMethodDictionarySources asSortedCollection.
+
+ self assert: expectedMethodDictionarySources = actualMethodDictionarySources
+
+ "Created: / 02-11-2014 / 11:22:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:29:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_dictionary_add_and_remove_methods_with_real_class
+ | expectedMethodDictionary actualMethodDictionary expectedMethodDictionaryKeys actualMethodDictionaryKeys realSelector |
+
+ realSelector := #test_method_dictionary_add_and_remove_methods_with_real_class.
+
+ rbClass compileMockMethod: 'isMeta ^ false'.
+ rbClass realClass: self class.
+
+ expectedMethodDictionary := self class methodDictionary
+ at: #selector_01 putOrAppend: Method new.
+ expectedMethodDictionary := expectedMethodDictionary
+ at: #selector_03 putOrAppend: Method new.
+ expectedMethodDictionary := expectedMethodDictionary removeKeyAndCompress: realSelector.
+
+ rbClass
+ compile: 'selector_01 ^ 1';
+ compile: 'selector_02 ^ 2';
+ compile: 'selector_03 ^ 3';
+ removeMethod: #selector_02;
+ removeMethod: #test_method_dictionary_add_and_remove_methods_with_real_class.
+
+ actualMethodDictionary := rbClass methodDictionary.
+ expectedMethodDictionaryKeys := expectedMethodDictionary keys asSortedCollection.
+ actualMethodDictionaryKeys := actualMethodDictionary keys asSortedCollection.
+
+ self assert: expectedMethodDictionaryKeys = actualMethodDictionaryKeys
+
+ "Created: / 30-09-2014 / 21:55:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 02-10-2014 / 21:11:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_dictionary_empty
+ | expectedMethodDictionary actualMethodDictionary |
+
+ expectedMethodDictionary := MethodDictionary new.
+ actualMethodDictionary := rbClass methodDictionary.
+
+ self assert: (expectedMethodDictionary keys) = (actualMethodDictionary keys)
+
+ "Created: / 30-09-2014 / 19:56:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_do_with_model_class
+ |expectedMethods actualMethods|
+
+ rbClass
+ compileMockMethod:'isMeta ^ false';
+ name:#SomeClass;
+ superclassName:#Object;
+ compile:'selector_01 ^ 1'.
+
+ expectedMethods := OrderedCollection new
+ add:(rbClass compiledMethodAt:#'selector_01');
+ yourself.
+
+ actualMethods := OrderedCollection new.
+
+ rbClass methodsDo:[ :method |
+ actualMethods add:method
+ ].
+
+ self assert:expectedMethods = actualMethods
+
+ "Created: / 02-11-2014 / 11:26:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_do_with_model_class_two_methods
+ |expectedMethods actualMethods|
+
+ rbClass
+ compileMockMethod:'isMeta ^ false';
+ name:#SomeClass;
+ superclassName:#Object;
+ compile:'selector_01 ^ 1';
+ compile:'selector_02 ^ 2'.
+
+ expectedMethods := OrderedCollection new
+ add:(rbClass compiledMethodAt:#selector_01);
+ add:(rbClass compiledMethodAt:#selector_02);
+ yourself.
+
+ actualMethods := OrderedCollection new.
+
+ rbClass methodsDo:[ :method |
+ actualMethods add:method
+ ].
+
+ self assert:expectedMethods = actualMethods
+
+ "Created: / 02-11-2014 / 11:28:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-11-2014 / 11:13:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_do_with_real_class
+ |actualMethodSelectors|
+
+ rbClass := model classNamed: self class name.
+
+ actualMethodSelectors := OrderedCollection new.
+
+ rbClass methodsDo:[ :method |
+ actualMethodSelectors add:method selector
+ ].
+
+ self assert:(actualMethodSelectors includes:#test_methods_do_with_real_class).
+ self deny:(actualMethodSelectors includes:#documentation).
+ self assert:(self class class includesSelector:#documentation).
+ self deny:(self class includesSelector:#documentation).
+
+ "Created: / 02-11-2014 / 11:37:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_do_with_real_metaclass
+ |actualMethodSelectors|
+
+ rbClass := model metaclassNamed: self class name.
+
+ actualMethodSelectors := OrderedCollection new.
+
+ rbClass methodsDo:[ :method |
+ actualMethodSelectors add:method selector
+ ].
+
+ self assert:(actualMethodSelectors includes:#documentation).
+ self deny:(actualMethodSelectors includes:#test_methods_do_with_real_metaclass).
+ self deny:(self class class includesSelector:#test_methods_do_with_real_metaclass).
+ self assert:(self class includesSelector:#test_methods_do_with_real_metaclass).
+
+ "Created: / 02-11-2014 / 11:43:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_name_set_as_string
+ | expectedName actualName |
+
+ expectedName := #SomeClass01.
+ rbClass name: 'SomeClass01'.
+ actualName := rbClass name.
+
+ self assert: expectedName == actualName
+
+ "Created: / 19-11-2014 / 21:12:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_name_set_as_symbol
+ | expectedName actualName |
+
+ expectedName := #SomeClass01.
+ rbClass name: #SomeClass01.
+ actualName := rbClass name.
+
+ self assert: expectedName == actualName
+
+ "Created: / 19-11-2014 / 21:15:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_name_without_prefix_non_prefixed_class
+ | expectedClassName actualClassName |
+
+ rbClass name: #SomeClass.
+ expectedClassName := #SomeClass.
+ actualClassName := rbClass nameWithoutPrefix.
+
+ self assert: expectedClassName = actualClassName
+
+ "Created: / 05-10-2014 / 00:13:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_name_without_prefix_prefixed_class
+ | expectedClassName actualClassName |
+
+ rbClass name: #'Prefix::SomeClass'.
+ expectedClassName := #SomeClass.
+ actualClassName := rbClass nameWithoutPrefix.
+
+ self assert: expectedClassName = actualClassName
+
+ "Created: / 05-10-2014 / 00:13:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:17:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class
+ | expectedClass actualClass |
+
+ expectedClass := RBClass new.
+
+ "Class must be defined in the model to have class and metaclass couple"
+ model defineClass: 'Object subclass:#DummyClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:'''''.
+
+ rbClass := model classNamed: #DummyClass01.
+ rbClass owningClass: expectedClass.
+
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 13:27:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_from_definition_string
+ | expectedClass actualClass |
+
+ "Class must be defined in the model to have class and metaclass couple"
+ model defineClass: 'Object subclass:#DummyClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:'''''.
+
+ model defineClass: 'Object subclass:#DummyPrivateClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ privateIn:DummyClass01'.
+
+ expectedClass := model classNamed: #DummyClass01.
+
+ rbClass := model classNamed: #'DummyClass01::DummyPrivateClass01'.
+
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 14:21:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:16:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_or_yourself_none_owner
+ | expectedClass actualClass |
+
+ rbClass := model classNamed: self class name.
+ expectedClass := rbClass.
+
+ actualClass := rbClass owningClassOrYourself.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 14:59:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_or_yourself_owner
+ | expectedClass actualClass |
+
+ "Class must be defined in the model to have class and metaclass couple"
+ model defineClass: 'Object subclass:#DummyClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:'''''.
+
+ expectedClass := model classNamed: #DummyClass01.
+ rbClass := model classNamed: self class name.
+ rbClass owningClass: expectedClass.
+
+ actualClass := rbClass owningClassOrYourself.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 14:56:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_custom
+ | expectedPackage actualPackage |
+
+ expectedPackage := 'some_package'.
+ rbClass package: 'some_package'.
+
+ actualPackage := rbClass package.
+
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 09-10-2014 / 23:40:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_empty
+ | expectedPackage actualPackage |
+
+ expectedPackage := nil.
+ actualPackage := rbClass package.
+
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 09-10-2014 / 23:39:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_from_real_class
+ | expectedPackage actualPackage |
+
+ expectedPackage := self class package.
+
+ self assert: expectedPackage size > 3.
+
+ rbClass realClass: self class.
+
+ actualPackage := rbClass package.
+
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 09-10-2014 / 23:37:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_classes_at_found
+ | expectedClass actualClass |
+
+ model defineClass: 'Object subclass:#DummyPrivateClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ privateIn:Object'.
+
+ expectedClass := model classNamed: #'Object::DummyPrivateClass01'.
+ self assert: (expectedClass name) = #'Object::DummyPrivateClass01'.
+
+ rbClass name: #Object.
+ actualClass := rbClass privateClassesAt: #DummyPrivateClass01.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 16-11-2014 / 11:50:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:17:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_classes_at_not_found
+ | expectedClass actualClass |
+
+ expectedClass := nil.
+ actualClass := rbClass privateClassesAt: #None.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 16-11-2014 / 11:41:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_classes_at_not_found_with_name
+ | expectedClass actualClass |
+
+ expectedClass := nil.
+ rbClass name: #DummyClass01.
+ actualClass := rbClass privateClassesAt: #None.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 16-11-2014 / 11:43:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 16-11-2014 / 16:25:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_shared_pool_names
+
+ self assert: #() = (rbClass realSharedPoolNames)
+
+ "Created: / 16-11-2014 / 16:40:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_source_code_at_existing_method
+ | class expectedSource actualSource |
+
+ class := model createClassImmediate: #DummyClass01.
+ model createMethodImmediate: class source: 'selector_01 ^ 555'.
+
+ rbClass := model classFor: class.
+
+ expectedSource := 'selector_01 ^ 555'.
+ actualSource := rbClass sourceCodeAt: #selector_01.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 31-01-2015 / 19:14:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_source_code_at_new_method
+ | expectedSource actualSource |
+
+ rbClass name: #DummyClass01;
+ compileMockMethod: 'isMeta ^ false';
+ compile: 'selector_01 ^ 555'.
+
+ expectedSource := 'selector_01 ^ 555'.
+ actualSource := rbClass sourceCodeAt: #selector_01.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 31-01-2015 / 19:17:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_source_code_at_unknown_method
+ | expectedSource actualSource |
+
+ rbClass name: #DummyClass01;
+ compileMockMethod: 'isMeta ^ false'.
+
+ expectedSource := nil.
+ actualSource := rbClass sourceCodeAt: #selector_01.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 31-01-2015 / 19:20:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_superclass_name
+ | expectedClassName actualClassName |
+
+ rbClass
+ name: #SomeClass;
+ superclassName: (self class name).
+
+ expectedClassName := self class name.
+ actualClassName := rbClass superclass name.
+
+ self assert: expectedClassName = actualClassName
+
+ "Created: / 05-10-2014 / 00:16:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_name_space
+
+ self assert: (rbClass topNameSpace) == (rbClass model)
+
+ "Created: / 16-11-2014 / 16:58:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class
+ | expectedClass actualClass |
+
+ "Class must be defined in the model to have class and metaclass couple"
+ model defineClass: 'Object subclass:#DummyClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:'''''.
+
+ model defineClass: 'Object subclass:#DummyPrivateClass01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ privateIn:DummyClass01'.
+
+ expectedClass := model classNamed: #DummyClass01.
+
+ rbClass := model classNamed: #'DummyClass01::DummyPrivateClass01'.
+ rbClass owningClass: expectedClass.
+
+ actualClass := rbClass topOwningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 14:12:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:18:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_with_all_superclasses_do_for_one_superclass
+ | expectedClassNames actualClassNames |
+
+ rbClass
+ name: #SomeClass;
+ superclassName: #Object.
+
+ expectedClassNames := OrderedCollection new
+ add: #SomeClass;
+ add: #Object;
+ yourself.
+
+ actualClassNames := OrderedCollection new.
+
+ rbClass withAllSuperclassesDo: [ :class |
+ actualClassNames add: class name.
+ ].
+
+ self assert: expectedClassNames = actualClassNames
+
+ "Created: / 05-10-2014 / 00:22:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBAbstractClassTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBClassTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,345 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBClassTests
+ instanceVariableNames:'rbClass mock model'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRBClassTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Test extensions in RBClass.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomRBClassTests methodsFor:'initialization & release'!
+
+setUp
+
+ mock := CustomMock new.
+ model := RBNamespace new.
+ rbClass := mock mockOf: RBClass.
+ rbClass model: model.
+
+ "Created: / 30-09-2014 / 19:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-10-2014 / 00:27:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ mock unmockAll
+
+ "Created: / 30-09-2014 / 19:44:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBClassTests methodsFor:'tests'!
+
+test_compile_for_class
+ | lastChange savedRbClass |
+
+ rbClass
+ name: #SomeClass;
+ superclassName: #Object;
+ instVarNames: #('inst1' 'inst2');
+ classVariableNames: #('Cls1');
+ poolDictionaryNames: (Array with: 'poolDict1');
+ category: 'Some-Test-Category';
+ compile.
+
+ model changes do: [ :change |
+ lastChange := change
+ ].
+ savedRbClass := model classNamed: #SomeClass.
+
+ self assert: (lastChange isKindOf: AddClassChange).
+ self assert: (lastChange changeClassName) = #SomeClass.
+ self assert: (lastChange category) = 'Some-Test-Category'.
+ self assert: (lastChange classVariableNames) = (#('Cls1') asStringCollection).
+ self assert: (lastChange instanceVariableNames) = (#('inst1' 'inst2') asStringCollection).
+ self assert: (lastChange poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).
+ self assert: (lastChange superclassName) = #Object.
+
+ self assert: (savedRbClass isKindOf: RBClass).
+ self assert: (savedRbClass name) = #SomeClass.
+ self assert: (savedRbClass category) = 'Some-Test-Category'.
+ self assert: (savedRbClass classVariableNames) = (OrderedCollection newFrom: #('Cls1')).
+ self assert: (savedRbClass instanceVariableNames) = (OrderedCollection newFrom: #('inst1' 'inst2')).
+ self assert: (savedRbClass poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).
+ self assert: (savedRbClass superclass name) = #Object.
+
+ "Created: / 05-10-2014 / 00:27:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:24:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_with_set_package
+ | lastChange savedRbClass |
+
+ rbClass
+ name: #SomeClass;
+ superclassName: #Object;
+ instVarNames: #('inst1' 'inst2');
+ classVariableNames: #('Cls1');
+ poolDictionaryNames: (Array with: 'poolDict1');
+ category: 'Some-Test-Category';
+ package: 'some_package';
+ compile.
+
+ model changes do: [ :change |
+ lastChange := change
+ ].
+ savedRbClass := model classNamed: #SomeClass.
+
+ self assert: (lastChange isKindOf: AddClassChange).
+ self assert: (lastChange changeClassName) = #SomeClass.
+ self assert: (lastChange category) = 'Some-Test-Category'.
+ self assert: (lastChange classVariableNames) = (#('Cls1') asStringCollection).
+ self assert: (lastChange instanceVariableNames) = (#('inst1' 'inst2') asStringCollection).
+ self assert: (lastChange poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).
+ self assert: (lastChange superclassName) = #Object.
+ self assert: (lastChange package) = 'some_package'.
+
+ self assert: (savedRbClass isKindOf: RBClass).
+ self assert: (savedRbClass name) = #SomeClass.
+ self assert: (savedRbClass category) = 'Some-Test-Category'.
+ self assert: (savedRbClass classVariableNames) = (OrderedCollection newFrom: #('Cls1')).
+ self assert: (savedRbClass instanceVariableNames) = (OrderedCollection newFrom: #('inst1' 'inst2')).
+ self assert: (savedRbClass poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).
+ self assert: (savedRbClass superclass name) = #Object.
+ self assert: (savedRbClass package) = 'some_package'.
+
+ "Created: / 09-10-2014 / 23:41:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:25:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_real_class_with_set_package
+ | lastChange savedRbClass expectedPackage |
+
+ expectedPackage := self class package deepCopy.
+
+ self assert: expectedPackage notEmpty.
+
+ rbClass := RBClass existingNamed: self class name.
+ rbClass
+ model: model;
+ compile.
+
+ model changes do: [ :change |
+ lastChange := change
+ ].
+ savedRbClass := model classNamed: self class name.
+
+ self assert: (lastChange isKindOf: AddClassChange).
+ self assert: (lastChange package) = expectedPackage.
+
+ self assert: (savedRbClass isKindOf: RBClass).
+ self assert: (savedRbClass package) = expectedPackage.
+
+ "Created: / 09-10-2014 / 23:54:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:36:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_with_custom_namespace
+ | lastChange savedRbClass customModel |
+
+ customModel := CustomNamespace new.
+
+ rbClass
+ model: customModel;
+ name: #SomeClass;
+ superclassName: #Object;
+ instVarNames: #('inst1' 'inst2');
+ classVariableNames: #('Cls1');
+ poolDictionaryNames: (Array with: 'poolDict1');
+ category: 'Some-Test-Category';
+ package: #some_package;
+ compile.
+
+ customModel changes do: [ :change |
+ lastChange := change
+ ].
+
+ savedRbClass := customModel classNamed: #SomeClass.
+
+ self assert: rbClass == savedRbClass.
+
+ self assert: (lastChange isKindOf: AddClassChange).
+ self assert: (lastChange changeClassName) = #SomeClass.
+ self assert: (lastChange category) = 'Some-Test-Category'.
+ self assert: (lastChange classVariableNames) = (#('Cls1') asStringCollection).
+ self assert: (lastChange instanceVariableNames) = (#('inst1' 'inst2') asStringCollection).
+ self assert: (lastChange poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).
+ self assert: (lastChange superclassName) = #Object.
+ self assert: (lastChange package) = #some_package.
+
+ self assert: (savedRbClass isKindOf: RBClass).
+ self assert: (savedRbClass name) = #SomeClass.
+ self assert: (savedRbClass category) = 'Some-Test-Category'.
+ self assert: (savedRbClass classVariableNames) = (OrderedCollection newFrom: #('Cls1')).
+ self assert: (savedRbClass instanceVariableNames) = (OrderedCollection newFrom: #('inst1' 'inst2')).
+ self assert: (savedRbClass poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).
+ self assert: (savedRbClass superclass name) = #Object.
+ self assert: (savedRbClass package) = #some_package.
+
+ "Created: / 04-11-2014 / 00:17:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:25:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_with_rb_namespace
+ | lastChange savedRbClass customModel |
+
+ customModel := RBNamespace new.
+
+ rbClass
+ model: customModel;
+ name: #SomeClass;
+ superclassName: #Object;
+ instVarNames: #('inst1' 'inst2');
+ classVariableNames: #('Cls1');
+ poolDictionaryNames: (Array with: 'poolDict1');
+ category: 'Some-Test-Category';
+ package: #some_package;
+ compile.
+
+ customModel changes do: [ :change |
+ lastChange := change
+ ].
+
+ savedRbClass := customModel classNamed: #SomeClass.
+
+ self assert: (lastChange isKindOf: AddClassChange).
+ self assert: (lastChange changeClassName) = #SomeClass.
+ self assert: (lastChange category) = 'Some-Test-Category'.
+ self assert: (lastChange classVariableNames) = (#('Cls1') asStringCollection).
+ self assert: (lastChange instanceVariableNames) = (#('inst1' 'inst2') asStringCollection).
+ self assert: (lastChange poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).
+ self assert: (lastChange superclassName) = #Object.
+ self assert: (lastChange package) = #some_package.
+
+ self assert: (savedRbClass isKindOf: RBClass).
+ self assert: (savedRbClass name) = #SomeClass.
+ self assert: (savedRbClass category) = 'Some-Test-Category'.
+ self assert: (savedRbClass classVariableNames) = (OrderedCollection newFrom: #('Cls1')).
+ self assert: (savedRbClass instanceVariableNames) = (OrderedCollection newFrom: #('inst1' 'inst2')).
+ self assert: (savedRbClass poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).
+ self assert: (savedRbClass superclass name) = #Object.
+ self assert: (savedRbClass package) = #some_package.
+
+ "Created: / 04-11-2014 / 00:17:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:25:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_class_with_set_package
+ | savedRbClass expectedPackage |
+
+ expectedPackage := self class package deepCopy.
+
+ self assert: expectedPackage notEmpty.
+
+ rbClass := RBClass existingNamed: self class name.
+
+ savedRbClass := model classNamed: self class name.
+
+ self assert: (savedRbClass isKindOf: RBClass).
+ self assert: (savedRbClass package) = expectedPackage.
+
+ "Created: / 09-10-2014 / 23:58:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:37:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_the_metaclass_for_new_class
+ | expectedMetaName actualMetaName |
+
+ "Should be 'SomeTestClass class', but if we change it
+ then some could be broken"
+ expectedMetaName := #SomeTestClass.
+
+ rbClass
+ name: #SomeTestClass;
+ classVariableNames: #();
+ poolDictionaryNames: #();
+ compile.
+
+ actualMetaName := rbClass theMetaclass name.
+
+ self assert: expectedMetaName = actualMetaName
+
+ "Created: / 08-10-2014 / 12:06:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_the_metaclass_for_real_class
+ | expectedMetaName actualMetaName |
+
+ "Should be 'SomeTestClass class', but if we change it
+ then some could be broken"
+ expectedMetaName := #Object.
+
+ rbClass
+ realName: #Object;
+ name: #Object;
+ compile.
+
+ actualMetaName := rbClass theMetaclass name.
+
+ self assert: expectedMetaName = actualMetaName
+
+ "Created: / 08-10-2014 / 12:16:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-10-2014 / 13:42:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBClassTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBLocalSourceCodeFormatter.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,175 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomSourceCodeFormatter subclass:#CustomRBLocalSourceCodeFormatter
+ instanceVariableNames:'localFormatterSettings originalFormatterSettings formatterClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomRBLocalSourceCodeFormatter class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Source code formatter based on RBFormatter, but with settings stored in instance variable.
+ Formatting itself temporarily changes global settings then performs formatting and
+ ensures that original settings are restored.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomRBLocalSourceCodeFormatter methodsFor:'accessing'!
+
+doesNotUnderstand: aMessage
+ "Store RBFormatter local settings"
+ | selector arguments |
+
+ selector := aMessage selector asSymbol.
+ arguments := aMessage arguments.
+
+ ((formatterClass class canUnderstand: selector) and: [arguments size <= 1]) ifTrue: [
+ (arguments isEmpty) ifTrue: [
+ ^ localFormatterSettings at: selector.
+ ] ifFalse: [
+ | accessor |
+
+ accessor := (selector copyFrom:1 to:(selector size - 1)) asSymbol.
+
+ ^ localFormatterSettings at: accessor put: (arguments first).
+ ]
+ ].
+
+ ^ super doesNotUnderstand: aMessage.
+
+ "Created: / 28-08-2014 / 22:39:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:37:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatterClass
+ ^ formatterClass
+!
+
+formatterClass:something
+ formatterClass := something.
+! !
+
+!CustomRBLocalSourceCodeFormatter methodsFor:'formatting'!
+
+formatParseTree:aParseTree
+ "Return parse tree formatted as source code with custom RBFormatter settings"
+ | source |
+
+ [
+ self setUpFormatterSettings.
+ aParseTree source notNil ifTrue:[
+ "normally aParseTree >> formattedCode should return formatted string,
+ but there is some error with building syntax-valid source code"
+ source := self formatSourceCode: aParseTree source
+ ] ifFalse:[
+ source := aParseTree formattedCode
+ ].
+ ] ensure: [
+ self restoreFormatterSettings.
+ ].
+
+ ^ source
+
+ "Modified: / 29-08-2014 / 00:12:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatSourceCode:aSourceCodeString
+
+ ^ formatterClass format: aSourceCodeString
+
+ "Created: / 28-08-2014 / 23:58:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 31-08-2014 / 10:59:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatter methodsFor:'initialization'!
+
+initialize
+
+ localFormatterSettings := IdentityDictionary new.
+ formatterClass := RBFormatter.
+
+ "Created: / 28-08-2014 / 23:05:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 31-08-2014 / 10:58:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+restoreFormatterSettings
+ "see setUpFormatterSettings "
+
+ originalFormatterSettings keysAndValuesDo: [ :key :value |
+ formatterClass perform: key asMutator with: value.
+ ].
+
+ "Modified: / 31-08-2014 / 14:59:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUpFormatterSettings
+ "Settings for RBFormatter to keep formatting settings independent on system settings.
+ Actually this is not perfect solution because of global scope modifications - imagine
+ parallel execution. "
+
+ originalFormatterSettings := IdentityDictionary new.
+ localFormatterSettings keysAndValuesDo: [ :key :value |
+ originalFormatterSettings at: key put: (formatterClass perform: key).
+ formatterClass perform: key asMutator with: value.
+ ].
+
+ "Created: / 20-08-2014 / 22:21:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 31-08-2014 / 15:00:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatter class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBLocalSourceCodeFormatterTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,212 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBLocalSourceCodeFormatterTests
+ instanceVariableNames:'spaceAfterReturnToken maxLengthForSingleLineBlocks
+ blockArgumentsOnNewLine formatter'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRBLocalSourceCodeFormatterTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomRBLocalSourceCodeFormatterTests methodsFor:'initialization & release'!
+
+setUp
+ "Original RBFormatter settings"
+
+ spaceAfterReturnToken := RBFormatter spaceAfterReturnToken.
+ maxLengthForSingleLineBlocks := RBFormatter maxLengthForSingleLineBlocks.
+ blockArgumentsOnNewLine := RBFormatter blockArgumentsOnNewLine.
+
+ formatter := CustomRBLocalSourceCodeFormatter new.
+
+ "Modified: / 30-08-2014 / 23:18:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ RBFormatter spaceAfterReturnToken: spaceAfterReturnToken.
+ RBFormatter maxLengthForSingleLineBlocks: maxLengthForSingleLineBlocks.
+ RBFormatter blockArgumentsOnNewLine: blockArgumentsOnNewLine.
+
+ "Modified: / 21-08-2014 / 11:54:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatterTests methodsFor:'private'!
+
+initilizeFormatterSettings: aFormatter
+
+ aFormatter
+ tabIndent: 4;
+ spaceAroundTemporaries: false;
+ emptyLineAfterTemporaries: true;
+ emptyLineAfterMethodComment: true;
+ spaceAfterReturnToken: true;
+ spaceAfterKeywordSelector: false;
+ spaceAfterBlockStart: true;
+ spaceBeforeBlockEnd: true;
+ cStyleBlocks: true;
+ blockArgumentsOnNewLine: false;
+ maxLengthForSingleLineBlocks: 4;
+ periodAfterLastStatementPolicy: #keep.
+
+ "Created: / 30-08-2014 / 23:27:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatterTests methodsFor:'tests'!
+
+test_format_parse_tree_source_is_nil
+ | expectedSource actualSource parseTree source |
+
+ source := 'selector ^ 777'.
+ parseTree := RBParser parseMethod: source.
+ parseTree source: nil.
+
+ formatter tabIndent: 4.
+ formatter spaceAfterReturnToken: true.
+
+ actualSource := formatter formatParseTree: parseTree.
+ expectedSource := 'selector
+ ^ 777'.
+
+ self assert: actualSource = expectedSource.
+
+ "Created: / 31-08-2014 / 14:59:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_format_parse_tree_source_not_nil
+ | expectedSource actualSource parseTree source |
+
+ source := 'selector ^ 777'.
+ parseTree := RBParser parseMethod: source.
+ parseTree source: source.
+
+ formatter tabIndent: 4.
+ formatter spaceAfterReturnToken: true.
+
+ actualSource := formatter formatParseTree: parseTree.
+ expectedSource := 'selector
+ ^ 777'.
+
+ self assert: actualSource = expectedSource.
+
+ "Created: / 31-08-2014 / 14:58:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_format_source_code
+ "Assert that some formatting is made."
+
+ | sourceCodeString actualSource |
+
+ sourceCodeString := 'selector ^ 563'.
+
+ actualSource := formatter formatSourceCode: sourceCodeString.
+
+ self deny: sourceCodeString = actualSource.
+
+ "Created: / 30-08-2014 / 23:24:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 09-09-2014 / 21:47:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_formatter_setting_set_and_get
+
+ | expectedTabIndent actualTabIndent |
+
+ self deny: (formatter class canUnderstand: #tabIndent:).
+ self deny: (formatter class canUnderstand: #tabIndent).
+
+ formatter tabIndent: 10.
+
+ expectedTabIndent := 10.
+ actualTabIndent := formatter tabIndent.
+
+ self assert: expectedTabIndent = actualTabIndent.
+
+ "Created: / 31-08-2014 / 14:42:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_formatter_setting_unknown
+
+ self deny: (formatter class canUnderstand: #someUnknownSetting:).
+
+ self should: [
+ formatter someUnknownSetting: 10
+ ] raise: MessageNotUnderstood
+
+ "Created: / 31-08-2014 / 14:44:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_formatter_settings_modified_and_then_restored
+
+ formatter
+ spaceAfterReturnToken: (spaceAfterReturnToken isNil ifTrue: [ true ] ifFalse: [ spaceAfterReturnToken not ]);
+ maxLengthForSingleLineBlocks: (spaceAfterReturnToken isNil ifTrue: [ 21 ] ifFalse: [ maxLengthForSingleLineBlocks + 10 ]);
+ blockArgumentsOnNewLine: (blockArgumentsOnNewLine isNil ifTrue: [ true ] ifFalse: [ blockArgumentsOnNewLine not ]).
+
+ formatter setUpFormatterSettings.
+
+ self assert: (RBFormatter spaceAfterReturnToken) == (spaceAfterReturnToken isNil ifTrue: [ true ] ifFalse: [ spaceAfterReturnToken not ]).
+ self assert: (RBFormatter maxLengthForSingleLineBlocks) == (spaceAfterReturnToken isNil ifTrue: [ 21 ] ifFalse: [ maxLengthForSingleLineBlocks + 10 ]).
+ self assert: (RBFormatter blockArgumentsOnNewLine) == (blockArgumentsOnNewLine isNil ifTrue: [ true ] ifFalse: [ blockArgumentsOnNewLine not ]).
+
+ formatter restoreFormatterSettings.
+
+ self assert: (RBFormatter spaceAfterReturnToken) == spaceAfterReturnToken.
+ self assert: (RBFormatter maxLengthForSingleLineBlocks) == maxLengthForSingleLineBlocks.
+ self assert: (RBFormatter blockArgumentsOnNewLine) == blockArgumentsOnNewLine.
+
+ "Created: / 21-08-2014 / 11:44:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-08-2014 / 23:40:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatterTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBMetaclassTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,314 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBMetaclassTests
+ instanceVariableNames:'rbClass mock model'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+CustomRBMetaclassTests subclass:#MockPrivateClass01
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRBMetaclassTests
+!
+
+CustomRBMetaclassTests::MockPrivateClass01 subclass:#MockPrivateClass03
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRBMetaclassTests::MockPrivateClass01
+!
+
+Object subclass:#MockPrivateClass02
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRBMetaclassTests
+!
+
+!CustomRBMetaclassTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Test extensions in RBMetaclass.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomRBMetaclassTests methodsFor:'initialization & release'!
+
+setUp
+
+ mock := CustomMock new.
+ model := RBNamespace new.
+ rbClass := mock mockOf: RBMetaclass.
+ rbClass model: model.
+
+ "Created: / 29-11-2014 / 02:28:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ mock unmockAll
+
+ "Created: / 29-11-2014 / 02:28:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBMetaclassTests methodsFor:'tests'!
+
+test_owning_class_empty
+ | expectedClass actualClass |
+
+ expectedClass := nil.
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 12:37:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_model_class
+ | expectedClass actualClass |
+
+ expectedClass := RBClass new.
+ rbClass owningClass: expectedClass.
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 12:43:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_model_metaclass
+ | expectedClass actualClass |
+
+ expectedClass := model classNamed: self class name.
+ rbClass owningClass: expectedClass theMetaclass.
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 13:39:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_real_class
+ | expectedClass actualClass |
+
+ expectedClass := model classNamed: self class name.
+ rbClass owningClass: self class.
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 12:42:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_real_metaclass
+ | expectedClass actualClass |
+
+ expectedClass := model classNamed: self class name.
+ rbClass owningClass: self class theMetaclass.
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 13:37:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class
+ | expectedClass actualClass |
+
+ expectedClass := model classNamed: #'SmallSense::CustomRBMetaclassTests'.
+
+ rbClass realClass: SmallSense::CustomRBMetaclassTests::MockPrivateClass01.
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 02:31:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-11-2014 / 12:19:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:28:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class_with_different_superclass
+ | expectedClass actualClass |
+
+ expectedClass := model classNamed: #'SmallSense::CustomRBMetaclassTests'.
+
+ rbClass realClass: CustomRBMetaclassTests::MockPrivateClass02.
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 12:20:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:28:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class_without_owner
+ | expectedClass actualClass |
+
+ expectedClass := nil.
+
+ rbClass realClass: CustomRBMetaclassTests.
+ actualClass := rbClass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 12:21:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_01
+ | expectedClass actualClass |
+
+ "Cannot use self class, because TestRunner eats also private classes
+ and when running in private class the class is different"
+ expectedClass := CustomRBMetaclassTests.
+ actualClass := CustomRBMetaclassTests::MockPrivateClass01 owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 13:34:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 30-11-2014 / 17:18:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_02
+ | expectedClass actualClass |
+
+ "Cannot use self class, because TestRunner eats also private classes
+ and when running in private class the class is different"
+ expectedClass := CustomRBMetaclassTests.
+ actualClass := CustomRBMetaclassTests::MockPrivateClass01 class owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 13:35:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 30-11-2014 / 17:18:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_03
+ | expectedClass actualClass |
+
+ "Cannot use self class, because TestRunner eats also private classes
+ and when running in private class the class is different"
+ expectedClass := CustomRBMetaclassTests.
+ actualClass := CustomRBMetaclassTests::MockPrivateClass01 theMetaclass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 13:35:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 30-11-2014 / 17:18:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_04
+ | expectedClass actualClass |
+
+ "Cannot use self class, because TestRunner eats also private classes
+ and when running in private class the class is different"
+ expectedClass := CustomRBMetaclassTests.
+ actualClass := CustomRBMetaclassTests::MockPrivateClass01 theNonMetaclass owningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 13:35:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 30-11-2014 / 17:18:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class_empty
+ | expectedClass actualClass |
+
+ expectedClass := nil.
+ actualClass := rbClass topOwningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 13:53:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class_with_real_class
+ | expectedClass actualClass |
+
+ expectedClass := model classNamed: #'SmallSense::CustomRBMetaclassTests'.
+
+ rbClass realClass: CustomRBMetaclassTests::MockPrivateClass01.
+ actualClass := rbClass topOwningClass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 14:04:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:28:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_top_owning_class_with_real_class_two_level
+ | expectedClass actualClass |
+
+ expectedClass := model classNamed: #'SmallSense::CustomRBMetaclassTests'.
+
+ rbClass realClass: CustomRBMetaclassTests::MockPrivateClass01 myMockPrivateClass03.
+ actualClass := rbClass topOwningClass.
+
+ self assert: (rbClass realClass name) = #'SmallSense::CustomRBMetaclassTests::MockPrivateClass01::MockPrivateClass03'.
+ self assert: expectedClass = actualClass
+
+ "Created: / 29-11-2014 / 14:05:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 13:13:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:29:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomRBMetaclassTests::MockPrivateClass01 class methodsFor:'accessing'!
+
+myMockPrivateClass03
+ "Returns my private class (for testing purposes)"
+
+ ^ MockPrivateClass03
+
+ "Created: / 29-11-2014 / 14:08:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBMethodTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,731 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBMethodTests
+ instanceVariableNames:'rbMethod mock model'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRBMethodTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomRBMethodTests methodsFor:'initialization & release'!
+
+setUp
+
+ mock := CustomMock new.
+ rbMethod := mock mockOf: RBMethod.
+ model := RBNamespace new.
+ rbMethod model: model.
+
+ "Created: / 30-09-2014 / 19:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 06-10-2014 / 07:38:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+ mock unmockAll
+
+ "Created: / 30-09-2014 / 19:44:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBMethodTests methodsFor:'tests'!
+
+test_category_custom_set
+ | expectedCategory actualCategory |
+
+ expectedCategory := 'test category'.
+
+ rbMethod category: expectedCategory.
+ actualCategory := rbMethod category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 06-10-2014 / 08:11:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_empty
+ | expectedCategory actualCategory |
+
+ expectedCategory := 'as yet unclassified'.
+
+ "actually we need to set model class with real class
+ and selector or source to retrieve 'as yet unclassified' category/protocol"
+ rbMethod
+ modelClass: (model classNamed: #Object);
+ selector: #someSelector.
+ actualCategory := rbMethod category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 06-10-2014 / 08:12:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_empty_with_none_class
+ | expectedCategory actualCategory |
+
+ expectedCategory := 'as yet unclassified'.
+
+ actualCategory := rbMethod category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 08-10-2014 / 18:40:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_from_compiled_method
+ | expectedCategory actualCategory |
+
+ expectedCategory := 'tests'.
+
+ rbMethod method: (self class compiledMethodAt: #test_category_from_compiled_method).
+ actualCategory := rbMethod category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 06-10-2014 / 08:20:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_from_real_class
+ | expectedCategory actualCategory |
+
+ expectedCategory := 'tests'.
+
+ rbMethod
+ class: self class;
+ selector: #test_category_from_real_class.
+
+ actualCategory := rbMethod category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 06-10-2014 / 08:21:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_for_model_class
+ | expectedModelClass actualModelClass |
+
+ expectedModelClass := RBClass new.
+
+ rbMethod class: expectedModelClass.
+ actualModelClass := rbMethod modelClass.
+
+ self assert: expectedModelClass = actualModelClass
+
+ "Created: / 06-10-2014 / 07:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_for_real_class
+ | expectedModelClass actualModelClass |
+
+ expectedModelClass := model classNamed: #Object.
+
+ rbMethod class: Object.
+ actualModelClass := rbMethod modelClass.
+
+ self assert: expectedModelClass = actualModelClass
+
+ "Created: / 06-10-2014 / 07:36:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_for_real_metaclass
+ | expectedModelClass actualModelClass |
+
+ expectedModelClass := model metaclassNamed: #Object.
+
+ rbMethod class: Object class.
+ actualModelClass := rbMethod modelClass.
+
+ self assert: expectedModelClass = actualModelClass
+
+ "Created: / 06-10-2014 / 07:42:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_with_code_generator
+ | actualMethod generator class source expectedSource actualSource |
+
+ generator := CustomSourceCodeGenerator new
+ formatter: CustomNoneSourceCodeFormatter new;
+ yourself.
+
+ class := RBClass new
+ name: #SomeTestClass;
+ model: model;
+ superclassName: #Object;
+ yourself.
+
+ actualMethod := class compiledMethodAt: #selector_01.
+ self assert: actualMethod isNil.
+
+ source := 'selector_01
+ "Comment"
+
+ `variable := 500.
+ ^ `variable'.
+
+ expectedSource := 'selector_01
+ "Comment"
+
+ variableName := 500.
+ ^ variableName'.
+
+ rbMethod
+ class: class;
+ sourceCodeGenerator: generator;
+ source: source;
+ replace: '`variable' with: 'variableName';
+ protocol: 'test protocol';
+ compile.
+
+ actualMethod := class compiledMethodAt: #selector_01.
+ actualSource := actualMethod source.
+
+ self assert: actualSource = expectedSource.
+ self assert: (actualMethod protocol) = (rbMethod protocol)
+
+ "Created: / 06-10-2014 / 22:45:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 15:14:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_with_custom_package
+ | actualMethod class change |
+
+ class := RBClass new
+ name: #SomeTestClass;
+ model: model;
+ superclassName: #Object;
+ yourself.
+
+ actualMethod := class compiledMethodAt: #selector_01.
+ self assert: actualMethod isNil.
+
+ change := rbMethod
+ class: class;
+ source: 'selector_01 ^ 12';
+ protocol: 'test protocol';
+ package: 'my_package';
+ compile.
+
+ actualMethod := class compiledMethodAt: #selector_01.
+
+ self assert: (actualMethod source) = (rbMethod source).
+ self assert: (actualMethod protocol) = (rbMethod protocol).
+ self assert: (actualMethod package) = (rbMethod package).
+
+ self assert: (change source) = (rbMethod source).
+ self assert: (change protocol) = (rbMethod protocol).
+ self assert: (change package) = (rbMethod package).
+
+ "Created: / 10-10-2014 / 11:25:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_without_code_generator
+ | actualMethod class |
+
+ class := RBClass new
+ name: #SomeTestClass;
+ model: model;
+ superclassName: #Object;
+ yourself.
+
+ actualMethod := class compiledMethodAt: #selector_01.
+ self assert: actualMethod isNil.
+
+ rbMethod
+ class: class;
+ source: 'selector_01 ^ 12';
+ protocol: 'test protocol';
+ compile.
+
+ actualMethod := class compiledMethodAt: #selector_01.
+
+ self assert: (actualMethod source) = (rbMethod source).
+ self assert: (actualMethod protocol) = (rbMethod protocol)
+
+ "Created: / 06-10-2014 / 21:11:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 06-10-2014 / 22:33:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_without_custom_package
+ | actualMethod class change |
+
+ class := RBClass new
+ name: #SomeTestClass;
+ model: model;
+ superclassName: #Object;
+ yourself.
+
+ actualMethod := class compiledMethodAt: #selector_01.
+ self assert: actualMethod isNil.
+
+ change := rbMethod
+ class: class;
+ source: 'selector_01 ^ 12';
+ protocol: 'test protocol';
+ compile.
+
+ actualMethod := class compiledMethodAt: #selector_01.
+
+ self assert: (actualMethod source) = (rbMethod source).
+ self assert: (actualMethod protocol) = (rbMethod protocol).
+ self assert: (actualMethod package) = (rbMethod package).
+
+ self assert: (change source) = (rbMethod source).
+ self assert: (change protocol) = (rbMethod protocol).
+ self assert: (change package) = (rbMethod package).
+
+ "Created: / 10-10-2014 / 11:51:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiled_method_empty
+ | expectedMethod actualMethod |
+
+ expectedMethod := nil.
+ actualMethod := rbMethod method.
+
+ self assert: expectedMethod = actualMethod
+
+ "Created: / 08-10-2014 / 19:27:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiled_method_for_real_method
+ | expectedMethod actualMethod |
+
+ expectedMethod := self class compiledMethodAt: #test_compiled_method_for_real_method.
+
+ rbMethod := RBMethod
+ for: RBClass new
+ fromMethod: expectedMethod
+ andSelector: #test_compiled_method_for_real_method.
+
+ actualMethod := rbMethod method.
+
+ self assert: expectedMethod = actualMethod
+
+ "Created: / 08-10-2014 / 19:30:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiled_method_for_real_method_empty
+ | expectedMethod actualMethod |
+
+ expectedMethod := self class compiledMethodAt: #test_compiled_method_for_real_method.
+
+ rbMethod
+ modelClass: (RBClass existingNamed: self className asSymbol);
+ selector: #test_compiled_method_for_real_method.
+
+ actualMethod := rbMethod method.
+
+ self assert: expectedMethod = actualMethod
+
+ "Created: / 08-10-2014 / 19:32:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiled_method_when_selector_empty
+ | expectedMethod actualMethod |
+
+ expectedMethod := nil.
+
+ rbMethod
+ modelClass: (RBClass existingNamed: self className asSymbol);
+ source: 'selector_01 ^ 1'.
+
+ actualMethod := rbMethod method.
+
+ self assert: expectedMethod = actualMethod
+
+ "Created: / 08-10-2014 / 19:36:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_mclass
+ | expectedClass actualClass |
+
+ expectedClass := RBClass new.
+ rbMethod modelClass: expectedClass.
+
+ actualClass := rbMethod mclass.
+
+ self assert: expectedClass = actualClass
+
+ "Created: / 25-11-2014 / 22:27:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 27-11-2014 / 23:18:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_arg_names_none_arg
+ | expectedArguments actualArguments |
+
+ expectedArguments := nil.
+
+ rbMethod source: 'selector ^ 5'.
+ actualArguments := rbMethod methodArgNames.
+
+ self assert: expectedArguments = actualArguments
+
+ "Created: / 07-10-2014 / 21:39:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_arg_names_one_arg
+ | expectedArguments actualArguments |
+
+ expectedArguments := #('arg_01').
+
+ rbMethod source: 'selector: arg_01 ^ 5'.
+ actualArguments := rbMethod methodArgNames.
+
+ self assert: expectedArguments = actualArguments
+
+ "Created: / 07-10-2014 / 21:39:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_arg_names_two_args
+ | expectedArguments actualArguments |
+
+ expectedArguments := #('arg_01' 'arg_02').
+
+ rbMethod source: 'selector: arg_01 param: arg_02 ^ 5'.
+ actualArguments := rbMethod methodArgNames.
+
+ self assert: expectedArguments = actualArguments
+
+ "Created: / 07-10-2014 / 21:57:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_definition_template_none_arg
+ | expectedMethodDefinition actualMethodDefinition |
+
+ expectedMethodDefinition := 'selector'.
+
+ rbMethod source: 'selector ^ 5'.
+ actualMethodDefinition := rbMethod methodDefinitionTemplate.
+
+ self assert: expectedMethodDefinition = actualMethodDefinition
+
+ "Created: / 07-10-2014 / 22:32:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_definition_template_two_args
+ | expectedMethodDefinition actualMethodDefinition |
+
+ expectedMethodDefinition := 'selector:arg_01 param:arg_02'.
+
+ rbMethod source: 'selector: arg_01 param: arg_02 ^ 5'.
+ actualMethodDefinition := rbMethod methodDefinitionTemplate.
+
+ self assert: expectedMethodDefinition = actualMethodDefinition
+
+ "Created: / 07-10-2014 / 22:24:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_code_generator_with_replacements
+ | expectedSource actualSource |
+
+ expectedSource := 'selector_01 ^ 1'.
+ rbMethod
+ source: 'selector_01 ^ `#literal';
+ sourceCodeGenerator: ( CustomSourceCodeGenerator new
+ formatter: CustomNoneSourceCodeFormatter new;
+ yourself);
+ replace: '`#literal' with: '1'.
+
+ actualSource := rbMethod newSource.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 10-10-2014 / 15:12:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_none_code_generator
+ | expectedSource actualSource |
+
+ expectedSource := 'selector_01 ^ 1'.
+ rbMethod source: 'selector_01 ^ 1'.
+
+ actualSource := rbMethod newSource.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 10-10-2014 / 14:43:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_some_code_generator
+ | expectedSource actualSource |
+
+ expectedSource := 'selector_01 ^ 1'.
+ rbMethod
+ source: 'selector_01 ^ 1';
+ sourceCodeGenerator: ( CustomSourceCodeGenerator new
+ formatter: CustomNoneSourceCodeFormatter new;
+ yourself).
+
+ actualSource := rbMethod newSource.
+
+ self assert: expectedSource = actualSource
+
+ "Created: / 10-10-2014 / 15:10:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_custom
+ | expectedPackage actualPackage |
+
+ expectedPackage := 'some_package'.
+
+ rbMethod package: 'some_package'.
+ actualPackage := rbMethod package.
+
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 10-10-2014 / 11:20:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_empty
+ | expectedPackage actualPackage |
+
+ expectedPackage := PackageId noProjectID.
+ actualPackage := rbMethod package.
+
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 10-10-2014 / 11:16:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_from_real_method
+ | expectedPackage actualPackage |
+
+ expectedPackage := self class package.
+
+ self assert: expectedPackage size > 3.
+
+ rbMethod method: (self class compiledMethodAt: #test_package_from_real_method).
+ actualPackage := rbMethod package.
+
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 10-10-2014 / 11:16:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_programming_language_default
+ | expectedLanguage actualLanguage |
+
+ expectedLanguage := SmalltalkLanguage instance.
+ actualLanguage := rbMethod programmingLanguage.
+
+ self assert: expectedLanguage = actualLanguage
+
+ "Created: / 26-12-2014 / 12:17:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_programming_language_from_real_class
+ | expectedLanguage actualLanguage |
+
+ expectedLanguage := JavaLanguage instance.
+ rbMethod modelClass: (RBClass new realClass: JavaClass new; yourself).
+ actualLanguage := rbMethod programmingLanguage.
+
+ self assert: expectedLanguage = actualLanguage
+
+ "Created: / 26-12-2014 / 12:59:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_programming_language_from_real_method
+ | expectedLanguage actualLanguage |
+
+ expectedLanguage := JavaLanguage instance.
+ rbMethod method: (JavaMethod new mclass: JavaClass new; yourself).
+ actualLanguage := rbMethod programmingLanguage.
+
+ self assert: expectedLanguage = actualLanguage
+
+ "Created: / 26-12-2014 / 12:23:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_method_arg_names_none_arg
+ "to check what Method >> methodArgNames returns"
+
+ | expectedArguments actualArguments class method |
+
+ class := mock mockClassOf: Object.
+ class new compileMockMethod: 'selector ^ 5'.
+ method := class compiledMethodAt: #selector.
+
+ expectedArguments := nil.
+ actualArguments := method methodArgNames.
+
+ self assert: expectedArguments = actualArguments
+
+ "Created: / 07-10-2014 / 21:41:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_method_arg_names_one_arg
+ "to check what Method >> methodArgNames returns"
+
+ | expectedArguments actualArguments class method |
+
+ class := mock mockClassOf: Object.
+ class new compileMockMethod: 'selector: arg_01 ^ 5'.
+ method := class compiledMethodAt: #selector:.
+
+ expectedArguments := #('arg_01').
+ actualArguments := method methodArgNames.
+
+ self assert: expectedArguments = actualArguments
+
+ "Created: / 07-10-2014 / 21:53:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_method_arg_names_two_args
+ "to check what Method >> methodArgNames returns"
+
+ | expectedArguments actualArguments class method |
+
+ class := mock mockClassOf: Object.
+ class new compileMockMethod: 'selector: arg_01 param: arg_02 ^ 5'.
+ method := class compiledMethodAt: #selector:param:.
+
+ expectedArguments := #('arg_01' 'arg_02').
+ actualArguments := method methodArgNames.
+
+ self assert: expectedArguments = actualArguments
+
+ "Created: / 07-10-2014 / 21:55:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_empty
+ | expectedSelector actualSelector |
+
+ expectedSelector := nil.
+ actualSelector := rbMethod selector.
+
+ self assert: expectedSelector = actualSelector
+
+ "Created: / 26-12-2014 / 13:33:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_empty_for_empty_source
+ | expectedSelector actualSelector |
+
+ expectedSelector := nil.
+ rbMethod source: ''.
+ actualSelector := rbMethod selector.
+
+ self assert: expectedSelector = actualSelector
+
+ "Created: / 26-12-2014 / 13:33:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_from_source
+ | expectedSelector actualSelector |
+
+ expectedSelector := #selector_01.
+ rbMethod source: 'selector_01 ^ 1'.
+ actualSelector := rbMethod selector.
+
+ self assert: expectedSelector = actualSelector
+
+ "Created: / 26-12-2014 / 13:37:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_set
+ | expectedSelector actualSelector |
+
+ expectedSelector := #selector_01.
+ rbMethod selector: expectedSelector.
+ actualSelector := rbMethod selector.
+
+ self assert: expectedSelector = actualSelector
+
+ "Created: / 26-12-2014 / 13:39:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_sends_literal_or_sends_another_literal_first
+
+ rbMethod source: 'selector ^ self subclassResponsibility'.
+
+ self assert: (rbMethod sends:#subclassResponsibility or:#subclassResponsibility:)
+
+ "Created: / 03-10-2014 / 20:14:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_sends_literal_or_sends_another_literal_second
+
+ rbMethod source: 'selector
+ "comment"
+
+ ^ self subclassResponsibility: #arg.'.
+
+ self assert: (rbMethod sends:#subclassResponsibility or:#subclassResponsibility:)
+
+ "Created: / 04-10-2014 / 00:03:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_sends_literal_or_sends_another_with_real_method
+ | someObject |
+
+ someObject := mock mockOf: Object.
+ someObject compileMockMethod: 'selector_01
+ "comment"
+
+ ^ self subclassResponsibility: #arg.'.
+
+ self assert: ((someObject class compiledMethodAt: #selector_01) isKindOf: CompiledCode).
+
+ rbMethod := RBMethod
+ for: (RBClass existingNamed: someObject className asSymbol)
+ fromMethod: (someObject class compiledMethodAt: #selector_01)
+ andSelector: #selector_01.
+
+
+ self assert: (rbMethod sends:#subclassResponsibility or:#subclassResponsibility:)
+
+ "Created: / 04-10-2014 / 00:05:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBMethodTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoring.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,79 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoring subclass:#CustomRefactoring
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomRefactoring class methodsFor:'testing'!
+
+isAbstract
+ ^ self == CustomRefactoring
+
+ "Created: / 26-01-2014 / 21:39:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isCustomRefactoring
+ ^ true
+! !
+
+!CustomRefactoring methodsFor:'testing'!
+
+isCustomRefactoring
+ ^ true
+! !
+
+!CustomRefactoring class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoringClassGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,105 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomNewClassGenerator subclass:#CustomRefactoringClassGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomRefactoringClassGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomRefactoringClassGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+ ^ 'Create new class which should perform some refactoring'
+
+ "Modified: / 09-11-2014 / 00:51:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+
+ ^ #(Generators)
+
+ "Created: / 08-11-2014 / 17:19:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+
+ ^ 'New Refactoring'
+
+ "Modified: / 08-11-2014 / 17:18:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoringClassGenerator methodsFor:'accessing - ui'!
+
+defaultClassName
+
+ ^ 'CustomXXXRefactoring'
+
+ "Created: / 08-11-2014 / 17:15:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newClassNameLabel
+
+ ^ 'Enter class name for new refactoring'
+
+ "Created: / 08-11-2014 / 17:16:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoringClassGenerator methodsFor:'executing - private'!
+
+buildForClass: aClass
+
+ aClass
+ superclassName: CustomRefactoring name;
+ category: CustomRefactoring category
+
+ "Created: / 08-11-2014 / 17:15:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 21:05:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoringClassGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,83 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomRefactoringClassGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomRefactoringClassGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomRefactoringClassGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomRefactoringClassGenerator new
+! !
+
+!CustomRefactoringClassGeneratorTests methodsFor:'tests'!
+
+test_refactoring_subclass_created
+ | expectedSource class |
+
+ expectedSource := 'buildInContext:aCustomContext
+ self shouldImplement'.
+
+ generatorOrRefactoring
+ newClassName: #DummyClass01;
+ executeInContext: context.
+
+ self assertClassExists: #DummyClass01.
+
+ class := Smalltalk at: #DummyClass01.
+
+ self assertMethodSource:expectedSource atSelector:#buildInContext: forClass: class.
+ self assert: (class superclass name) = #SmallSense::CustomRefactoring.
+
+ "Created: / 09-11-2014 / 01:04:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 21:03:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoryBuilder.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,704 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomRefactoryBuilder
+ instanceVariableNames:'changeManager formatter model rewritterClass searcherClass
+ parserClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+CustomRefactoryBuilder subclass:#ClassCategorySearcher
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#ClassSearcher
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#CodeSelectionSearcher
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#MethodSearcher
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#PackageSearcher
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#ProtocolSearcher
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomRefactoryBuilder
+!
+
+!CustomRefactoryBuilder class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Encapsulates performing refactoring changes on the source code within single object.
+ Single refactorings are stored as change objects which represens changes in the source code.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomRefactoryBuilder class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+! !
+
+!CustomRefactoryBuilder methodsFor:'accessing'!
+
+changeManager
+ ^ changeManager
+!
+
+changeManager:something
+ changeManager := something.
+!
+
+formatter
+ ^ formatter
+!
+
+formatter: aFormatter
+ formatter := aFormatter.
+
+ "Modified (format): / 31-08-2014 / 17:12:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+model
+ ^ model
+!
+
+model:something
+ model := something.
+!
+
+parser
+ "Returns prepared source code parser"
+
+ ^ parserClass
+
+ "Created: / 24-08-2014 / 23:36:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-12-2014 / 22:02:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+parserClass
+ "Returns a class used to parse the source code (i.e. RBParser)"
+
+ ^ parserClass
+
+ "Modified (comment): / 10-12-2014 / 22:01:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+parserClass: aClass
+ "see parserClass"
+
+ parserClass := aClass
+
+ "Modified (comment): / 10-12-2014 / 21:59:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+rewritterClass
+ "Returns a class used for rewriting the source code.
+ For example CustomParseTreeRewriter."
+
+ ^ rewritterClass
+
+ "Modified (comment): / 10-12-2014 / 21:16:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+rewritterClass: aClass
+ "see rewritterClass"
+
+ rewritterClass := aClass.
+
+ "Modified (comment): / 10-12-2014 / 21:16:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+searcher
+ "Returns prepared source code searcher"
+
+ ^ searcherClass new
+
+ "Created: / 16-08-2014 / 22:13:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-12-2014 / 22:03:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+searcherClass
+ "Returns a class used to search on the source code (i.e. ParseTreeSearcher)"
+
+ ^ searcherClass
+
+ "Modified (comment): / 10-12-2014 / 22:00:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+searcherClass:something
+ searcherClass := something.
+! !
+
+!CustomRefactoryBuilder methodsFor:'compiling'!
+
+execute
+ "Performs code changes ( add method, add class, rename class... )
+ so they take in effect ( method is added, class is renamed, ... )
+ with respect to current change manager implementatin - see CustomChangeManager subclasses."
+
+ model execute
+
+ "Created: / 15-08-2014 / 00:45:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 17:42:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+undoChanges
+ "redo all changes made by execute method"
+
+ model undoChanges
+
+ "Created: / 19-10-2014 / 14:57:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 17:42:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'initialization'!
+
+initialize
+
+ super initialize.
+ model := CustomNamespace new.
+ rewritterClass := CustomParseTreeRewriter.
+ searcherClass := ParseTreeSearcher.
+ parserClass := RBParser.
+
+ "Created: / 15-08-2014 / 00:42:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-12-2014 / 22:04:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'parsing'!
+
+parse: aSourceCode codeSelection: aCodeSelection
+ "Retuns a parse tree from given source code string
+ depending on what is selected within a method."
+
+ aCodeSelection isWholeMethodSelected ifTrue: [
+ ^ self parseMethod: aSourceCode
+ ].
+
+ ^ self parseExpression: aSourceCode
+
+ "Created: / 10-12-2014 / 21:40:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+parseExpression: aSourceCode
+ "Helper for retrieving parse tree from source code string.
+ Assume thats expression and if parsing fails then try method parsing."
+
+ ^ self parser parseExpression: aSourceCode onError: [ :string :pos |
+ self parser parseRewriteMethod: aSourceCode onError: [ :string :pos |
+ self error: 'Could not parse ', string, ' at pos ', pos asString
+ ]
+ ]
+
+ "Created: / 25-08-2014 / 22:34:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-02-2015 / 21:55:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+parseMethod: aSourceCode
+ "Helper for retrieving parse tree from source code string.
+ Assume thats method and if parsing fails then try expression parsing."
+
+ ^ self parser parseRewriteMethod: aSourceCode onError: [ :string :pos |
+ self parser parseExpression: aSourceCode onError: [ :string :pos |
+ self error: 'Could not parse ', string, ' at pos ', pos asString
+ ]
+ ]
+
+ "Created: / 25-08-2014 / 22:35:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-02-2015 / 21:55:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'refactory - changes'!
+
+changeCategoryOf: aClass to: aCategory
+ "Changes class category to the given one in given class"
+ | change |
+
+ (self model classFor: aClass) category: aCategory.
+
+ change := (self initializeChange: RefactoryClassCategoryChange)
+ changeClass: aClass;
+ category: aCategory;
+ yourself.
+
+ model changes addChange: change
+
+ "Created: / 08-11-2014 / 13:40:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 17:35:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+executeReplace: searchPattern with: rewritePattern inCodeSelection: aCodeSelection
+ "Performs replacement on some code selection within method source code.
+ Firstly the search and relace is limited just to some selection
+ (i.e. some expression, but whole method can be selected)
+ and then is this new code inserted in the method source code."
+ | parseTree foundMatch rewriter selectedCode |
+
+ selectedCode := aCodeSelection selectedSourceCode.
+ parseTree := self parse: selectedCode codeSelection: aCodeSelection.
+
+ rewriter := rewritterClass new
+ oldSource: aCodeSelection selectedSourceCode;
+ replace: searchPattern with: rewritePattern;
+ yourself.
+
+ foundMatch := rewriter executeTree: parseTree.
+
+ foundMatch ifTrue: [
+ | change newSource newParseTree |
+
+ newSource := rewriter tree newSource.
+ newParseTree := self parse: newSource codeSelection: aCodeSelection.
+ newSource := formatter formatParseTree: newParseTree.
+
+ aCodeSelection selectedInterval notNil ifTrue: [
+ rewriter := rewritterClass new.
+ foundMatch := rewriter
+ replace: selectedCode with: newSource when: [ :aNode |
+ aNode intersectsInterval: aCodeSelection selectedInterval
+ ];
+ executeTree: (self parseMethod: aCodeSelection currentSourceCode).
+
+ newSource := rewriter newSource.
+ ].
+
+ (foundMatch and: [ newSource notNil ]) ifTrue: [
+ change := model
+ compile: newSource
+ in: aCodeSelection selectedMethod mclass
+ classified: aCodeSelection selectedMethod category.
+
+ change package: aCodeSelection selectedMethod package
+ ]
+ ].
+
+ "Created: / 24-08-2014 / 10:24:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-02-2015 / 21:57:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeChange: aChangeClass
+ "Returns new initialized instance of a code change like AddClassChange"
+
+ ^ aChangeClass new
+ model: self model;
+ yourself
+
+ "Created: / 08-11-2014 / 16:10:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replace: searchPattern with: rewritePattern inContext: aCustomContext
+ "Searches for given pattern in methods source code or selected code fragments
+ and if source code matches then executes replacement"
+
+ self
+ search: searchPattern
+ inContext: aCustomContext
+ withResultDo: [ :sourceSelection |
+ self executeReplace: searchPattern with: rewritePattern inCodeSelection: sourceSelection
+ ]
+
+ "Created: / 16-08-2014 / 19:15:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 22:14:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'searching - instance creation'!
+
+classCategorySearcher
+
+ ^ self initializeSearcher: ClassCategorySearcher
+
+ "Created: / 04-11-2014 / 18:47:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classSearcher
+
+ ^ self initializeSearcher: ClassSearcher
+
+ "Created: / 04-11-2014 / 21:43:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+codeSelectionSearcher
+
+ ^ self initializeSearcher: CodeSelectionSearcher
+
+ "Created: / 04-11-2014 / 22:36:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeSearcher: searcherClass
+ "Returns new searcher with prepared instance variables."
+
+ ^ searcherClass new
+ model: model;
+ yourself
+
+ "Created: / 03-11-2014 / 09:45:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodSearcher
+
+ ^ self initializeSearcher: MethodSearcher
+
+ "Created: / 04-11-2014 / 22:32:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+packageSearcher
+
+ ^ self initializeSearcher: PackageSearcher
+
+ "Created: / 01-11-2014 / 19:52:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 03-11-2014 / 09:46:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+protocolSearcher
+
+ ^ self initializeSearcher: ProtocolSearcher
+
+ "Created: / 01-11-2014 / 15:56:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 03-11-2014 / 09:46:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+ "Searches for source code pattern in whole context which contains code, methods, classes...
+ and when context is from browser then restrict search within its perspective (CustomPerspective)."
+ | perspective |
+
+ perspective := aCustomContext perspective.
+
+ self class privateClassesDo: [ :class |
+ (class includesSelector: #search:inContext:withResultDo:) ifTrue: [
+ (perspective isNil or: [ class availableInPerspective: perspective ]) ifTrue: [
+ | searcher |
+
+ searcher := self initializeSearcher: class.
+ searcher search: searchPattern inContext: aCustomContext withResultDo: aBlock
+ ]
+ ]
+ ]
+
+ "Created: / 17-08-2014 / 16:21:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 05-11-2014 / 20:33:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-12-2014 / 22:41:52 / root"
+! !
+
+!CustomRefactoryBuilder::ClassCategorySearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+ "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+ ^ aCustomPerspective isClassCategoryPerspective
+
+ "Created: / 04-11-2014 / 18:44:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ClassCategorySearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+ "Iterates through all classes to find out which belongs to given categories and
+ executes search on those classes for methods matching given searchPattern."
+ | categories classSearcher |
+
+ categories := aCustomContext selectedClassCategories.
+ categories isEmptyOrNil ifTrue: [
+ "Skip search when none categories are selected.
+ The algorithm would iterate through all classes so this is an optimization."
+ ^ self
+ ].
+
+ classSearcher := self classSearcher.
+
+ model allClassesDo: [ :class |
+ "Including only non metaclasses, because search in class
+ searches both class and metaclass."
+ (class isMeta not and: [categories includes: class category]) ifTrue: [
+ classSearcher search: searchPattern inClass: class withResultDo: aBlock
+ ]
+ ]
+
+ "Created: / 04-11-2014 / 18:42:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 20:55:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ClassSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+ "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+ ^ aCustomPerspective isClassPerspective
+
+ "Created: / 04-11-2014 / 21:39:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ClassSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inClass: aClass withResultDo: aBlock
+ "Searches through all methods from given class and metaclass."
+ | methodSearcher |
+
+ methodSearcher := self methodSearcher.
+
+ aClass instAndClassMethodsDo: [ :method |
+ methodSearcher search: searchPattern inMethod: method withResultDo: aBlock
+ ]
+
+ "Created: / 17-08-2014 / 13:15:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 20:57:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+ "Executes search on each class in selected class collection.
+ see search:inClass:withResultDo:"
+
+ aCustomContext selectedClasses ? #() do:[ :class |
+ self search: searchPattern inClass: class withResultDo: aBlock
+ ].
+
+ "Created: / 04-11-2014 / 21:45:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::CodeSelectionSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+ "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+ ^ aCustomPerspective isCodeViewPerspective
+
+ "Created: / 04-11-2014 / 22:28:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::CodeSelectionSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+ "Searches for each selected code fragment (see CustomSourceCodeSelection)
+ which matches given search pattern.
+ If match is found then code selection is passed in a block."
+
+ aCustomContext selectedCodes ? #() do:[ :codeSelection |
+ | parseTree selectedCode |
+
+ selectedCode := codeSelection selectedSourceCode.
+ selectedCode notEmptyOrNil ifTrue: [
+ parseTree := self parseExpression: selectedCode.
+
+ (self searcher)
+ matches: searchPattern do: [ :aNode :answer |
+ aBlock value: codeSelection
+ ];
+ executeTree: parseTree
+ ]
+ ].
+
+ "Created: / 04-11-2014 / 22:26:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 16:15:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::MethodSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+ "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+ ^ aCustomPerspective isMethodPerspective
+
+ "Created: / 04-11-2014 / 22:29:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::MethodSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+ "Searches all selected methods and executes given block when match is found."
+
+ aCustomContext selectedMethods ? #() do: [ :method |
+ self search: searchPattern inMethod: method withResultDo: aBlock
+ ].
+
+ "Created: / 04-11-2014 / 22:24:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+search: searchPattern inMethod: aMethod withResultDo: aBlock
+ | parseTree |
+
+ parseTree := aMethod parseTree.
+
+ parseTree isNil ifTrue: [
+ self error: 'Cannot retrieve parseTree for method: ', aMethod asString.
+ ]
+ ifFalse: [
+ (self searcher)
+ matches: searchPattern do: [ :aNode :answer |
+ | selectedCodeResult |
+
+ selectedCodeResult := CustomSourceCodeSelection new
+ selectedMethod: aMethod;
+ yourself.
+
+ aBlock value: selectedCodeResult
+ ];
+ executeTree: parseTree
+ ].
+
+ "Created: / 16-08-2014 / 22:27:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 28-10-2014 / 09:45:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::PackageSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+ "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+ ^ aCustomPerspective isPackagePerspective
+
+ "Created: / 01-11-2014 / 16:46:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::PackageSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+ "Executes search on each method which belongs to selected packages.
+ see search:inMethod:withResultDo:"
+ | packages methodSearcher |
+
+ packages := aCustomContext selectedPackages.
+ packages isEmptyOrNil ifTrue: [
+ "Skip search when none packages are selected.
+ The algorithm would iterate through all classes so this is an optimization."
+ ^ self
+ ].
+
+ methodSearcher := self methodSearcher.
+
+ model allClassesDo: [ :class |
+ "Including only non metaclasses, because we use instAndClassMethodsDo:
+ and allClassesDo: have different implementations."
+ class isMeta ifFalse: [
+ class instAndClassMethodsDo: [ :method |
+ (packages includes: method package) ifTrue: [
+ methodSearcher search: searchPattern inMethod: method withResultDo: aBlock
+ ]
+ ]
+ ]
+ ]
+
+ "Created: / 01-11-2014 / 17:28:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 20:59:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ProtocolSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+ "Returns true when perspective is desired type.
+ We need to limit the searching with respect to perspective,
+ because we need to search for example only in classes when we are in the class perspective
+ (the list of classes in the IDE - Tools::NewSystemBrowser)."
+
+ ^ aCustomPerspective isProtocolPerspective
+
+ "Created: / 29-10-2014 / 22:51:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ProtocolSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+ "Executes search on each method in selected protocols within selected classes.
+ see search:inMethod:withResultDo:"
+ | methodSearcher |
+
+ methodSearcher := self methodSearcher.
+
+ aCustomContext selectedClasses ? #() do:[ :class |
+ aCustomContext selectedProtocols ? #() do:[ :protocol |
+ class methodsDo:[ :method |
+ (protocol = (method category)) ifTrue:[
+ methodSearcher search: searchPattern inMethod: method withResultDo: aBlock
+ ]
+ ]
+ ]
+ ]
+
+ "Created: / 29-10-2014 / 19:16:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 20:59:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoryBuilderTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,1923 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomRefactoryBuilderTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRefactoryBuilderTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomRefactoryBuilderTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+ ^ nil
+
+ "Created: / 24-08-2014 / 21:35:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilderTests methodsFor:'tests'!
+
+test_available_in_perspective_class_category
+ | perspective |
+
+ perspective := CustomPerspective classCategoryPerspective.
+
+ self assert: (refactoryBuilder classCategorySearcher class availableInPerspective:perspective)
+
+ "Modified: / 05-11-2014 / 20:20:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_class_searcher
+ | perspective |
+
+ perspective := CustomPerspective classPerspective.
+
+ self assert: (refactoryBuilder classSearcher class availableInPerspective:perspective)
+
+ "Modified: / 05-11-2014 / 20:21:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_code_selection_searcher
+ | perspective |
+
+ perspective := CustomPerspective codeViewPerspective.
+
+ self assert: (refactoryBuilder codeSelectionSearcher class availableInPerspective:perspective)
+
+ "Modified: / 05-11-2014 / 20:21:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_method_searcher
+ | perspective |
+
+ perspective := CustomPerspective methodPerspective.
+
+ self assert: (refactoryBuilder methodSearcher class availableInPerspective:perspective)
+
+ "Modified: / 05-11-2014 / 20:21:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_package_searcher
+ | perspective |
+
+ perspective := CustomPerspective packagePerspective.
+
+ self assert: (refactoryBuilder packageSearcher class availableInPerspective:perspective)
+
+ "Modified: / 05-11-2014 / 20:21:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_protocols
+ | perspective |
+
+ perspective := CustomPerspective protocolPerspective.
+
+ self assert: (refactoryBuilder protocolSearcher class availableInPerspective:perspective)
+
+ "Modified: / 05-11-2014 / 20:21:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_category_of_to_model_class
+ | expectedCategory actualCategory class |
+
+ class := model createClass
+ name: #DummyClassForTestCase01;
+ category: 'Category01';
+ compile;
+ yourself.
+
+ expectedCategory := 'Category02'.
+
+ refactoryBuilder changeCategoryOf: class to: 'Category02'.
+
+ actualCategory := class category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 08-11-2014 / 13:46:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_category_of_to_model_class_execute
+ | expectedCategory actualCategory class |
+
+ class := model createClass
+ name: #DummyClassForTestCase01;
+ category: 'Category01';
+ compile;
+ yourself.
+
+ expectedCategory := 'Category02'.
+
+ refactoryBuilder changeCategoryOf: class to: 'Category02'; execute.
+
+ actualCategory := (Smalltalk at: #DummyClassForTestCase01) category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 08-11-2014 / 14:10:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 17:43:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_category_of_to_real_class
+ | expectedCategory actualCategory class |
+
+ class := model createClassImmediate: #DummyClassForTestCase01 category: 'Category01'.
+
+ expectedCategory := 'Category02'.
+
+ refactoryBuilder changeCategoryOf: class to: 'Category02'; execute.
+
+ actualCategory := class category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Modified: / 08-11-2014 / 13:45:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_replace_with_in_code_selection_01
+
+ |originalSource expectedSource actualSource codeSelection|
+
+ originalSource := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ expectedSource := 'selector
+ self information: (resources string:''Translate this'').
+ ^ self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: originalSource;
+ selectedInterval: (32 to: 47);
+ selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring). "/ just some method
+
+ refactoryBuilder executeReplace: '`@code'
+ with: '(resources string: `@code)'
+ inCodeSelection: codeSelection.
+
+ refactoryBuilder model changes do: [ :change |
+ actualSource := change source
+ ].
+
+ self assertSource: expectedSource sameAs: actualSource.
+
+ "Created: / 25-08-2014 / 21:53:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 09-12-2014 / 22:22:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_replace_with_in_code_selection_02
+
+ |originalSource expectedSource actualSource codeSelection|
+
+ originalSource := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ expectedSource := 'selector
+ resources string:(self information:''Translate this'').
+ ^ self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: originalSource;
+ selectedInterval: (14 to: 47);
+ selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring). "/ just some method
+
+ refactoryBuilder executeReplace: '`@code'
+ with: '(resources string: `@code)'
+ inCodeSelection: codeSelection.
+
+ refactoryBuilder model changes do: [ :change |
+ actualSource := change source
+ ].
+
+ self assertSource: expectedSource sameAs: actualSource.
+
+ "Created: / 26-08-2014 / 22:37:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 17:52:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_replace_with_in_code_selection_03
+
+ |originalSource expectedSource actualSource codeSelection|
+
+ originalSource := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ expectedSource := 'selector
+ self information: ''Translate this''.
+ ^ resources string:self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: originalSource;
+ selectedInterval: (55 to: 59);
+ selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring). "/ just some method
+
+ refactoryBuilder executeReplace: '`@code'
+ with: '(resources string: `@code)'
+ inCodeSelection: codeSelection.
+
+ refactoryBuilder model changes do: [ :change |
+ actualSource := change source
+ ].
+
+ self assertSource: expectedSource sameAs: actualSource.
+
+ "Created: / 26-08-2014 / 22:41:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-12-2014 / 20:07:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_replace_with_in_code_selection_04
+
+ |originalSource expectedSource actualSource codeSelection|
+
+ originalSource := 'selector
+ | temp |
+
+ temp := ''Translate this''.
+
+ self information: temp.
+ ^ self.'.
+
+ expectedSource := 'selector
+ | temp |
+
+ temp := ''Translate this''.
+
+ self information: (resources string:temp).
+ ^ self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: originalSource;
+ selectedInterval: (77 to: 81);
+ selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring). "/ just some method
+
+ refactoryBuilder executeReplace: '`@code'
+ with: '(resources string: `@code)'
+ inCodeSelection: codeSelection.
+
+ refactoryBuilder model changes do: [ :change |
+ actualSource := change source
+ ].
+
+ self assertSource: expectedSource sameAs: actualSource.
+
+ "Created: / 26-08-2014 / 22:52:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-12-2014 / 20:08:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_initialize_change_for_add_class
+ "/ something initializeChange:aChangeClass.
+ | change |
+
+ change := refactoryBuilder initializeChange: AddClassChange.
+
+ self assert: (change class) == AddClassChange.
+ self assert: (change model) == (refactoryBuilder model)
+
+ "Modified: / 08-11-2014 / 16:12:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_class_with_result_do_class_with_methods
+ | class expectedResult actualResult |
+
+ class := model createClassImmediate: 'DummyClassForTestCase'.
+ model createMethodImmediate: class source: 'selector_01 ^ 1'.
+ model createMethodImmediate: class class source: 'selector_02 ^ 2'.
+
+ expectedResult := OrderedCollection new
+ add: (class compiledMethodAt: #selector_01);
+ add: (class class compiledMethodAt: #selector_02);
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder classSearcher search: '`@something' inClass: class withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection selectedMethod
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 19-10-2014 / 16:56:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-11-2014 / 22:15:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_class_with_result_do_empty_class
+ | class expectedResult actualResult |
+
+ class := model createClassImmediate: 'DummyClassForTestCase'.
+
+ expectedResult := OrderedCollection new.
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder classSearcher search: '`@something' inClass: class withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Modified: / 04-11-2014 / 22:19:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_class_with_result_do_model_class_with_methods
+ | class expectedResult actualResult |
+
+ class := model createClass
+ name: #DummyClassForTestCase;
+ compile;
+ yourself.
+ class compile: 'selector_01 ^ 1' classified: 'some protocol'.
+ class theMetaclass compile: 'selector_02 ^ 2' classified: 'some protocol'.
+
+ expectedResult := OrderedCollection new
+ add: (class compiledMethodAt: #selector_01);
+ add: (class theMetaclass compiledMethodAt: #selector_02);
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder classSearcher search: '`@something' inClass: class withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection selectedMethod
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 19-10-2014 / 17:24:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-11-2014 / 22:19:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_different_with_class
+ | category01 class01 category02 class02 modelClass expectedResult actualResult |
+
+ category01 := 'Some-Non-Existing-Category01'.
+ category02 := 'Some-Non-Existing-Category02'.
+
+ class01 := model createClassImmediate: 'DummyClassForTestCase01' category: category01.
+ model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+ model createMethodImmediate: class01 class source: 'selector_02 ^ 2'.
+
+ class02 := model createClassImmediate: 'DummyClassForTestCase02' category: category02.
+ model createMethodImmediate: class02 source: 'selector_01X ^ 101'.
+ model createMethodImmediate: class02 class source: 'selector_02X ^ 202'.
+
+ modelClass := model classFor: class01.
+
+ expectedResult := OrderedCollection new
+ add: (modelClass compiledMethodAt: #selector_01) selector;
+ add: (modelClass theMetaclass compiledMethodAt: #selector_02) selector;
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ context selectedClassCategories: (Array with: category01).
+
+ refactoryBuilder classCategorySearcher search: '`@something' inContext: context withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 21:27:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_empty_context
+ | expectedResult actualResult |
+
+ expectedResult := OrderedCollection new.
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder classCategorySearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Modified (comment): / 04-11-2014 / 20:50:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_empty_with_model_classes
+ | expectedResult actualResult class01 |
+
+ class01 := model createClass
+ name: #DummyClass01;
+ category: 'Some-Category01';
+ compile;
+ compile: 'selector_01 ^ 1';
+ compile: 'selector_02 ^ 2';
+ yourself.
+
+ model createClass
+ name: #DummyClass02;
+ category: 'Some-Category02';
+ compile;
+ compile: 'selector_03 ^ 3'.
+
+ model createClass
+ name: #DummyClass03;
+ compile;
+ compile: 'selector_04 ^ 4'.
+
+ context selectedClassCategories: (Array with:'Some-Category01').
+
+ expectedResult := OrderedCollection new
+ add: (class01 compiledMethodAt:#selector_01);
+ add: (class01 compiledMethodAt:#selector_02);
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder classCategorySearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedMethod
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 05-11-2014 / 21:21:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:19:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_model_classes
+ | expectedResult actualResult class01 class03 |
+
+ class01 := model createClass
+ name: #DummyClass01;
+ category: 'Some-Category01';
+ compile;
+ compile: 'selector_01 ^ 1';
+ compile: 'selector_02 ^ 2';
+ yourself.
+
+ model createClass
+ name: #DummyClass02;
+ category: 'Some-Category02';
+ compile;
+ compile: 'selector_03 ^ 3'.
+
+ class03 := model createClass
+ name: #DummyClass03;
+ category: 'Some-Category03';
+ compile;
+ compile: 'selector_04 ^ 4';
+ yourself.
+
+ context selectedClassCategories: (Array with:'Some-Category01' with:'Some-Category03').
+
+ expectedResult := OrderedCollection new
+ add: (class03 compiledMethodAt:#selector_04);
+ add: (class01 compiledMethodAt:#selector_01);
+ add: (class01 compiledMethodAt:#selector_02);
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder classCategorySearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedMethod
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 21:03:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:15:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_real_category
+ | actualResult |
+
+ actualResult := OrderedCollection new.
+
+ context selectedClassCategories: (Array with: self class category).
+
+ refactoryBuilder classCategorySearcher search: '`@something' inContext: context withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: actualResult size notEmptyOrNil
+
+ "Created: / 04-11-2014 / 21:18:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:03:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_with_class
+ | category class modelClass expectedResult actualResult |
+
+ category := 'Some-Non-Existing-Category01'.
+ class := model createClassImmediate: 'DummyClassForTestCase' category: category.
+ model createMethodImmediate: class source: 'selector_01 ^ 1'.
+ model createMethodImmediate: class class source: 'selector_02 ^ 2'.
+
+ modelClass := model classFor: class.
+ self assert: modelClass == (model classFor: class).
+
+ expectedResult := OrderedCollection new
+ add: (modelClass compiledMethodAt: #selector_01) selector;
+ add: (modelClass theMetaclass compiledMethodAt: #selector_02) selector;
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ context selectedClassCategories: (Array with: category).
+
+ refactoryBuilder classCategorySearcher search: '`@something' inContext: context withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 21:32:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_classes
+ | class01 class02 modelClass01 modelClass02 expectedResult actualResult |
+
+ class01 := model createClassImmediate: 'DummyClassForTestCase01'.
+ model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+ model createMethodImmediate: class01 class source: 'selector_02 ^ 2'.
+
+ class02 := model createClassImmediate: 'DummyClassForTestCase02'.
+ model createMethodImmediate: class02 source: 'selector_01X ^ 101'.
+ model createMethodImmediate: class02 class source: 'selector_02X ^ 202'.
+
+ modelClass01 := model classFor: class01.
+ modelClass02 := model classFor: class02.
+
+ expectedResult := OrderedCollection new
+ add: (modelClass01 compiledMethodAt: #selector_01) selector;
+ add: (modelClass01 theMetaclass compiledMethodAt: #selector_02) selector;
+ add: (modelClass02 compiledMethodAt: #selector_01X) selector;
+ add: (modelClass02 theMetaclass compiledMethodAt: #selector_02X) selector;
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ context selectedClasses:(Array with: class01 with: class02).
+
+ refactoryBuilder classSearcher search:'`@something' inContext:context withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 21:59:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_classes_empty_context
+ | expectedResult actualResult |
+
+ actualResult := OrderedCollection new.
+ expectedResult := OrderedCollection new.
+
+ refactoryBuilder classSearcher search:'`@something' inContext:context withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 22:06:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_empty_browser_context
+ | browserContext expectedResult actualResult |
+
+ browserContext := CustomBrowserContext
+ perspective: CustomPerspective new
+ state: Tools::NavigationState new.
+
+ expectedResult := OrderedCollection new.
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder search:'`@something' inContext:browserContext withResultDo:[ :method |
+ actualResult add: method selector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Modified (format): / 25-10-2014 / 21:00:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_empty_code_selection
+ | expectedResult actualResult |
+
+ context selectedCodes: {CustomSourceCodeSelection new}.
+
+ expectedResult := OrderedCollection new.
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder codeSelectionSearcher search:'`@something' inContext:context withResultDo:[ :method |
+ actualResult add: method selector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Modified: / 04-01-2015 / 16:13:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_empty_sub_context
+ | expectedResult actualResult |
+
+ expectedResult := OrderedCollection new.
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder search:'`@something' inContext:context withResultDo:[ :method |
+ actualResult add: method selector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 25-10-2014 / 21:01:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 19:08:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_browser_context_with_class_category_perspective
+ | expectedResult actualResult class02 class03 method03
+ codeSelection class04 class05 method05 class06 |
+
+ model createClass
+ name: #DummyClassForTestCase01;
+ category: 'Some-Test-Category01';
+ compile;
+ compile: 'selector_01 ^ 1'.
+
+ class02 := model createClass
+ name: #DummyClassForTestCase02;
+ compile;
+ compile: 'selector_02 ^ 2';
+ yourself.
+
+ class03 := model createClass
+ name: #DummyClassForTestCase03;
+ compile;
+ yourself.
+
+ method03 := model createMethod
+ class: class03;
+ source: 'selector_03 ^ self';
+ compile;
+ yourself.
+
+ self assert: #selector_03 = (method03 selector).
+
+ codeSelection := CustomSourceCodeSelection new
+ selectedMethod: method03;
+ selectedInterval: (15 to: 18);
+ yourself.
+
+ self assert: 'self' = (codeSelection selectedSourceCode).
+
+ class04 := model createClass
+ name: #DummyClassForTestCase04;
+ compile;
+ compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+ yourself.
+
+ class05 := model createClass
+ name: #DummyClassForTestCase05;
+ compile;
+ yourself.
+
+ method05 := model createMethod
+ class: class05;
+ source: 'selector_05 ^ 5';
+ compile;
+ yourself.
+
+ class06 := model createClass
+ name: #DummyClassForTestCase06;
+ compile;
+ yourself.
+
+ model createMethod
+ class: class06;
+ source: 'selector_06 ^ 6';
+ package: #some_package01;
+ compile.
+
+ context := mock mockOf: CustomSubContext.
+ context
+ compileMockMethod: 'perspective ^ CustomPerspective classCategoryPerspective';
+ selectedClassCategories: (Array with: 'Some-Test-Category01');
+ selectedClasses: (Array with: class02 with: class04);
+ selectedCodes: (Array with: codeSelection);
+ selectedProtocols: (Array with: 'method protocol 01');
+ selectedMethods: (Array with: method05);
+ selectedPackages: (Array with: #some_package01).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ | selector |
+
+ selector := sourceSelection selectedSelector.
+ self assert: selector notNil.
+
+ actualResult add: selector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 05-11-2014 / 22:04:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:15:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_browser_context_with_class_perspective
+ | expectedResult actualResult class02 class03 method03
+ codeSelection class04 class05 method05 class06 |
+
+ model createClass
+ name: #DummyClassForTestCase01;
+ category: 'Some-Test-Category01';
+ compile;
+ compile: 'selector_01 ^ 1'.
+
+ class02 := model createClass
+ name: #DummyClassForTestCase02;
+ compile;
+ compile: 'selector_02 ^ 2';
+ yourself.
+
+ class03 := model createClass
+ name: #DummyClassForTestCase03;
+ compile;
+ yourself.
+
+ method03 := model createMethod
+ class: class03;
+ source: 'selector_03 ^ self';
+ compile;
+ yourself.
+
+ self assert: #selector_03 = (method03 selector).
+
+ codeSelection := CustomSourceCodeSelection new
+ selectedMethod: method03;
+ selectedInterval: (15 to: 18);
+ yourself.
+
+ self assert: 'self' = (codeSelection selectedSourceCode).
+
+ class04 := model createClass
+ name: #DummyClassForTestCase04;
+ compile;
+ compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+ yourself.
+
+ class05 := model createClass
+ name: #DummyClassForTestCase05;
+ compile;
+ yourself.
+
+ method05 := model createMethod
+ class: class05;
+ source: 'selector_05 ^ 5';
+ compile;
+ yourself.
+
+ class06 := model createClass
+ name: #DummyClassForTestCase06;
+ compile;
+ yourself.
+
+ model createMethod
+ class: class06;
+ source: 'selector_06 ^ 6';
+ package: #some_package01;
+ compile.
+
+ context := mock mockOf: CustomSubContext.
+ context
+ compileMockMethod: 'perspective ^ CustomPerspective classPerspective';
+ selectedClassCategories: (Array with: 'Some-Test-Category01');
+ selectedClasses: (Array with: class02 with: class04);
+ selectedCodes: (Array with: codeSelection);
+ selectedProtocols: (Array with: 'method protocol 01');
+ selectedMethods: (Array with: method05);
+ selectedPackages: (Array with: #some_package01).
+
+ expectedResult := OrderedCollection new
+ add: #selector_02;
+ add: #selector_04;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ | selector |
+
+ selector := sourceSelection selectedSelector.
+ self assert: selector notNil.
+
+ actualResult add: selector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 05-11-2014 / 22:02:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:15:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_browser_context_with_package_perspective
+ | expectedResult actualResult class02 class03 method03
+ codeSelection class04 class05 method05 class06 |
+
+ model createClass
+ name: #DummyClassForTestCase01;
+ category: 'Some-Test-Category01';
+ compile;
+ compile: 'selector_01 ^ 1'.
+
+ class02 := model createClass
+ name: #DummyClassForTestCase02;
+ compile;
+ compile: 'selector_02 ^ 2';
+ yourself.
+
+ class03 := model createClass
+ name: #DummyClassForTestCase03;
+ compile;
+ yourself.
+
+ method03 := model createMethod
+ class: class03;
+ source: 'selector_03 ^ self';
+ compile;
+ yourself.
+
+ self assert: #selector_03 = (method03 selector).
+
+ codeSelection := CustomSourceCodeSelection new
+ selectedMethod: method03;
+ selectedInterval: (15 to: 18);
+ yourself.
+
+ self assert: 'self' = (codeSelection selectedSourceCode).
+
+ class04 := model createClass
+ name: #DummyClassForTestCase04;
+ compile;
+ compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+ yourself.
+
+ class05 := model createClass
+ name: #DummyClassForTestCase05;
+ compile;
+ yourself.
+
+ method05 := model createMethod
+ class: class05;
+ source: 'selector_05 ^ 5';
+ compile;
+ yourself.
+
+ class06 := model createClass
+ name: #DummyClassForTestCase06;
+ compile;
+ yourself.
+
+ model createMethod
+ class: class06;
+ source: 'selector_06 ^ 6';
+ package: #some_package01;
+ compile.
+
+ context := mock mockOf: CustomSubContext.
+ context
+ compileMockMethod: 'perspective ^ CustomPerspective packagePerspective';
+ selectedClassCategories: (Array with: 'Some-Test-Category01');
+ selectedClasses: (Array with: class02 with: class04);
+ selectedCodes: (Array with: codeSelection);
+ selectedProtocols: (Array with: 'method protocol 01');
+ selectedMethods: (Array with: method05);
+ selectedPackages: (Array with: #some_package01).
+
+ expectedResult := OrderedCollection new
+ add: #selector_06;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ | selector |
+
+ selector := sourceSelection selectedSelector.
+ self assert: selector notNil.
+
+ actualResult add: selector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 05-11-2014 / 22:06:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:15:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_browser_context_with_protocol_perspective
+ | expectedResult actualResult class02 class03 method03
+ codeSelection class04 class05 method05 class06 |
+
+ model createClass
+ name: #DummyClassForTestCase01;
+ category: 'Some-Test-Category01';
+ compile;
+ compile: 'selector_01 ^ 1'.
+
+ class02 := model createClass
+ name: #DummyClassForTestCase02;
+ compile;
+ compile: 'selector_02 ^ 2';
+ yourself.
+
+ class03 := model createClass
+ name: #DummyClassForTestCase03;
+ compile;
+ yourself.
+
+ method03 := model createMethod
+ class: class03;
+ source: 'selector_03 ^ self';
+ compile;
+ yourself.
+
+ self assert: #selector_03 = (method03 selector).
+
+ codeSelection := CustomSourceCodeSelection new
+ selectedMethod: method03;
+ selectedInterval: (15 to: 18);
+ yourself.
+
+ self assert: 'self' = (codeSelection selectedSourceCode).
+
+ class04 := model createClass
+ name: #DummyClassForTestCase04;
+ compile;
+ compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+ yourself.
+
+ class05 := model createClass
+ name: #DummyClassForTestCase05;
+ compile;
+ yourself.
+
+ method05 := model createMethod
+ class: class05;
+ source: 'selector_05 ^ 5';
+ compile;
+ yourself.
+
+ class06 := model createClass
+ name: #DummyClassForTestCase06;
+ compile;
+ yourself.
+
+ model createMethod
+ class: class06;
+ source: 'selector_06 ^ 6';
+ package: #some_package01;
+ compile.
+
+ context := mock mockOf: CustomSubContext.
+ context
+ compileMockMethod: 'perspective ^ CustomPerspective protocolPerspective';
+ selectedClassCategories: (Array with: 'Some-Test-Category01');
+ selectedClasses: (Array with: class02 with: class04);
+ selectedCodes: (Array with: codeSelection);
+ selectedProtocols: (Array with: 'method protocol 01');
+ selectedMethods: (Array with: method05);
+ selectedPackages: (Array with: #some_package01).
+
+ expectedResult := OrderedCollection new
+ add: #selector_04;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ | selector |
+
+ selector := sourceSelection selectedSelector.
+ self assert: selector notNil.
+
+ actualResult add: selector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 05-11-2014 / 22:05:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:15:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_sub_context
+ | expectedResult actualResult class01 class02 class03 method03
+ codeSelection class04 class05 method05 class06 |
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01 category: 'Some-Test-Category01'.
+ model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+
+ class02 := model createClassImmediate: #DummyClassForTestCase02.
+ model createMethodImmediate: class02 source: 'selector_02 ^ 2'.
+
+ class03 := model createClassImmediate: #DummyClassForTestCase03.
+ method03 := model createMethodImmediate: class03 source: 'selector_03 ^ self'.
+ self assert: #selector_03 = (method03 selector).
+
+ codeSelection := CustomSourceCodeSelection new
+ selectedMethod: method03;
+ selectedInterval: (15 to: 18);
+ yourself.
+
+ self assert: 'self' = (codeSelection selectedSourceCode).
+
+ class04 := model createClassImmediate: #DummyClassForTestCase04.
+ model createMethodImmediate: class04 protocol: 'method protocol 01' source: 'selector_04 ^ 4'.
+
+ class05 := model createClassImmediate: #DummyClassForTestCase05.
+ method05 := model createMethodImmediate: class05 source: 'selector_05 ^ 5'.
+
+ class06 := model createClassImmediate: #DummyClassForTestCase06.
+ (model createMethodImmediate: class06 source: 'selector_06 ^ 6')
+ package: #some_package01.
+
+ context
+ selectedClassCategories: (Array with: 'Some-Test-Category01');
+ selectedClasses: (Array with: class02 with: class04);
+ selectedCodes: (Array with: codeSelection);
+ selectedProtocols: (Array with: 'method protocol 01');
+ selectedMethods: (Array with: method05);
+ selectedPackages: (Array with: #some_package01).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #selector_02;
+ add: #selector_03;
+ add: #selector_04;
+ add: #selector_04;
+ add: #selector_05;
+ add: #selector_06;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ | selector |
+
+ selector := sourceSelection selectedSelector.
+ self assert: selector notNil.
+
+ actualResult add: selector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 25-10-2014 / 21:05:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 21:02:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_sub_context_model_classes
+ | expectedResult actualResult class02 class03 method03
+ codeSelection class04 class05 method05 class06 |
+
+ model createClass
+ name: #DummyClassForTestCase01;
+ category: 'Some-Test-Category01';
+ compile;
+ compile: 'selector_01 ^ 1'.
+
+ class02 := model createClass
+ name: #DummyClassForTestCase02;
+ compile;
+ compile: 'selector_02 ^ 2';
+ yourself.
+
+ class03 := model createClass
+ name: #DummyClassForTestCase03;
+ compile;
+ yourself.
+
+ method03 := model createMethod
+ class: class03;
+ source: 'selector_03 ^ self';
+ compile;
+ yourself.
+
+ self assert: #selector_03 = (method03 selector).
+
+ codeSelection := CustomSourceCodeSelection new
+ selectedMethod: method03;
+ selectedInterval: (15 to: 18);
+ yourself.
+
+ self assert: 'self' = (codeSelection selectedSourceCode).
+
+ class04 := model createClass
+ name: #DummyClassForTestCase04;
+ compile;
+ compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+ yourself.
+
+ class05 := model createClass
+ name: #DummyClassForTestCase05;
+ compile;
+ yourself.
+
+ method05 := model createMethod
+ class: class05;
+ source: 'selector_05 ^ 5';
+ compile;
+ yourself.
+
+ class06 := model createClass
+ name: #DummyClassForTestCase06;
+ compile;
+ yourself.
+
+ model createMethod
+ class: class06;
+ source: 'selector_06 ^ 6';
+ package: #some_package01;
+ compile.
+
+ context
+ selectedClassCategories: (Array with: 'Some-Test-Category01');
+ selectedClasses: (Array with: class02 with: class04);
+ selectedCodes: (Array with: codeSelection);
+ selectedProtocols: (Array with: 'method protocol 01');
+ selectedMethods: (Array with: method05);
+ selectedPackages: (Array with: #some_package01).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #selector_02;
+ add: #selector_03;
+ add: #selector_04;
+ add: #selector_04;
+ add: #selector_05;
+ add: #selector_06;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ | selector |
+
+ selector := sourceSelection selectedSelector.
+ self assert: selector notNil.
+
+ actualResult add: selector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 05-11-2014 / 21:11:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:16:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_methods_01
+ | expectedResult actualResult class01 method |
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01.
+ method := model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+
+ context selectedMethods:(Array with:method).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder methodSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 22:55:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_methods_02
+ | expectedResult actualResult class01 method01 method02 |
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01.
+ method01 := model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+ method02 := self class compiledMethodAt:#test_search_in_context_with_result_do_methods_02.
+
+ context selectedMethods:(Array with:method01 with:method02).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #test_search_in_context_with_result_do_methods_02;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder methodSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 22:59:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_methods_03
+ | expectedResult actualResult class01 method01 method02 |
+
+ class01 := model createClass
+ name: #DummyClassForTestCase01;
+ compile;
+ compile: 'selector_01 ^ 1';
+ yourself.
+
+ method01 := class01 compiledMethodAt:#selector_01.
+ method02 := model createMethod
+ class: class01;
+ source: 'selector_02 ^ 2';
+ compile;
+ yourself.
+
+ context selectedMethods:(Array with:method01 with:method02).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #selector_02;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder methodSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 23:05:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_methods_empty_context
+ | expectedResult actualResult |
+
+ actualResult := OrderedCollection new.
+ expectedResult := OrderedCollection new.
+
+ refactoryBuilder methodSearcher search: '`@something' inContext: context withResultDo: [ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 22:52:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_packages_01
+ | expectedResult actualResult class01 method |
+
+ class01 := (model createClassImmediate: #DummyClassForTestCase01)
+ package: #some_package01;
+ yourself.
+
+ method := model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+ method package: #some_package01.
+
+ context
+ selectedPackages:(Array with:#some_package01).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder packageSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 01-11-2014 / 20:14:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 02-11-2014 / 13:31:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_packages_02
+ |expectedResult actualResult class01 method01 method03 method04 method05 class02 method07 method08|
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01.
+ method01 := model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+ method01 package: #some_package01.
+ model createMethodImmediate: class01 source: 'selector_02 ^ 2'.
+ method03 := model createMethodImmediate: class01 source: 'selector_03 ^ 3'.
+ method03 package: #some_package03.
+ method04 := model createMethodImmediate: class01 class source: 'selector_04 ^ 4'.
+ method04 package: #some_package02.
+ method05 := model createMethodImmediate: class01 source: 'selector_05 ^ 5'.
+ method05 package: #some_package01.
+
+ class02 := model createClassImmediate: #DummyClassForTestCase02.
+ model createMethodImmediate: class02 class source: 'selector_06 ^ 6'.
+ method07 := model createMethodImmediate: class02 class source: 'selector_07 ^ 7'.
+ method07 package: #some_package02.
+ method08 := model createMethodImmediate: class02 class source: 'selector_08 ^ 8'.
+ method08 package: #some_package03.
+
+ context
+ selectedPackages:(Array with:#some_package01 with:#some_package02).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #selector_04;
+ add: #selector_05;
+ add: #selector_07;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder packageSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 02-11-2014 / 11:58:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:53:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_packages_03
+ |expectedResult actualResult class01 class02|
+
+ class01 := model createClass
+ name: #DummyClassForTestCase01;
+ compile;
+ yourself.
+
+ model createMethod class: class01; source: 'selector_01 ^ 1'; package: #some_package01; compile.
+ model createMethod class: class01; source: 'selector_02 ^ 2'; compile.
+ model createMethod class: class01; source: 'selector_03 ^ 3'; package: #some_package03; compile.
+ model createMethod class: class01 theMetaclass; source: 'selector_04 ^ 4'; package: #some_package02; compile.
+ model createMethod class: class01; source: 'selector_05 ^ 5'; package: #some_package01; compile.
+
+ class02 := model createClass
+ name: #DummyClassForTestCase02;
+ compile;
+ yourself.
+
+ model createMethod class: class02 theMetaclass; source: 'selector_06 ^ 6'; compile.
+ model createMethod class: class02 theMetaclass; source: 'selector_07 ^ 7'; package: #some_package02; compile.
+ model createMethod class: class02 theMetaclass; source: 'selector_08 ^ 8'; package: #some_package03; compile.
+ model createMethod class: class02; source: 'selector_09 ^ 9'; package: #some_package01; compile.
+
+ context
+ selectedPackages:(Array with:#some_package01 with:#some_package02).
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #selector_04;
+ add: #selector_05;
+ add: #selector_07;
+ add: #selector_09;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder packageSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 02-11-2014 / 16:52:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-11-2014 / 01:12:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_packages_empty_context
+ | expectedResult actualResult |
+
+ expectedResult := OrderedCollection new.
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder packageSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 02-11-2014 / 11:57:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_01
+ | expectedResult actualResult class01 |
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01.
+ model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+
+ context
+ selectedClasses:(Array with:class01);
+ selectedProtocols:(Array with:'method protocol 01').
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Modified: / 01-11-2014 / 16:28:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_02
+ | expectedResult actualResult class01 |
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01.
+ model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+ model createMethodImmediate: class01 protocol: 'method protocol 02' source: 'selector_02 ^ 2' .
+ model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_03 ^ 3' .
+
+ context
+ selectedClasses:(Array with:class01);
+ selectedProtocols:(Array with:'method protocol 01').
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #selector_03;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 01-11-2014 / 16:29:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_03
+ | expectedResult actualResult class01 class02 |
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01.
+ model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+ model createMethodImmediate: class01 protocol: 'method protocol 02' source: 'selector_02 ^ 2' .
+ model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_03 ^ 3' .
+
+ class02 := model createClassImmediate: #DummyClassForTestCase02.
+ model createMethodImmediate: class02 protocol: 'method protocol 02' source: 'selector_04 ^ 4' .
+
+ context
+ selectedClasses:(Array with:class01 with:class02);
+ selectedProtocols:(Array with:'method protocol 01').
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #selector_03;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 01-11-2014 / 16:34:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_04
+ | expectedResult actualResult class01 class02 |
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01.
+ model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+ model createMethodImmediate: class01 protocol: 'method protocol 02' source: 'selector_02 ^ 2' .
+ model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_03 ^ 3' .
+
+ class02 := model createClassImmediate: #DummyClassForTestCase02.
+ model createMethodImmediate: class02 protocol: 'method protocol 02' source: 'selector_04 ^ 4' .
+ model createMethodImmediate: class02 protocol: 'method protocol 01' source: 'selector_05 ^ 5' .
+
+ context
+ selectedClasses:(Array with:class01 with:class02);
+ selectedProtocols:(Array with:'method protocol 01').
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ add: #selector_03;
+ add: #selector_05;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 01-11-2014 / 16:36:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_empty_classes
+ | expectedResult actualResult class01 |
+
+ class01 := model createClassImmediate: #DummyClassForTestCase01.
+ model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+
+ context
+ selectedProtocols:(Array with:'method protocol 01').
+
+ expectedResult := OrderedCollection new
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 01-11-2014 / 17:07:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_empty_context
+ | expectedResult actualResult |
+
+ expectedResult := OrderedCollection new
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 01-11-2014 / 17:08:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_model_classes
+ | expectedResult actualResult class01 |
+
+ class01 := model createClass
+ name: #DummyClassForTestCase01;
+ compile;
+ compile: 'selector_01 ^ 1' classified: 'method protocol 01';
+ yourself.
+
+ context
+ selectedClasses:(Array with:class01);
+ selectedProtocols:(Array with:'method protocol 01').
+
+ expectedResult := OrderedCollection new
+ add: #selector_01;
+ asSortedCollection.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ actualResult := actualResult asSortedCollection.
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 01-11-2014 / 16:41:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_01
+ |source codeSelection resultsFoundCount |
+
+ source := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: source;
+ selectedInterval: (32 to: 47).
+
+ resultsFoundCount := 0.
+
+ context selectedCodes: (Array with: codeSelection).
+
+ refactoryBuilder codeSelectionSearcher search: '`@code'
+ inContext: context
+ withResultDo: [ :codeSelection |
+ resultsFoundCount := resultsFoundCount + 1
+ ].
+
+ self assert: resultsFoundCount = 1.
+
+ "Created: / 04-11-2014 / 23:27:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 18:40:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_02
+ |source codeSelection resultsFoundCount |
+
+ source := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: source;
+ selectedInterval: (32 to: 47).
+
+ resultsFoundCount := 0.
+
+ context selectedCodes: (Array with: codeSelection).
+
+ refactoryBuilder codeSelectionSearcher search: '`#literal'
+ inContext: context
+ withResultDo: [ :codeSelection |
+ resultsFoundCount := resultsFoundCount + 1
+ ].
+
+ self assert: resultsFoundCount = 1.
+
+ "Created: / 04-11-2014 / 23:28:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 18:41:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_03
+ |source codeSelection resultsFoundCount |
+
+ source := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: source;
+ selectedInterval: (1 to: source size).
+
+ resultsFoundCount := 0.
+
+ context selectedCodes: (Array with: codeSelection).
+
+ refactoryBuilder codeSelectionSearcher search: '`#literal'
+ inContext: context
+ withResultDo: [ :codeSelection |
+ resultsFoundCount := resultsFoundCount + 1
+ ].
+
+ self assert: resultsFoundCount = 1.
+
+ "Created: / 04-11-2014 / 23:28:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 18:37:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_04
+ |source codeSelection resultsFoundCount |
+
+ source := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: source;
+ selectedInterval: (14 to: 51).
+
+ resultsFoundCount := 0.
+
+ context selectedCodes: (Array with: codeSelection).
+
+ refactoryBuilder codeSelectionSearcher search: '`@code'
+ inContext: context
+ withResultDo: [ :codeSelection |
+ resultsFoundCount := resultsFoundCount + 1
+ ].
+
+ self assert: resultsFoundCount = 1.
+
+ "Created: / 04-11-2014 / 23:28:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_05
+ |source codeSelection resultsFoundCount |
+
+ source := 'selector
+ self information: ''Translate this''.
+ ^ self.'.
+
+ codeSelection := CustomSourceCodeSelection new.
+ codeSelection
+ currentSourceCode: source;
+ selectedInterval: (30 to: 38).
+
+ resultsFoundCount := 0.
+
+ context selectedCodes: (Array with: codeSelection).
+
+ self should: [
+ refactoryBuilder codeSelectionSearcher search: '`@code'
+ inContext: context
+ withResultDo: [ :codeSelection |
+ resultsFoundCount := resultsFoundCount + 1
+ ].
+ ] raise: Error.
+
+ "Created: / 04-11-2014 / 23:29:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_empty_context
+ | expectedResult actualResult |
+
+ expectedResult := OrderedCollection new.
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder codeSelectionSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedSelector
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Modified: / 04-11-2014 / 23:26:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_method_with_result_do_model_method_01
+ |expectedResult actualResult method|
+
+ method := model createMethod
+ source:'selector_01 ^ 1';
+ yourself.
+
+ expectedResult := OrderedCollection new
+ add:method;
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder methodSearcher search:'`@something' inMethod:method withResultDo:[ :sourceSelection |
+ actualResult add:sourceSelection selectedMethod
+ ].
+
+ self assert:expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 23:15:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_method_with_result_do_model_method_02
+ | expectedResult actualResult method |
+
+ method := model createMethod
+ source: 'selector_01 ^ 1';
+ yourself.
+
+ expectedResult := OrderedCollection new
+ add: method;
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder methodSearcher search:'`#literal' inMethod:method withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedMethod
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 23:16:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_method_with_result_do_model_method_03
+ |expectedResult actualResult method|
+
+ method := model createMethod
+ source:'selector_01 ^ self';
+ yourself.
+
+ expectedResult := OrderedCollection new.
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder methodSearcher search:'`#literal' inMethod:method withResultDo:[ :sourceSelection |
+ actualResult add:sourceSelection selectedMethod
+ ].
+
+ self assert:expectedResult = actualResult.
+
+ "Created: / 04-11-2014 / 23:19:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_method_with_result_do_real_method
+ | expectedResult actualResult class method |
+
+ class := model createClassImmediate: #DummyClass01.
+ method := model createMethodImmediate: class source: 'selector_01 ^ 1'.
+
+ expectedResult := OrderedCollection new
+ add: method;
+ yourself.
+
+ actualResult := OrderedCollection new.
+
+ refactoryBuilder methodSearcher search:'`@something' inMethod:method withResultDo:[ :sourceSelection |
+ actualResult add: sourceSelection selectedMethod
+ ].
+
+ self assert: expectedResult = actualResult.
+
+ "Modified: / 04-11-2014 / 23:14:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilderTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoryClassChangeTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,175 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRefactoryClassChangeTests
+ instanceVariableNames:'change model'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRefactoryClassChangeTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomRefactoryClassChangeTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ model := RBNamespace new.
+ change := RefactoryClassChange new
+ model: model;
+ yourself.
+
+ "Modified: / 08-11-2014 / 14:29:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryClassChangeTests methodsFor:'tests'!
+
+test_change_class_with_existing_class
+ | expectedClass actualClass |
+
+ change changeClass: self class.
+
+ expectedClass := self class.
+ actualClass := change changeClass.
+
+ self assert: expectedClass == actualClass
+
+ "Created: / 08-11-2014 / 14:35:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_existing_class_with_rb_class
+ | expectedClass actualClass rbClass |
+
+ rbClass := model classFor: self class.
+
+ change changeClass: rbClass.
+
+ expectedClass := self class.
+ actualClass := change changeClass.
+
+ self assert: expectedClass == actualClass
+
+ "Created: / 08-11-2014 / 14:36:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_existing_metaclass
+ | expectedClass actualClass |
+
+ change changeClass: self class class.
+
+ expectedClass := self class class.
+ actualClass := change changeClass.
+
+ self assert: expectedClass == actualClass
+
+ "Created: / 08-11-2014 / 14:35:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_non_existing_class
+ | expectedClass actualClass |
+
+ change model: nil.
+
+ change changeClass: (RBClass new
+ name: #DummyClass01;
+ yourself).
+
+ self assert: (Smalltalk at: #DummyClass01) isNil.
+
+ expectedClass := nil.
+ actualClass := change changeClass.
+
+ self assert: expectedClass == actualClass
+
+ "Created: / 08-11-2014 / 14:38:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_non_existing_class_but_model_class
+ | expectedClass actualClass class |
+
+ model defineClass: 'Object subclass:#DummyClassForTestCase01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:'''''.
+
+ self assert: (Smalltalk at: #DummyClassForTestCase01) isNil.
+
+ class := model classNamed: #DummyClassForTestCase01.
+
+ change changeClass: class.
+
+ expectedClass := class.
+ actualClass := change changeClass.
+
+ self assert: expectedClass == actualClass
+
+ "Created: / 08-11-2014 / 14:27:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_non_existing_metaclass_but_model_metaclass
+ | expectedClass actualClass class |
+
+ model defineClass: 'Object subclass:#DummyClassForTestCase01
+ instanceVariableNames:''''
+ classVariableNames:''''
+ poolDictionaries:''''
+ category:'''''.
+
+ self assert: (Smalltalk at: #DummyClassForTestCase01) isNil.
+
+ class := model metaclassNamed: #DummyClassForTestCase01.
+
+ change changeClass: class.
+
+ expectedClass := class.
+ actualClass := change changeClass.
+
+ self assert: expectedClass == actualClass
+
+ "Created: / 08-11-2014 / 14:33:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomRefactoring subclass:#CustomReplaceIfNilWithIfTrueRefactoring
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomReplaceIfNilWithIfTrueRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoring class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Search for ifNil:ifNotNil: expressions and replace it with isNil ifTrue:ifFalse: expression'
+
+ "Created: / 07-08-2014 / 21:50:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Replace ifNil:ifNotNil: with isNil ifTrue:ifFalse:'
+
+ "Created: / 07-08-2014 / 21:51:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoring class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ true
+
+ "Created: / 07-08-2014 / 21:01:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ ^ true
+
+ "Created: / 07-08-2014 / 22:14:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoring methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ "Performs a refactoring within given context scope"
+
+ refactoryBuilder
+ replace: '``@receiver ifNil: ``@nilBlock ifNotNil: ``@notNilBlock'
+ with: '``@receiver isNil ifTrue: ``@nilBlock ifFalse: ``@notNilBlock'
+ inContext: aCustomContext
+
+ "Created: / 23-08-2014 / 00:17:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoring class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomReplaceIfNilWithIfTrueRefactoringTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,112 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomReplaceIfNilWithIfTrueRefactoringTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings-Tests'
+!
+
+!CustomReplaceIfNilWithIfTrueRefactoringTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoringTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomReplaceIfNilWithIfTrueRefactoring new
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoringTests methodsFor:'tests'!
+
+test_available_in_context
+
+ "Available for every context"
+ self assert: (generatorOrRefactoring class availableInContext: context).
+
+ "Modified: / 16-10-2014 / 21:36:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective
+
+ "Available for every perspective"
+ self assert: (generatorOrRefactoring class availableInContext: CustomPerspective instance).
+
+ "Modified: / 16-10-2014 / 21:38:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_if_nil_replaced_with_is_nil_if_true
+ | expectedSource class |
+
+ class := model createClassImmediate: 'DummyClassForTestCase01'.
+ model createMethod
+ class: class;
+ protocol: 'protocol';
+ source: 'selector: arg
+ arg ifNil: [
+ self warn: ''nil''.
+ ]
+ ifNotNil: [ self information: ''info'' ].
+ ';
+ compile.
+
+ context selectedClasses: (Array with: class).
+ model execute.
+
+ generatorOrRefactoring executeInContext: context.
+
+ expectedSource := 'selector:arg
+ arg isNil ifTrue:[
+ self warn:''nil''.
+ ] ifFalse:[
+ self information:''info''
+ ].'.
+
+ self assertMethodSource: expectedSource atSelector: #selector: forClass: class.
+
+ "Created: / 10-08-2014 / 09:42:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-10-2014 / 19:02:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 25-01-2015 / 15:17:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSilentDialog.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,187 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomDialog subclass:#CustomSilentDialog
+ instanceVariableNames:'methodAnswers'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-UI'
+!
+
+CustomSilentDialog subclass:#NilComponent
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:CustomSilentDialog
+!
+
+!CustomSilentDialog class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ CustomDialog implementation based on non human interaction with dialog answers.
+ You may set dialog aswers to inject them in code generators.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomSilentDialog class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize
+
+ "Created: / 11-05-2014 / 11:13:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'accessing'!
+
+answer: anAnswer forSelector: aSelector
+
+ methodAnswers
+ at: aSelector
+ put: anAnswer
+
+ "Created: / 11-05-2014 / 00:32:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodAnswer: aSelector
+
+ ^ methodAnswers at: aSelector
+
+ "Created: / 11-05-2014 / 00:25:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'construction-adding'!
+
+addAbortAndOkButtons
+ "/ Nothing to do
+
+ "Created: / 15-09-2014 / 16:21:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addComponent:aView
+ "Add given component. Component is automatically stretched to occupy windows' width"
+
+ ^ CustomSilentDialog::NilComponent new
+
+ "Created: / 15-09-2014 / 18:48:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 14-10-2014 / 11:27:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+addComponent:aView labeled:labelString
+ "Add a label and some component side-by-side. Returns the component"
+
+ ^ CustomSilentDialog::NilComponent new
+
+ "Created: / 15-09-2014 / 15:45:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 14-10-2014 / 11:26:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'dialogs'!
+
+requestClassName:aString initialAnswer:anInitialAswer
+
+ ^ self methodAnswer: #requestClassName:initialAnswer:
+
+ "Created: / 11-05-2014 / 00:16:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'initialization'!
+
+initialize
+
+ methodAnswers := Dictionary new
+
+ "Created: / 11-05-2014 / 00:19:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'opening'!
+
+open
+ "/ Ignored
+
+ "Created: / 15-09-2014 / 16:23:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'user interaction & notifications'!
+
+information: aString
+
+ ^ self
+
+ "Created: / 13-05-2014 / 22:33:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog::NilComponent class methodsFor:'documentation'!
+
+documentation
+"
+ Substitute for component in CustomDialog to hide any real UI.
+ This class just understand all method calls and returns self.
+"
+! !
+
+!CustomSilentDialog::NilComponent methodsFor:'queries'!
+
+doesNotUnderstand: aMessage
+ "Do nothing when a message arrives."
+
+ ^ self
+
+ "Created: / 14-10-2014 / 11:25:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleAccessMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,91 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomSimpleAccessMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomSimpleAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSimpleAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Access Method(s) for selected instance variables'
+
+ "Modified: / 07-07-2014 / 22:20:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Access Method(s)'
+! !
+
+!CustomSimpleAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ "Creates access methods for given context"
+
+ self executeSubGeneratorOrRefactoringClasses:(Array
+ with:CustomSimpleGetterMethodsCodeGenerator
+ with:CustomSimpleSetterMethodsCodeGenerator)
+ inContext:aCustomContext
+
+ "Modified: / 11-07-2014 / 21:16:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleAccessMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,109 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomSimpleAccessMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomSimpleAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSimpleAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomSimpleAccessMethodsCodeGenerator new
+! !
+
+!CustomSimpleAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_access_methods_generated_with_comments
+ | expectedGetterSource expectedSetterSource |
+
+ userPreferences
+ generateCommentsForGetters: true;
+ generateCommentsForSetters: true.
+
+ expectedGetterSource := 'instanceVariable
+ "return the instance variable ''instanceVariable'' (automatically generated)"
+
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ "set the value of the instance variable ''instanceVariable'' (automatically generated)"
+
+ instanceVariable := something'.
+
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+ "Created: / 08-07-2014 / 13:28:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-07-2014 / 16:02:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_access_methods_generated_without_comments
+ | expectedGetterSource expectedSetterSource |
+
+ userPreferences
+ generateCommentsForGetters: false;
+ generateCommentsForSetters: false.
+
+ expectedGetterSource := 'instanceVariable
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ instanceVariable := something'.
+
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+ "Created: / 08-07-2014 / 16:59:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleGetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,115 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomSimpleGetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomSimpleGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSimpleGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+ ^ 'Getter methods for selected instance variables'
+
+ "Modified: / 11-05-2014 / 16:37:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Getters')
+
+ "Created: / 22-08-2014 / 18:56:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+ ^ 'Getter Method(s)'
+
+ "Modified (format): / 11-05-2014 / 16:29:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns simple getter method source code for given class and variable name"
+
+ | methodName comment |
+
+ methodName := self methodNameFor: aName.
+ comment := ''.
+
+ userPreferences generateCommentsForGetters ifTrue:[
+ | varType |
+
+ varType := self varTypeOf: aName class: aClass.
+ comment := '"return the %1 variable ''%2'' (automatically generated)"'.
+ comment := comment bindWith: varType with: aName.
+ ].
+
+ ^ self sourceCodeGenerator
+ source: '`@methodName
+ `"comment
+
+ ^ `variableName';
+ replace: '`@methodName' with: methodName asSymbol;
+ replace: '`variableName' with: aName asString;
+ replace: '`"comment' with: comment;
+ newSource.
+
+ "Created: / 19-05-2014 / 20:32:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-09-2014 / 22:35:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleGetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,103 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomSimpleGetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomSimpleGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSimpleGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomSimpleGetterMethodsCodeGenerator new
+
+ "Modified: / 29-05-2014 / 00:07:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_simple_getter_method_generated_with_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: true.
+
+ expectedSource := 'instanceVariable
+ "return the instance variable ''instanceVariable'' (automatically generated)"
+
+ ^ instanceVariable'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+ "Created: / 31-05-2014 / 20:06:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-06-2014 / 10:41:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_simple_getter_method_generated_without_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: false.
+
+ expectedSource := 'instanceVariable
+ ^ instanceVariable'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+ "Created: / 31-05-2014 / 20:05:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-06-2014 / 10:41:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleSetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomSimpleSetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomSimpleSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSimpleSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Setter methods for selected instance variables'
+
+ "Modified: / 04-07-2014 / 15:29:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Setters')
+
+ "Created: / 22-08-2014 / 18:55:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Setter Method(s)'
+
+ "Modified: / 04-07-2014 / 16:20:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns simple setter for given class and variable name."
+
+ | methodName comment argName |
+
+ methodName := self methodNameFor: aName.
+ argName := self argNameForMethodName: methodName.
+ comment := ''.
+
+ userPreferences generateCommentsForSetters ifTrue:[
+ | varType |
+
+ varType := self varTypeOf: aName class: aClass.
+ comment := '"set the value of the %1 variable ''%2'' (automatically generated)"'.
+ comment := comment bindWith: varType with: aName.
+ ].
+
+ ^ self sourceCodeGenerator
+ source: '`@methodName
+ `"comment
+
+ `variableName := `argName';
+ replace: '`@methodName' with: (methodName, ': ', argName) asSymbol;
+ replace: '`argName' with: argName asString;
+ replace: '`variableName' with: aName asString;
+ replace: '`"comment' with: comment;
+ newSource.
+
+ "Modified: / 19-09-2014 / 22:36:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleSetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,103 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomSimpleSetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomSimpleSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSimpleSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomSimpleSetterMethodsCodeGenerator new
+! !
+
+!CustomSimpleSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_simple_setter_method_generated_with_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: true.
+
+ expectedSource := 'instanceVariable:something
+ "set the value of the instance variable ''instanceVariable'' (automatically generated)"
+
+ instanceVariable := something'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+ "Created: / 05-07-2014 / 13:29:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-07-2014 / 19:38:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_simple_setter_method_generated_without_comments
+ "test setter method"
+
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: false.
+
+ expectedSource := 'instanceVariable:something
+ instanceVariable := something'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+ "Created: / 05-07-2014 / 13:38:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-07-2014 / 19:38:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeFormatter.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,81 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomSourceCodeFormatter
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomSourceCodeFormatter class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Defines required methods for a source code formatter implementation used in this package.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomSourceCodeFormatter class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+! !
+
+!CustomSourceCodeFormatter methodsFor:'formatting'!
+
+formatParseTree: aParseTree
+ "Should return parse tree formatted as source code "
+
+ self subclassResponsibility
+
+ "Modified (comment): / 28-08-2014 / 22:13:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,231 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CodeGenerator subclass:#CustomSourceCodeGenerator
+ instanceVariableNames:'formatter commentPlaceholderMarker commentReplacements'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomSourceCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Extension for CodeGenerator to support work just with source code and with formatter.
+ Replacements definition are not stricly limited to just expressions, but also method call.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomSourceCodeGenerator methodsFor:'accessing'!
+
+commentPlaceholderMarker: aString
+ "
+ Sets prefix string which will mark comment replace
+ in code replacements given by:
+ replace: '`comment' with: 'comment'
+ "
+
+ commentPlaceholderMarker := aString
+
+ "Created: / 19-09-2014 / 21:17:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter
+
+ ^ formatter
+
+ "Created: / 19-09-2014 / 22:24:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter: aSourceCodeFormatter
+
+ formatter := aSourceCodeFormatter
+
+ "Created: / 19-09-2014 / 22:25:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newSource
+ "
+ Returns formatted method source
+ code as string (with replacements and so on)
+ "
+
+ | parser method |
+
+ source := self replaceCommentsInSource: source.
+ parser := RBParser new.
+ recordedReplacementsInSource := OrderedCollection new.
+ parser errorBlock:[ :str :pos | self error: ('Error: %1: %2' bindWith: pos with: str). ^ self ].
+
+ parser initializeParserWith: source type: #rewriteSavingCommentsOn:errorBlock:.
+ method := parser parseMethod: source.
+
+ method source: nil.
+ method acceptVisitor: self.
+ self replaceInSourceCode.
+ method source: source.
+
+ ^ formatter formatParseTree: method.
+
+ "Created: / 19-09-2014 / 22:07:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replace: placeholder with: code
+
+ (placeholder startsWith: commentPlaceholderMarker) ifTrue: [
+ commentReplacements
+ at: placeholder
+ put: code
+ ]
+ ifFalse: [
+ replacements
+ at: placeholder
+ put: (self replacementFromCode: code)
+ ]
+
+ "Created: / 19-09-2014 / 21:18:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-09-2014 / 23:58:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGenerator methodsFor:'initialization'!
+
+initialize
+ "Invoked when a new instance is created."
+
+ super initialize.
+ commentPlaceholderMarker := '`"'.
+ commentReplacements := Dictionary new.
+
+ "Created: / 19-09-2014 / 21:42:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGenerator methodsFor:'private'!
+
+formatReplacement: replacement
+ "Returns formatted source code replacement, but keep Symbol not formatted"
+
+ replacement isSymbol ifTrue: [
+ ^ replacement formattedCode
+ ].
+
+ ^ formatter formatParseTree: replacement
+
+ "Created: / 20-09-2014 / 10:01:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replaceCommentsInSource: aSourceCodeString
+ "
+ Returns source string with replaced occurences of comment
+ replaces given by:
+ replace: '`{double_quote_char}comment' with: '{double_quote_char}a comment{double_quote_char}'
+ where {double_quote_char} is "" (but not escaped like in this comment)
+ "
+
+ | sourceCode |
+
+ sourceCode := aSourceCodeString.
+
+ commentReplacements keysAndValuesDo: [ :placeholder :code |
+ sourceCode := sourceCode copyReplaceString: placeholder withString: code
+ ].
+
+ ^ sourceCode
+
+ "Created: / 19-09-2014 / 22:08:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replacePlaceholdersInSelectorPartsOf:aMessageNode
+ aMessageNode selectorParts do:[:part |
+ part isPatternVariable ifTrue:[
+ |replacement|
+
+ replacement := self replacementFor:part value.
+ "(replacement isSymbol or:[ replacement isVariable ]) ifFalse:[
+ self error:'Replacement for selector parts must be a single selector'
+ ]."
+ replacement isNil ifTrue: [
+ self error: 'None replacement for: ', part value asString.
+ ].
+ source notNil ifTrue:[
+ self
+ recordReplaceInSourceFrom:part start
+ to:part stop
+ by: (self formatReplacement: replacement).
+ ].
+ part value: (self formatReplacement: replacement).
+ ]
+ ]
+
+ "Created: / 19-09-2014 / 23:55:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 20-09-2014 / 10:14:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replacementFromCode: aCode
+
+ ^ aCode isSymbol
+ ifTrue:[aCode]
+ ifFalse:[
+ RBParser parseRewriteExpression: aCode onError: [ :str :pos |
+ RBParser parseRewriteMethod: aCode onError: [ :str :pos |
+ self error: 'Cannot parse: ', str, ' at pos: ', pos asString
+ ]
+ ]
+ ]
+
+ "Created: / 19-09-2014 / 23:56:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,180 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomSourceCodeGeneratorTests
+ instanceVariableNames:'sourceCodeGenerator'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomSourceCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSourceCodeGeneratorTests methodsFor:'initialization & release'!
+
+setUp
+
+ sourceCodeGenerator := CustomSourceCodeGenerator new.
+ sourceCodeGenerator formatter: CustomNoneSourceCodeFormatter new.
+
+ "Modified: / 19-09-2014 / 23:42:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGeneratorTests methodsFor:'tests'!
+
+test_new_source_literal_replacement
+ |expectedSource actualSource|
+
+ actualSource := sourceCodeGenerator
+ replace:'`"comment1' with:'"comment1"';
+ replace:'`"comment2' with:'"other comment2"';
+ replace:'`#literal' with:'''some info''';
+ source:'selector
+ `"comment1
+
+ self information: `#literal.
+
+ `"comment2
+
+ ^ 55';
+ newSource.
+ expectedSource := 'selector
+ "comment1"
+
+ self information: ''some info''.
+
+ "other comment2"
+
+ ^ 55'.
+ self assert:expectedSource = actualSource.
+
+ "Created: / 19-09-2014 / 23:45:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_selector_as_symbol
+ | expectedSource actualSource |
+
+ actualSource := sourceCodeGenerator
+ source: '`@selector
+ self shouldImplement';
+ replace: '`@selector' with: 'aSelector: withParam' asSymbol;
+ newSource.
+
+ expectedSource := 'aSelector: withParam
+ self shouldImplement'.
+
+ self assert: expectedSource = actualSource.
+
+ "Created: / 20-09-2014 / 09:36:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_selector_replacement
+ |expectedSource actualSource|
+
+ actualSource := sourceCodeGenerator
+ source:'`@selector
+ self shouldImplement';
+ replace:'`@selector' with:'aSelector';
+ newSource.
+ expectedSource := 'aSelector
+ self shouldImplement'.
+ self assert:expectedSource = actualSource.
+
+ "Created: / 19-09-2014 / 23:51:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_selector_with_param
+ | expectedSource actualSource |
+
+ actualSource := sourceCodeGenerator
+ source: '`@selector
+ self shouldImplement';
+ replace: '`@selector' with: 'aSelector: withParam';
+ newSource.
+
+ expectedSource := 'aSelector: withParam
+ self shouldImplement'.
+
+ self assert: expectedSource = actualSource.
+
+ "Created: / 20-09-2014 / 09:39:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_replace_comments_in_source
+ | expectedSource actualSource |
+
+ actualSource := sourceCodeGenerator
+ replace: '`"comment1' with: '"comment1"';
+ replace: '`"comment2' with: '"other comment2"';
+ replaceCommentsInSource:'selector
+ `"comment1
+
+ self information: ''some info''.
+
+ `"comment2
+
+ ^ 55'.
+
+ expectedSource := 'selector
+ "comment1"
+
+ self information: ''some info''.
+
+ "other comment2"
+
+ ^ 55'.
+
+ self assert: expectedSource = actualSource.
+
+ "Created: / 19-09-2014 / 22:50:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeSelection.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,270 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomSourceCodeSelection
+ instanceVariableNames:'selectedInterval currentSourceCode selectedMethod selectedClass
+ selectedSelector'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomSourceCodeSelection class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Container class which holds actual source code from text editor (source code editor)
+ with exact position of selected source code. Also keeps corresponding class, method and selector
+ to current source code.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomSourceCodeSelection methodsFor:'accessing'!
+
+currentSourceCode
+ "Returns the source code string. This is the code we actually
+ working on - for example modified method in code editor.
+ If such code is not directly known then is retrieved from selected method
+ or from selected class and selector."
+
+ currentSourceCode notNil ifTrue: [
+ ^ currentSourceCode
+ ].
+
+ self selectedMethod notNil ifTrue: [
+ ^ self selectedMethod source
+ ].
+
+ (selectedSelector notNil and: [selectedClass notNil]) ifTrue: [
+ ^ (selectedClass compiledMethodAt: selectedSelector asSymbol) source
+ ].
+
+ ^ nil
+
+ "Modified: / 28-10-2014 / 11:46:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+currentSourceCode: aSourceCode
+ "see ... currentSourceCode"
+
+ currentSourceCode := aSourceCode.
+
+ "Modified (comment): / 18-10-2014 / 12:03:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClass
+ "Returns the selected class which belongs to the selected source code."
+
+ ^ selectedClass
+
+ "Modified (comment): / 18-10-2014 / 12:27:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClass: aClass
+ "see ... selectedClass"
+
+ selectedClass := aClass.
+
+ "Modified (comment): / 18-10-2014 / 12:27:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedInterval
+ "Returns numeric interval to tell which fragment of the currentSourceCode is selected.
+ For example (2 to: 5) means that second to fifth character is selected."
+
+ ^ selectedInterval
+
+ "Modified (comment): / 18-10-2014 / 12:50:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedInterval: anInterval
+ "see ... selectedInterval"
+
+ selectedInterval := anInterval.
+
+ "Modified (comment): / 18-10-2014 / 12:51:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethod
+ "Returns the selected method which belongs to the selected source code."
+
+ ^ selectedMethod
+
+ "Modified (comment): / 18-10-2014 / 12:53:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethod: aMethod
+ "see ... selectedMethod"
+
+ selectedMethod := aMethod.
+
+ "Modified (comment): / 18-10-2014 / 12:53:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedSelector
+ "Returns the selected method selector which belongs to the selected source code.
+ If not known then returns selected method selector or source code."
+
+ | selector |
+
+ selectedSelector notNil ifTrue: [
+ ^ selectedSelector
+ ].
+
+ selector := nil.
+
+ self selectedMethod notNil ifTrue: [
+ selector := self selectedMethod selector
+ ].
+
+ selector isNil ifTrue: [
+ | source |
+
+ source := self currentSourceCode.
+ source notNil ifTrue: [
+ "In some cases the 'who' method from Method >> selector
+ returns nil as selector so parse the selector from source"
+ selector := (Parser parseMethodSpecification: source) selector
+ ]
+ ].
+
+ ^ selector
+
+ "Modified (format): / 28-10-2014 / 12:20:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedSelector: aSelector
+ "see ... selectedSelector"
+
+ selectedSelector := aSelector.
+
+ "Modified (comment): / 18-10-2014 / 12:54:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedSourceCode
+ "Returns selected source code fragment as string from current source code
+ specified by selected interval.
+ For example when code is 'some_code' and interval is (2 to: 4) then 'ome' is returned."
+
+ | source interval |
+
+ source := self currentSourceCode.
+ source isNil ifTrue: [ ^ nil ].
+ source := source asString.
+
+ interval := self selectedInterval.
+
+ interval isNil ifTrue: [
+ "Return the whole source when none interval is specified"
+ ^ source
+ ].
+
+ interval isEmpty ifTrue: [
+ "Cannot retrieve any source when interval is empty, so return unknown source"
+ ^ nil
+ ].
+
+ (interval first between: 1 and: source size) ifFalse: [
+ self error: 'selectedInterval is not within currentSourceCode range'
+ ].
+
+ ^ source copyFrom: interval first to: (interval last min:source size)
+
+ "Created: / 24-08-2014 / 22:18:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 22:49:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelection methodsFor:'printing & storing'!
+
+printOn:aStream
+ "append a printed representation if the receiver to the argument, aStream"
+
+ super printOn:aStream.
+ aStream nextPutAll:' (selectedInterval: '.
+
+ self selectedInterval printOn:aStream.
+ aStream nextPutAll:'; currentSourceCode: '.
+
+ self currentSourceCode printOn:aStream.
+ aStream nextPutAll:'; selectedMethod: '.
+
+ self selectedMethod printOn:aStream.
+ aStream nextPutAll:'; selectedClass: '.
+
+ self selectedClass printOn:aStream.
+ aStream nextPutAll:'; selectedSelector: '.
+
+ self selectedSelector printOn:aStream.
+ aStream nextPutAll:')'.
+
+ "Modified: / 28-10-2014 / 10:25:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelection methodsFor:'queries'!
+
+isWholeMethodSelected
+ "Returns true if complete method source code is selected
+ othervise returns false"
+
+ self selectedMethod isNil ifTrue: [
+ ^ false
+ ].
+
+ ^ (self currentSourceCode) = (self selectedSourceCode)
+
+ "Created: / 07-12-2014 / 18:48:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelection class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeSelectionTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,306 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomSourceCodeSelectionTests
+ instanceVariableNames:'codeSelection'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomSourceCodeSelectionTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSourceCodeSelectionTests methodsFor:'initialization & release'!
+
+setUp
+
+ codeSelection := CustomSourceCodeSelection new.
+
+ "Created: / 24-08-2014 / 22:51:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelectionTests methodsFor:'tests'!
+
+test_current_source_code_class_and_selector_filled
+
+ codeSelection
+ selectedClass: self class;
+ selectedSelector: #setUp.
+
+ self assert: (codeSelection currentSourceCode startsWith: 'setUp').
+
+ "Created: / 24-08-2014 / 22:56:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_current_source_code_filled
+
+ codeSelection currentSourceCode: 'src'.
+
+ self assert: codeSelection currentSourceCode = 'src'.
+
+ "Created: / 24-08-2014 / 22:54:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_current_source_code_method_filled
+
+ codeSelection selectedMethod: (self class compiledMethodAt: #setUp).
+
+ self assert: (codeSelection currentSourceCode startsWith: 'setUp').
+
+ "Created: / 24-08-2014 / 22:55:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_current_source_code_not_filled
+
+ self assert: codeSelection currentSourceCode isNil.
+
+ "Created: / 24-08-2014 / 22:57:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_whole_method_selected_all_empty
+
+ self deny: codeSelection isWholeMethodSelected
+
+ "Created: / 07-12-2014 / 18:51:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_whole_method_selected_complete_selection
+ | method |
+
+ method := self class compiledMethodAt: #test_is_whole_method_selected_complete_selection.
+
+ codeSelection
+ selectedInterval: (1 to: method source size);
+ selectedMethod: method.
+
+ self assert: codeSelection isWholeMethodSelected
+
+ "Created: / 07-12-2014 / 19:11:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_whole_method_selected_empty_method
+
+ codeSelection
+ selectedInterval: (3 to: 6);
+ currentSourceCode: 'some code'.
+
+ self deny: codeSelection isWholeMethodSelected
+
+ "Created: / 07-12-2014 / 19:09:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_whole_method_selected_empty_selection
+
+ codeSelection selectedMethod: (self class compiledMethodAt: #test_is_whole_method_selected_empty_selection).
+
+ self assert: codeSelection isWholeMethodSelected
+
+ "Modified: / 07-12-2014 / 18:53:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_print_on_all_filled
+ | expectedString actualString stream method |
+
+ method := (self class compiledMethodAt: #test_print_on_all_filled).
+
+ expectedString := 'a SmallSense::CustomSourceCodeSelection (selectedInterval: 2 to:5; ',
+ 'currentSourceCode: test_print_on_all_filled ^ 265; ',
+ 'selectedMethod: ', method asString, '; ',
+ 'selectedClass: SmallSense::CustomSourceCodeSelectionTests; selectedSelector: test_print_on_all_filled)'.
+
+ stream := WriteStream on:(String new).
+
+ codeSelection
+ selectedClass: self class;
+ selectedMethod: method;
+ selectedInterval: (2 to: 5);
+ selectedSelector: #test_print_on_all_filled;
+ currentSourceCode: 'test_print_on_all_filled ^ 265'.
+
+ codeSelection printOn:stream.
+
+ actualString := stream contents.
+
+ self assert: expectedString = actualString.
+
+ "Modified: / 25-01-2015 / 14:36:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 21:07:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_selected_selector_from_method
+ | expectedSelector actualSelector |
+
+ expectedSelector := #test_selected_selector_from_method.
+ codeSelection selectedMethod: (self class compiledMethodAt: #test_selected_selector_from_method).
+
+ actualSelector := codeSelection selectedSelector.
+
+ self assert: expectedSelector = actualSelector.
+
+ "Created: / 28-10-2014 / 09:31:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_selector_from_source
+ | expectedSelector actualSelector |
+
+ expectedSelector := #test_selector_01.
+ codeSelection currentSourceCode: 'test_selector_01 ^ 101'.
+
+ actualSelector := codeSelection selectedSelector.
+
+ self assert: expectedSelector = actualSelector.
+
+ "Created: / 28-10-2014 / 10:52:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_selector_known
+ | expectedSelector actualSelector |
+
+ expectedSelector := #selector_01.
+ codeSelection selectedSelector: expectedSelector.
+
+ actualSelector := codeSelection selectedSelector.
+
+ self assert: expectedSelector = actualSelector.
+
+ "Created: / 28-10-2014 / 09:30:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_selector_unknown
+ | expectedSelector actualSelector |
+
+ expectedSelector := nil.
+ actualSelector := codeSelection selectedSelector.
+
+ self assert: expectedSelector = actualSelector.
+
+ "Created: / 28-10-2014 / 09:29:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_code_nil_when_unknown
+
+ self assert: codeSelection selectedSourceCode isNil
+
+ "Modified: / 05-11-2014 / 22:51:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_code_part_code
+
+ codeSelection
+ currentSourceCode: 'selector ^ self otherSelector.';
+ selectedInterval: (12 to: 15).
+
+ self assert: codeSelection selectedSourceCode = 'self'.
+
+ "Created: / 24-08-2014 / 23:06:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_code_whole_code
+
+ codeSelection
+ currentSourceCode: 'selector ^ self otherSelector.';
+ selectedInterval: (1 to: 30).
+
+ self assert: codeSelection selectedSourceCode = 'selector ^ self otherSelector.'.
+
+ "Created: / 24-08-2014 / 22:58:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_code_with_exceeding_interval
+
+ codeSelection
+ currentSourceCode: 'selector ^ self otherSelector.';
+ selectedInterval: (1 to: 9999999).
+
+ self assert: codeSelection selectedSourceCode = 'selector ^ self otherSelector.'.
+
+ "Created: / 18-10-2014 / 13:13:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_interval_empty
+
+ codeSelection
+ currentSourceCode: 'selector ^ self otherSelector.';
+ selectedInterval: (1 to: 0).
+
+ self assert: codeSelection selectedSourceCode isNil.
+
+ "Created: / 14-10-2014 / 10:22:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_interval_wrong
+
+ codeSelection
+ currentSourceCode: 'selector ^ self otherSelector.';
+ selectedInterval: (9999 to: 99999).
+
+ self should: [
+ codeSelection selectedSourceCode
+ ] raise: Error
+
+ "Created: / 18-10-2014 / 13:06:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_unknown
+ | expectedSource |
+
+ expectedSource := 'selector ^ self otherSelector.'.
+
+ codeSelection
+ currentSourceCode: expectedSource.
+
+ self assert: expectedSource = (codeSelection selectedSourceCode).
+
+ "Created: / 14-10-2014 / 10:19:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 28-10-2014 / 09:13:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelectionTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSubContext.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,201 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomContext subclass:#CustomSubContext
+ instanceVariableNames:'selectedClasses selectedClassCategories selectedProtocols
+ selectedMethods selectedPackages selectedVariables selectedCodes'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom'
+!
+
+!CustomSubContext class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSubContext methodsFor:'accessing'!
+
+selectedClassCategories: classCategories
+ "Sets the list of class categories"
+
+ selectedClassCategories := classCategories.
+
+ "Modified (comment): / 29-11-2014 / 18:32:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClasses: classes
+ "Sets the list of classes"
+
+ selectedClasses := classes
+
+ "Created: / 26-04-2014 / 16:05:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-11-2014 / 19:26:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 20:23:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedCodes: something
+ "Sets the list of code selections - instances of CustomSourceCodeSelection"
+
+ selectedCodes := something.
+
+ "Created: / 18-08-2014 / 23:53:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 29-11-2014 / 18:33:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethods: methods
+ "Sets the list of methods"
+
+ selectedMethods := methods.
+
+ "Modified: / 25-11-2014 / 20:27:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedPackages: packages
+ "Sets the list of packages"
+
+ selectedPackages := packages.
+
+ "Modified (comment): / 29-11-2014 / 18:31:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedProtocols: protocols
+ "Sets the list of method protocols (i.e. categories)"
+
+ selectedProtocols := protocols.
+
+ "Modified (comment): / 29-11-2014 / 18:34:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedVariables: variables
+ "Sets the list of class variable names"
+
+ selectedVariables := variables.
+
+ "Modified (comment): / 29-11-2014 / 18:36:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubContext methodsFor:'accessing-selection'!
+
+selectedClassCategories
+
+ ^ selectedClassCategories
+
+ "Modified: / 05-05-2014 / 20:31:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClasses
+ "Returns the list of classes"
+
+ "classes is supposed to be a collection of RBClass/RBMetaclass. However, if real classes
+ are passed, they are converted to RBClasses here for your convenience"
+
+ ^ selectedClasses ? #() collect: [ :class |
+ class isBehavior
+ ifTrue:[ self asRBClass: class ]
+ ifFalse:[ class ]
+ ]
+
+ "Created: / 19-12-2013 / 12:24:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 25-11-2014 / 20:24:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedCodes
+
+ ^ selectedCodes
+
+ "Created: / 18-08-2014 / 23:52:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethods
+ "Returns the list of methods"
+
+ "methods is supposed to be a collection of RBMethod. However, if real methods (Method)
+ are passed, they are converted to RBMethod here for your convenience"
+
+ ^ selectedMethods ? #() collect: [ :method |
+ method isMethod
+ ifTrue:[ self asRBMethod: method ]
+ ifFalse:[ method ]
+ ]
+
+ "Modified (comment): / 25-11-2014 / 20:26:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedPackages
+
+ ^ selectedPackages
+
+ "Modified: / 05-05-2014 / 20:32:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedProtocols
+ ^ selectedProtocols
+
+ "Modified: / 05-05-2014 / 20:31:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedVariables
+
+ ^ selectedVariables
+
+ "Modified: / 05-05-2014 / 20:32:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubContext methodsFor:'initialization'!
+
+initialize
+
+ super initialize.
+ selectedClasses := OrderedCollection new.
+
+ "Created: / 19-12-2013 / 12:37:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-11-2014 / 10:19:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubContext class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSubContextTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,138 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomSubContextTests
+ instanceVariableNames:'model context'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomSubContextTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSubContextTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ model := CustomNamespace new.
+ context := CustomSubContext new
+ model: model;
+ yourself
+
+ "Modified: / 19-11-2014 / 19:59:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubContextTests methodsFor:'tests'!
+
+test_selected_classes_as_rb_class
+
+ |expectedClasses actualClasses modelClass|
+
+ modelClass := model classNamed: self class name.
+ expectedClasses := Array with: modelClass.
+
+ context selectedClasses: (Array with: self class).
+ actualClasses := context selectedClasses.
+
+ self assert: expectedClasses = actualClasses
+
+ "Created: / 25-11-2014 / 20:31:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_classes_existing_rb_class
+
+ |expectedClasses actualClasses modelClass|
+
+ modelClass := model classNamed: self class name.
+ expectedClasses := Array with: modelClass.
+
+ context selectedClasses: (Array with: modelClass).
+ actualClasses := context selectedClasses.
+
+ self assert: expectedClasses = actualClasses
+
+ "Created: / 25-11-2014 / 20:37:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_methods_as_rb_method
+
+ |expectedMethods realMethod actualMethods modelClass modelMethod|
+
+ modelClass := model classNamed: self class name.
+ modelMethod := modelClass compiledMethodAt: #test_selected_methods_as_rb_method.
+ expectedMethods := Array with: modelMethod.
+
+ realMethod := self class compiledMethodAt: #test_selected_methods_as_rb_method.
+ context selectedMethods: (Array with: realMethod).
+ actualMethods := context selectedMethods.
+
+ "Cannot test collection equality, because each contains different RBMethod instance
+ self assert: expectedMethods = actualMethods"
+ self assert: (expectedMethods size) = (actualMethods size).
+ self assert: (expectedMethods first selector) = (actualMethods first selector).
+ self assert: (expectedMethods first isKindOf: RBMethod).
+ self deny: expectedMethods first isMethod
+
+ "Modified: / 19-11-2014 / 20:29:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 25-11-2014 / 20:30:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_methods_existing_rb_method
+
+ |expectedMethods actualMethods modelClass modelMethod|
+
+ modelClass := model classNamed: self class name.
+ modelMethod := modelClass compiledMethodAt: #test_selected_methods_as_rb_method.
+ expectedMethods := Array with: modelMethod.
+
+ context selectedMethods: (Array with: modelMethod).
+ actualMethods := context selectedMethods.
+
+ self assert: expectedMethods = actualMethods
+
+ "Created: / 19-11-2014 / 20:30:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSubclassResponsibilityCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,205 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomSubclassResponsibilityCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomSubclassResponsibilityCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Generates method stubs marked by: self subclassResponsibility'
+
+ "Modified: / 08-04-2014 / 21:40:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Subclass responsibility methods'
+
+ "Modified: / 08-04-2014 / 21:38:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator class methodsFor:'queries'!
+
+availableInContext: aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ aCustomContext selectedClasses notEmptyOrNil
+
+!
+
+availableInPerspective:aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ ^ aCustomPerspective isClassPerspective
+
+! !
+
+!CustomSubclassResponsibilityCodeGenerator methodsFor:'code generation'!
+
+createSubclassResponsibilityForClass: anRBClass
+
+ | missingRequiredSelectors classQuery |
+
+ classQuery := CustomClassQuery new.
+ self determineIsClassAbstract: anRBClass.
+ missingRequiredSelectors := self missingRequiredProtocolFor: anRBClass.
+
+ missingRequiredSelectors isCollection ifTrue: [
+ missingRequiredSelectors do: [ :selector |
+ | superclassMethod |
+
+ superclassMethod := (classQuery methodForSuperclassSelector: selector class: anRBClass).
+
+ model createMethod
+ class: anRBClass;
+ protocol: superclassMethod category;
+ source: ('`@selector
+
+ self shouldImplement');
+ replace: '`@selector' with: superclassMethod methodDefinitionTemplate asSymbol;
+ compile.
+ ]
+ ]
+
+ "Created: / 09-04-2014 / 20:16:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-12-2014 / 23:19:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 06:41:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator methodsFor:'executing'!
+
+buildInContext:aCustomContext
+
+ aCustomContext selectedClasses do: [ :class |
+ self
+ createSubclassResponsibilityForClass: class theNonMetaclass;
+ createSubclassResponsibilityForClass: class theMetaclass.
+ ]
+
+ "Created: / 08-04-2014 / 21:33:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 13-05-2014 / 22:04:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator methodsFor:'private'!
+
+determineIsClassAbstract: aClass
+ "For model class (RBClass, RBMetaclass) determines if the class is abstract or not.
+ Original RBAbstractClass >> isAbstract implementation returns mostly wrong guess,
+ especially for newly created classes."
+
+ aClass isBehavior ifTrue: [
+ "Nothing to do a for real class"
+ ^ self
+ ].
+
+ aClass isDefined ifTrue: [
+ aClass isAbstract: aClass realClass isAbstract
+ ] ifFalse: [
+ "For newly created class lets assume thats not abstract"
+ aClass isAbstract: false
+ ].
+
+ "Created: / 14-12-2014 / 23:19:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+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|
+
+ aClass isAbstract ifTrue:[
+ "abstract classes are not responsible for methods to be defined in subclasses"
+ ^ #().
+ ].
+
+ requiredSelectors := IdentitySet new.
+ implementedSelectors := IdentitySet withAll:(aClass methodDictionary keys).
+
+ aClass allSuperclassesDo:[:eachSuperClass |
+ eachSuperClass methodDictionary keysAndValuesDo:[:eachSelector :eachMethod |
+ (eachMethod sendsAnySelector:#( #subclassResponsibility #subclassResponsibility: )) ifTrue:[
+ (implementedSelectors includes:eachSelector) ifFalse:[
+ requiredSelectors add:eachSelector.
+ ]
+ ] ifFalse:[
+ (requiredSelectors includes:eachSelector) ifFalse:[
+ implementedSelectors add:eachSelector.
+ ].
+ ].
+ ]
+ ].
+ ^ requiredSelectors
+
+ "Created: / 11-05-2015 / 06:41:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSubclassResponsibilityCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,212 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomSubclassResponsibilityCodeGeneratorTests
+ instanceVariableNames:'mockSuperClass mockClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomSubclassResponsibilityCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomSubclassResponsibilityCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+ ^ CustomSubclassResponsibilityCodeGenerator new
+
+ "Created: / 29-08-2014 / 21:41:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGeneratorTests methodsFor:'initialization & release'!
+
+setUp
+
+ super setUp.
+ mockSuperClass := model createClassImmediate: 'MockSuperClassForTestCase' superClassName: 'Object'.
+ mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: (mockSuperClass new className).
+
+ "Created: / 14-04-2014 / 17:16:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 21:39:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGeneratorTests methodsFor:'tests'!
+
+test_determine_is_class_abstract_model_class
+ | expectedIsAbstract actualIsAbstract class |
+
+ class := model createClass
+ name: #DummyClass01;
+ compile;
+ yourself.
+
+ expectedIsAbstract := false.
+ generatorOrRefactoring determineIsClassAbstract: class.
+ actualIsAbstract := class isAbstract.
+
+ self assert: expectedIsAbstract = actualIsAbstract
+
+ "Created: / 14-12-2014 / 23:46:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_determine_is_class_abstract_real_abstract_class_wrapped_with_model_class
+ | expectedIsAbstract actualIsAbstract class realClass |
+
+ realClass := model createClassImmediate: #DummyClass01.
+ model createMethodImmediate: realClass class source: 'isAbstract ^ true'.
+
+ class := model classNamed: #DummyClass01.
+ expectedIsAbstract := true.
+ generatorOrRefactoring determineIsClassAbstract: class.
+ actualIsAbstract := class isAbstract.
+
+ self assert: expectedIsAbstract = actualIsAbstract
+
+ "Created: / 14-12-2014 / 23:45:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_determine_is_class_abstract_real_class
+ | expectedIsAbstract actualIsAbstract |
+
+ expectedIsAbstract := false.
+ generatorOrRefactoring determineIsClassAbstract: self class.
+ actualIsAbstract := self class isAbstract.
+
+ self assert: expectedIsAbstract = actualIsAbstract
+
+ "Modified: / 14-12-2014 / 23:35:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_determine_is_class_abstract_real_class_wrapped_with_model_class
+ | expectedIsAbstract actualIsAbstract class |
+
+ class := model classNamed: self class name.
+ expectedIsAbstract := false.
+ generatorOrRefactoring determineIsClassAbstract: class.
+ actualIsAbstract := class isAbstract.
+
+ self assert: expectedIsAbstract = actualIsAbstract
+
+ "Created: / 14-12-2014 / 23:38:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_none_subclass_responsibility
+
+ context selectedClasses: (Array with: mockClass).
+
+ model createMethodImmediate: mockSuperClass protocol: 'instance-protocol' source: 'instanceMethod: aParam
+ ^ self'.
+
+ self assert: (mockClass includesSelector: #instanceMethod:) not.
+ self assert: (mockClass class includesSelector: #instanceMethod:) not.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assert: (mockClass includesSelector: #instanceMethod:) not.
+ self assert: (mockClass class includesSelector: #instanceMethod:) not.
+
+ "Created: / 13-05-2014 / 21:49:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 20:12:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_subclass_responsibility_class_method
+ | expectedSource |
+
+ context selectedClasses: (Array with: mockClass).
+
+ model createMethodImmediate: mockSuperClass class protocol: 'class-protocol' source: 'classMethod: aParam
+ self subclassResponsibility'.
+
+ self assert: (mockClass includesSelector: #classMethod:) not.
+ self assert: (mockClass class includesSelector: #classMethod:) not.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assert: (mockClass includesSelector: #classMethod:) not.
+ self assert: (mockClass class includesSelector: #classMethod:).
+
+ expectedSource := 'classMethod:aParam
+ self shouldImplement'.
+
+ self assertMethodSource: expectedSource atSelector: #classMethod: forClass: mockClass class.
+
+ "Created: / 15-04-2014 / 22:05:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 20:12:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_subclass_responsibility_instance_method
+
+ |expectedSource|
+
+ context selectedClasses: (Array with: mockClass).
+
+ model createMethodImmediate: mockSuperClass protocol: 'instance-protocol' source: 'instanceMethod: aParam
+ self subclassResponsibility'.
+
+ self assert: (mockClass includesSelector: #instanceMethod:) not.
+ self assert: (mockClass class includesSelector: #instanceMethod:) not.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assert: (mockClass includesSelector: #instanceMethod:).
+ self assert: (mockClass class includesSelector: #instanceMethod:) not.
+
+ expectedSource := 'instanceMethod:aParam
+ self shouldImplement'.
+
+ self assertMethodSource: expectedSource atSelector: #instanceMethod: forClass: mockClass.
+
+ "Created: / 14-04-2014 / 18:10:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 20:12:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,343 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomTestCaseCodeGenerator
+ instanceVariableNames:'testClassName testSuperName testClassCategory generateSetUp
+ generateTearDown samePackageAsTestedClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomTestCaseCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ ^ 'Creates a new test case'
+
+ "Created: / 16-09-2014 / 11:32:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Testing')
+
+ "Created: / 05-08-2014 / 14:52:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'New Test Case'
+
+ "Created: / 16-09-2014 / 11:23:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ | classes |
+
+ classes := aCustomContext selectedClasses.
+ ^ classes isEmptyOrNil or:[ classes noneSatisfy: [:cls | cls inheritsFrom: Smalltalk::TestCase ] ].
+
+ "Modified: / 12-06-2015 / 20:45:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ ^aCustomPerspective isClassPerspective
+! !
+
+!CustomTestCaseCodeGenerator methodsFor:'accessing'!
+
+generateSetUp
+ ^ generateSetUp
+!
+
+generateSetUp:aBoolean
+ generateSetUp := aBoolean.
+!
+
+generateTearDown
+ ^ generateTearDown
+!
+
+generateTearDown:aBoolean
+ generateTearDown := aBoolean.
+!
+
+samePackageAsTestedClass
+ "Returns true when we should assign TestCase class
+ to the same package as tested class."
+
+ ^ samePackageAsTestedClass
+
+ "Created: / 15-11-2014 / 11:54:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+samePackageAsTestedClass: aBoolean
+ "see samePackageAsTestedClass"
+
+ samePackageAsTestedClass := aBoolean
+
+ "Created: / 15-11-2014 / 11:56:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+testClassCategory
+ ^ testClassCategory
+!
+
+testClassCategory:aString
+ testClassCategory := aString.
+!
+
+testClassName
+ ^ testClassName
+!
+
+testClassName:aString
+ testClassName := aString.
+!
+
+testSuperName
+ ^ testSuperName
+!
+
+testSuperName:aString
+ testSuperName := aString.
+! !
+
+!CustomTestCaseCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultGenerateSetUp
+ "raise an error: this method should be implemented (TODO)"
+
+ ^ false
+
+ "Created: / 16-09-2014 / 10:27:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+defaultGenerateTearDown
+ "raise an error: this method should be implemented (TODO)"
+
+ ^ false
+
+ "Created: / 16-09-2014 / 10:27:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+defaultSamePackageAsTestedClass
+ "default value for samePackageAsTestedClass"
+
+ ^ true
+
+ "Created: / 15-11-2014 / 12:21:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+defaultSetUpCodeGeneratorClass
+ ^ CustomTestCaseSetUpCodeGenerator
+!
+
+defaultTearDownCodeGeneratorClass
+ ^ CustomTestCaseTearDownCodeGenerator
+!
+
+defaultTestSuperName
+ ^ 'TestCase'
+! !
+
+!CustomTestCaseCodeGenerator methodsFor:'executing - private'!
+
+buildInContext:aCustomContext
+ | classes |
+
+ classes := aCustomContext selectedClasses.
+ classes notEmptyOrNil ifTrue: [
+ classes do: [:cls |
+ | name |
+
+ name := cls theNonMetaClass name , 'Tests'.
+ self generateTestCaseNamed:name forClassUnderTest: cls theNonMetaclass
+ ]
+ ] ifFalse:[
+ self generateTestCaseNamed:testClassName forClassUnderTest: nil .
+ ].
+
+ "Modified: / 16-09-2014 / 10:30:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 23:49:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+configureInContext:aCustomContext
+ | classes |
+
+ classes := aCustomContext selectedClasses.
+ testSuperName := self defaultTestSuperName.
+ classes isEmptyOrNil ifTrue:[
+ testClassName := 'NewTestCase'.
+ testClassCategory := 'Some Tests'
+ ] ifFalse:[
+ classes size == 1 ifTrue:[
+ testClassName := classes anElement theNonMetaclass name , 'Tests'.
+ testClassCategory := classes anElement theNonMetaclass category , '-Tests'.
+ ] ifFalse:[
+ testClassCategory := 'Some Tests'.
+ ].
+ ].
+ generateSetUp := self defaultGenerateSetUp.
+ generateTearDown := self defaultGenerateTearDown.
+ samePackageAsTestedClass := self defaultSamePackageAsTestedClass.
+
+ "/ Now open the dialog...
+
+ classes size <= 1 ifTrue: [
+ dialog
+ addClassNameEntryOn:((AspectAdaptor forAspect:#testClassName)
+ subject:self)
+ labeled:'Class'
+ validateBy:nil.
+ ].
+
+ dialog
+ addClassNameEntryOn:((AspectAdaptor forAspect:#testSuperName)
+ subject:self)
+ labeled:'Superclass'
+ validateBy:nil.
+ dialog
+ addClassCategoryEntryOn:((AspectAdaptor forAspect:#testClassCategory)
+ subject:self)
+ labeled:'Category'
+ validateBy:nil.
+ dialog addSeparator.
+ dialog
+ addCheckBoxOn:((AspectAdaptor forAspect:#generateSetUp) subject:self)
+ labeled:'Generate #setUp'.
+ dialog
+ addCheckBoxOn:((AspectAdaptor forAspect:#generateTearDown) subject:self)
+ labeled:'Generate #tearDown'.
+ dialog
+ addCheckBoxOn:((AspectAdaptor forAspect:#samePackageAsTestedClass) subject:self)
+ labeled:'Same package as tested class'.
+ dialog addButtons.
+ dialog open.
+
+ "Created: / 16-09-2014 / 09:39:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 16-09-2014 / 11:27:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:03:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generateTestCaseCodeFor:testCase forClassUnderTest:anObject
+ self
+ generateTestCaseSetUpCodeFor: testCase;
+ generateTestCaseTearDownCodeFor: testCase.
+
+ "Modified: / 16-09-2014 / 11:16:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+generateTestCaseNamed:testCaseClassName forClassUnderTest:classUnderTest
+ | testCase |
+
+ (testCase := model createClass)
+ superclassName:testSuperName;
+ name:testClassName asSymbol;
+ category:testClassCategory.
+
+ self samePackageAsTestedClass ifTrue: [
+ testCase package: classUnderTest package
+ ].
+
+ testCase compile.
+
+ self generateTestCaseCodeFor:testCase forClassUnderTest:classUnderTest
+
+ "Created: / 16-09-2014 / 10:28:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 15-11-2014 / 15:32:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generateTestCaseSetUpCodeFor: testCase
+ generateSetUp ifTrue: [
+ | subcontext |
+
+ subcontext := CustomSubContext new.
+ subcontext selectedClasses: (Array with: testCase).
+ (self defaultSetUpCodeGeneratorClass subGeneratorOrRefactoringOf: self)
+ samePackageAsTestedClass: self samePackageAsTestedClass;
+ executeInContext: subcontext.
+ ].
+
+ "Created: / 16-09-2014 / 11:15:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-10-2014 / 23:52:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 31-01-2015 / 23:30:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generateTestCaseTearDownCodeFor: testCase
+ generateTearDown ifTrue: [
+ | subcontext |
+
+ subcontext := CustomSubContext new.
+ subcontext selectedClasses: (Array with: testCase).
+ (self defaultTearDownCodeGeneratorClass subGeneratorOrRefactoringOf: self)
+ samePackageAsTestedClass: self samePackageAsTestedClass;
+ executeInContext:subcontext.
+ ].
+
+ "Created: / 16-09-2014 / 11:15:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-10-2014 / 23:52:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 31-01-2015 / 22:14:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,236 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomTestCaseCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomTestCaseCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^CustomTestCaseCodeGenerator new
+! !
+
+!CustomTestCaseCodeGeneratorTests methodsFor:'tests'!
+
+test_available_in_context_classes_all_test_case_subclass
+
+ context selectedClasses: {self class}.
+
+ self deny: (generatorOrRefactoring class availableInContext: context)
+
+ "Created: / 31-01-2015 / 22:05:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_classes_none_test_case_subclass
+
+ context selectedClasses: {Object}.
+
+ self assert: (generatorOrRefactoring class availableInContext: context)
+
+ "Created: / 31-01-2015 / 22:03:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_classes_one_test_case_subclass
+
+ context selectedClasses: {Object. self class}.
+
+ self deny: (generatorOrRefactoring class availableInContext: context)
+
+ "Created: / 31-01-2015 / 22:04:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_empty_classes
+
+ context selectedClasses: #().
+
+ self assert: (generatorOrRefactoring class availableInContext: context)
+
+ "Modified: / 31-01-2015 / 22:01:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_unknown_classes
+
+ context selectedClasses: nil.
+
+ self assert: (generatorOrRefactoring class availableInContext: context)
+
+ "Created: / 31-01-2015 / 22:01:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective
+
+ self assert: (generatorOrRefactoring class availableInPerspective: CustomPerspective classPerspective)
+
+ "Modified: / 31-01-2015 / 22:07:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_class_generated_all_checked
+ | class testClass setUpSource tearDownSource |
+
+ class := self classWithInstanceVariable
+ category: 'Some-Category';
+ package: #some_package_01;
+ yourself.
+
+ self assertClassNotExists: class name.
+
+ context selectedClasses: {class}.
+
+ generatorOrRefactoring
+ configureInContext: context;
+ samePackageAsTestedClass: true;
+ generateSetUp: true;
+ generateTearDown: true;
+ testClassCategory: 'Some-Tests';
+ testClassName: #DummyClassTests;
+ testSuperName: #TestCase;
+ executeInContext: context.
+
+ testClass := Smalltalk at: #DummyClassTests.
+
+ self assert: (testClass package) = #some_package_01.
+ self assert: (testClass superclass name) = #TestCase.
+ self assert: (testClass category) = 'Some-Tests'.
+
+ setUpSource := 'setUp
+ super setUp.
+
+ "Add your own code here..."'.
+ self assertMethodSource: setUpSource atSelector: #setUp forClass: testClass.
+
+ tearDownSource := 'tearDown
+ "Add your own code here..."
+
+ super tearDown.'
+.
+ self assertMethodSource: tearDownSource atSelector: #tearDown forClass: testClass
+
+ "Created: / 31-01-2015 / 23:02:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_class_generated_for_metaclass
+ | class |
+
+ class := self classWithInstanceVariable
+ category: 'Some-Category';
+ yourself.
+
+ self assertClassNotExists: class name.
+
+ context selectedClasses: (Array with: class theMetaclass ).
+ generatorOrRefactoring
+ configureInContext: context;
+ executeInContext: context.
+
+ self assertClassExists: class name
+
+ "Created: / 14-10-2014 / 10:42:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 05-11-2014 / 22:37:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_class_generated_with_package
+ | class testClass |
+
+ class := self classWithInstanceVariable
+ category: 'Some-Category';
+ package: #some_package_01;
+ yourself.
+
+ self assertClassNotExists: class name.
+
+ context selectedClasses: (Array with: class theMetaclass ).
+
+ generatorOrRefactoring
+ configureInContext: context;
+ executeInContext: context.
+
+ self assert: generatorOrRefactoring samePackageAsTestedClass.
+
+ testClass := Smalltalk at: generatorOrRefactoring testClassName asSymbol.
+
+ self assertClassExists: class name.
+ self assert: (testClass package) = #some_package_01.
+
+ "Created: / 15-11-2014 / 15:21:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_class_generated_without_package
+ | class testClass |
+
+ class := self classWithInstanceVariable
+ category: 'Some-Category';
+ package: #some_package_01;
+ yourself.
+
+ self assertClassNotExists: class name.
+
+ context selectedClasses: (Array with: class theMetaclass ).
+
+ generatorOrRefactoring
+ configureInContext: context;
+ samePackageAsTestedClass: false;
+ executeInContext: context.
+
+ testClass := Smalltalk at: generatorOrRefactoring testClassName asSymbol.
+
+ self assertClassExists: class name.
+ self deny: (testClass package) = #some_package_01.
+
+ "Created: / 15-11-2014 / 15:37:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseHelper.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,82 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomTestCaseHelper
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Helpers'
+!
+
+!CustomTestCaseHelper class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Helper class with utility methods used in TestCase generators/refactoring.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomTestCaseHelper methodsFor:'helpers'!
+
+testCategory: aCategory
+ "Returns category based on given category in which should be TestCase located
+ e.g. from Category creates Category-Tests"
+ | suffix |
+
+ suffix := '-Tests'.
+
+ (aCategory asString endsWith: suffix) ifTrue: [
+ ^ aCategory
+ ].
+
+ ^ aCategory asString, suffix.
+
+ "Created: / 30-08-2014 / 20:01:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 08-11-2014 / 21:09:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseHelperTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,90 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomTestCaseHelperTests
+ instanceVariableNames:'testCaseHelper'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Helpers-Tests'
+!
+
+!CustomTestCaseHelperTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseHelperTests methodsFor:'initialization & release'!
+
+setUp
+ super setUp.
+
+ testCaseHelper := CustomTestCaseHelper new
+
+ "Modified: / 08-11-2014 / 21:11:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseHelperTests methodsFor:'tests'!
+
+test_test_category_ending_with_tests
+ | expectedCategory actualCategory |
+
+ expectedCategory := 'Some-Category-Tests'.
+ actualCategory := testCaseHelper testCategory:'Some-Category-Tests'.
+
+ self assert: expectedCategory equals: actualCategory.
+
+ "Created: / 30-08-2014 / 22:06:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-11-2014 / 21:13:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_category_ending_without_tests
+ | expectedCategory actualCategory |
+
+ expectedCategory := 'Some-Category-Tests'.
+ actualCategory := testCaseHelper testCategory:'Some-Category'.
+
+ self assert: expectedCategory equals: actualCategory.
+
+ "Created: / 30-08-2014 / 22:07:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-11-2014 / 21:13:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseMethodCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,235 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomTestCaseMethodCodeGenerator
+ instanceVariableNames:'testMethodSelectors'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomTestCaseMethodCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseMethodCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Creates test method for TestCase from method selection'
+
+ "Created: / 24-08-2014 / 16:16:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Testing')
+
+ "Created: / 05-08-2014 / 14:14:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Test method'
+
+ "Created: / 24-08-2014 / 16:14:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ aCustomContext selectedMethods notEmptyOrNil
+
+ "Created: / 24-08-2014 / 16:18:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ ^ aCustomPerspective isMethodPerspective
+
+ "Created: / 24-08-2014 / 16:16:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator methodsFor:'accessing'!
+
+testMethodSelector:aSelector
+ "Returns how the test case method will be called for particular selector
+ belonging to method to be tested."
+
+ ^ testMethodSelectors at:aSelector asSymbol ifAbsent: [
+ self createTestMethodSelectorFor: aSelector asSymbol
+ ].
+
+ "Created: / 15-10-2014 / 08:19:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+testMethodSelector:aSelector put:aTestMethodName
+ "Sets test method name - see testMethodName:."
+
+ testMethodSelectors at:aSelector asSymbol put:aTestMethodName
+
+ "Created: / 15-10-2014 / 08:21:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator methodsFor:'converting'!
+
+createTestMethodSelectorFor:aMethodSelector
+ "Returns test method selector created from method selector to be tested"
+
+ |testSelector|
+
+ testSelector := 'test_'.
+ aMethodSelector asString do:[:character |
+ character isUppercase ifTrue:[
+ testSelector := testSelector , '_'.
+ ].
+ testSelector := testSelector , character asString toLowerCase
+ ].
+ testSelector replaceAll:$: with:$_.
+ ^testSelector
+
+ "Created: / 15-10-2014 / 09:04:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator methodsFor:'executing - private'!
+
+buildInContext: aCustomContext
+
+ aCustomContext selectedMethods do:[ :method |
+ | class className |
+
+ class := method mclass owningClassOrYourself.
+
+ className := class theNonMetaclass name.
+ (className endsWith: 'Tests') ifFalse: [
+ | testClass |
+
+ className := className, 'Tests'.
+ testClass := Smalltalk classNamed: className.
+ testClass notNil ifTrue: [
+ | testSelector |
+
+ testSelector := self testMethodSelector: method selector.
+ (testClass includesSelector: testSelector asSymbol) ifFalse: [
+ model createMethod
+ package: method package;
+ class: testClass;
+ protocol: 'tests';
+ source: (testSelector, '
+ "/ something ', (method methodDefinitionTemplate asString), '.
+ self assert: 1 = 2.
+ ');
+ compile
+ ].
+ ].
+ ].
+ ].
+
+ "Created: / 24-08-2014 / 16:24:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-11-2014 / 15:01:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (format): / 25-01-2015 / 15:18:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+configureInContext:aCustomContext
+
+ aCustomContext selectedMethods do:[:selectedMethod |
+ | selector |
+
+ selector := selectedMethod selector asSymbol.
+ (testMethodSelectors includesKey: selector) ifFalse: [
+ testMethodSelectors
+ at: selector
+ put: (self createTestMethodSelectorFor: selector).
+ ].
+
+ dialog
+ addSelectorNameEntryOn:(DictionaryAdaptor new
+ subject:testMethodSelectors;
+ aspect:selector)
+ labeled:selector asString
+ validateBy:nil.
+ ].
+
+ dialog addButtons.
+ dialog open.
+
+ "Created: / 15-10-2014 / 08:59:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator methodsFor:'initialization'!
+
+initialize
+
+ super initialize.
+ testMethodSelectors := Dictionary new.
+
+ "Created: / 15-10-2014 / 08:22:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseMethodCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,106 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomTestCaseMethodCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomTestCaseMethodCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseMethodCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomTestCaseMethodCodeGenerator new
+! !
+
+!CustomTestCaseMethodCodeGeneratorTests methodsFor:'tests'!
+
+test_generate_test_method_for_class
+ | expectedSource method class testClass |
+
+ class := model createClassImmediate: #MockClassForTestCase01 superClassName: #Object.
+ testClass := model createClassImmediate: #MockClassForTestCase01Tests.
+ method := model createMethodImmediate: class source: 'selector_01 ^ 1'.
+
+ context selectedMethods: (Array with: method).
+
+ expectedSource := 'test_selector_01
+ "/ something selector_01.
+
+ self assert:1 = 2.'.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertMethodSource:expectedSource atSelector:#test_selector_01 forClass:testClass
+
+ "Created: / 29-11-2014 / 15:04:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generate_test_method_for_private_class
+ | expectedSource privateClass method testClass |
+
+ model createClassImmediate: #MockClassForTestCase01 superClassName: #Object.
+ privateClass := model createClassImmediate: #PrivateClass01 superClassName: #MockClassForTestCase01 privateIn: #MockClassForTestCase01.
+ testClass := model createClassImmediate: #MockClassForTestCase01Tests.
+ method := model createMethodImmediate: privateClass source: 'selector_01 ^ 1'.
+
+ context selectedMethods: (Array with: method).
+
+ expectedSource := 'test_selector_01
+ "/ something selector_01.
+
+ self assert:1 = 2.'.
+
+ generatorOrRefactoring executeInContext: context.
+
+ self assertMethodSource:expectedSource atSelector:#test_selector_01 forClass:testClass
+
+ "Created: / 31-10-2014 / 00:30:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:54:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseSetUpCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,180 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomTestCaseSetUpCodeGenerator
+ instanceVariableNames:'samePackageAsTestedClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomTestCaseSetUpCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseSetUpCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ ^ 'Generates initial #setUp for test cases'
+
+ "Modified: / 16-09-2014 / 11:24:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Testing')
+
+ "Created: / 05-08-2014 / 14:14:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ ^ 'TestCase setUp method'
+
+ "Modified: / 05-08-2014 / 14:13:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseSetUpCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ ^ aCustomContext selectedClasses anySatisfy: [:cls | cls isMetaclass not and:[ cls inheritsFrom: Smalltalk::TestCase ] ]
+
+ "Modified: / 12-06-2015 / 20:46:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ ^ aCustomPerspective isClassPerspective
+
+ "Modified: / 05-08-2014 / 13:49:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseSetUpCodeGenerator methodsFor:'accessing'!
+
+samePackageAsTestedClass
+ "Returns true when we should assign TestCase class
+ to the same package as tested class."
+
+ ^ samePackageAsTestedClass
+
+ "Created: / 15-11-2014 / 11:54:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+samePackageAsTestedClass: aBoolean
+ "see samePackageAsTestedClass"
+
+ samePackageAsTestedClass := aBoolean
+
+ "Created: / 15-11-2014 / 11:56:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseSetUpCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultSamePackageAsTestedClass
+ "default value for samePackageAsTestedClass"
+
+ ^ true
+
+ "Created: / 15-11-2014 / 12:21:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseSetUpCodeGenerator methodsFor:'executing'!
+
+buildForClass: class
+ | source category superHasSetup current package |
+
+ current := class.
+ superHasSetup := false.
+ [ superHasSetup not and:[ current isNil not ] ] whileTrue:[
+ superHasSetup := current includesSelector: #setUp.
+ superHasSetup ifFalse:[
+ current := current superclass.
+ ].
+ ].
+ superHasSetup ifTrue:[
+ source := 'setUp
+ super setUp.
+
+ "Add your own code here..."
+'.
+ category := (current compiledMethodAt: #setUp) category.
+ ] ifFalse:[
+ source := 'setUp
+ "/ super setUp.
+
+ "Add your own code here..."
+'.
+ category := (Smalltalk::TestCase compiledMethodAt: #setUp) category.
+ ].
+
+ package := PackageId noProjectID.
+ samePackageAsTestedClass ? self defaultSamePackageAsTestedClass ifTrue: [
+ package := class package
+ ].
+
+ model createMethod
+ class: class;
+ source: source;
+ category: category;
+ package: package;
+ compile.
+
+ "Created: / 05-08-2014 / 14:17:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 31-01-2015 / 18:32:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 20:46:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+buildInContext:aCustomContext
+ aCustomContext selectedClasses do:[:cls |
+ (cls isMetaclass not and:[ cls inheritsFrom: Smalltalk::TestCase ]) ifTrue:[
+ self buildForClass: cls.
+ ].
+ ]
+
+ "Modified: / 12-06-2015 / 20:46:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseSetUpCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,184 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomTestCaseSetUpCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomTestCaseSetUpCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseSetUpCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomTestCaseSetUpCodeGenerator new
+! !
+
+!CustomTestCaseSetUpCodeGeneratorTests methodsFor:'tests'!
+
+test_set_up_method_generated_default_package
+ | expectedPackage class actualPackage |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ package: #dummy_package01;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedPackage := #dummy_package01.
+ generatorOrRefactoring executeInContext: context.
+ actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #setUp) package.
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 31-01-2015 / 21:26:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_not_same_package
+ | expectedPackage class actualPackage |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ package: #dummy_package01;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedPackage := PackageId noProjectID.
+ generatorOrRefactoring samePackageAsTestedClass: false.
+ generatorOrRefactoring executeInContext: context.
+ actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #setUp) package.
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 31-01-2015 / 21:31:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_same_method_protocol
+ | class expectedCategory actualCategory |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedCategory := (Smalltalk::TestCase compiledMethodAt: #setUp) category.
+ generatorOrRefactoring executeInContext: context.
+ actualCategory := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #setUp) category.
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 31-01-2015 / 21:36:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 20:46:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_same_package
+ | expectedPackage class actualPackage |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ package: #dummy_package01;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedPackage := #dummy_package01.
+ generatorOrRefactoring samePackageAsTestedClass: true.
+ generatorOrRefactoring executeInContext: context.
+ actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #setUp) package.
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 31-01-2015 / 21:30:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_set_up_implemented
+ | expectedSource class |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedSource := 'setUp
+ super setUp.
+
+ "Add your own code here..."'.
+ generatorOrRefactoring executeInContext: context.
+ self assertMethodSource: expectedSource atSelector: #setUp forClass: class
+
+ "Created: / 31-01-2015 / 20:30:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_set_up_not_implemented
+ | expectedSource class |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedSource := 'setUp
+ "/ super setUp.
+ "Add your own code here..."'.
+ generatorOrRefactoring buildForClass: class.
+ self assertMethodSource: expectedSource atSelector: #setUp forClass: class
+
+ "Created: / 31-01-2015 / 20:30:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseTearDownCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,181 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomTestCaseTearDownCodeGenerator
+ instanceVariableNames:'samePackageAsTestedClass'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomTestCaseTearDownCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseTearDownCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ ^ 'Generates initial #tearDown for TestCases'
+
+ "Modified: / 05-08-2014 / 14:50:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Testing')
+
+ "Created: / 05-08-2014 / 14:14:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ ^ 'TestCase tearDown method'
+
+ "Modified: / 05-08-2014 / 14:51:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseTearDownCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ ^ aCustomContext selectedClasses anySatisfy: [:cls | cls isMetaclass not and:[ cls inheritsFrom: Smalltalk::TestCase ] ]
+
+ "Modified: / 12-06-2015 / 20:46:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ ^ aCustomPerspective isClassPerspective
+
+ "Modified: / 05-08-2014 / 13:49:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseTearDownCodeGenerator methodsFor:'accessing'!
+
+samePackageAsTestedClass
+ "Returns true when we should assign TestCase class
+ to the same package as tested class."
+
+ ^ samePackageAsTestedClass
+
+ "Created: / 15-11-2014 / 11:54:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+samePackageAsTestedClass: aBoolean
+ "see samePackageAsTestedClass"
+
+ samePackageAsTestedClass := aBoolean
+
+ "Created: / 15-11-2014 / 11:56:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseTearDownCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultSamePackageAsTestedClass
+ "default value for samePackageAsTestedClass"
+
+ ^ true
+
+ "Created: / 15-11-2014 / 12:21:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseTearDownCodeGenerator methodsFor:'executing'!
+
+buildForClass: class
+ | source category superHasSetup current package |
+
+ current := class.
+ superHasSetup := false.
+ [ superHasSetup not and:[ current isNil not ] ] whileTrue:[
+ superHasSetup := current includesSelector: #tearDown.
+ superHasSetup ifFalse:[
+ current := current superclass.
+ ].
+
+ ].
+ superHasSetup ifTrue:[
+ source := 'tearDown
+ "Add your own code here..."
+
+ super tearDown.
+'.
+ category := (current compiledMethodAt: #tearDown) category.
+ ] ifFalse:[
+ source := 'tearDown
+ "Add your own code here..."
+
+ "/ super tearDown.
+'.
+ category := (Smalltalk::TestCase compiledMethodAt: #tearDown ) category.
+ ].
+
+ package := PackageId noProjectID.
+ samePackageAsTestedClass ? self defaultSamePackageAsTestedClass ifTrue: [
+ package := class package
+ ].
+
+ model createMethod
+ class: class;
+ source: source;
+ category: category;
+ package: package;
+ compile.
+
+ "Created: / 05-08-2014 / 14:17:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 31-01-2015 / 18:34:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 20:46:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+buildInContext:aCustomContext
+ aCustomContext selectedClasses do:[:cls |
+ (cls isMetaclass not and:[ cls inheritsFrom: Smalltalk::TestCase ]) ifTrue:[
+ self buildForClass: cls.
+ ].
+ ]
+
+ "Modified: / 12-06-2015 / 20:44:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseTearDownCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,184 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomTestCaseTearDownCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomTestCaseTearDownCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomTestCaseTearDownCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomTestCaseTearDownCodeGenerator new
+! !
+
+!CustomTestCaseTearDownCodeGeneratorTests methodsFor:'tests'!
+
+test_tear_down_method_generated_default_package
+ | expectedPackage class actualPackage |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ package: #dummy_package01;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedPackage := #dummy_package01.
+ generatorOrRefactoring executeInContext: context.
+ actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #tearDown) package.
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 31-01-2015 / 21:41:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_not_same_package
+ | expectedPackage class actualPackage |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ package: #dummy_package01;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedPackage := PackageId noProjectID.
+ generatorOrRefactoring samePackageAsTestedClass: false.
+ generatorOrRefactoring executeInContext: context.
+ actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #tearDown) package.
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 31-01-2015 / 21:42:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_same_method_protocol
+ | class expectedCategory actualCategory |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedCategory := (Smalltalk::TestCase compiledMethodAt: #tearDown) category.
+ generatorOrRefactoring executeInContext: context.
+ actualCategory := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #tearDown) category.
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 31-01-2015 / 21:42:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 20:47:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_same_package
+ | expectedPackage class actualPackage |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ package: #dummy_package01;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedPackage := #dummy_package01.
+ generatorOrRefactoring samePackageAsTestedClass: true.
+ generatorOrRefactoring executeInContext: context.
+ actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #tearDown) package.
+ self assert: expectedPackage = actualPackage
+
+ "Created: / 31-01-2015 / 21:42:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_tear_down_implemented
+ | expectedSource class |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ superclassName: #TestCase;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedSource := 'tearDown
+ "Add your own code here..."
+
+ super tearDown.'.
+ generatorOrRefactoring executeInContext: context.
+ self assertMethodSource: expectedSource atSelector: #tearDown forClass: class
+
+ "Created: / 31-01-2015 / 21:42:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_tear_down_not_implemented
+ | expectedSource class |
+
+ class := model createClass
+ name: #DummyTestCase01;
+ compile;
+ yourself.
+
+ context selectedClasses: {class}.
+
+ expectedSource := 'tearDown
+ "Add your own code here..."
+ "/ super tearDown.'.
+ generatorOrRefactoring buildForClass: class.
+ self assertMethodSource: expectedSource atSelector: #tearDown forClass: class
+
+ "Created: / 31-01-2015 / 21:41:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUITestCaseCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,92 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomTestCaseCodeGenerator subclass:#CustomUITestCaseCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomUITestCaseCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomUITestCaseCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ ^ 'Creates a new test case for UI'
+
+ "Created: / 16-09-2014 / 11:33:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'New UI Test Case'
+
+ "Created: / 16-09-2014 / 11:23:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomUITestCaseCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultGenerateSetUp
+ ^ true
+
+ "Created: / 16-09-2014 / 11:26:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+defaultSetUpCodeGeneratorClass
+ ^ CustomUITestCaseSetUpCodeGenerator
+
+ "Created: / 16-09-2014 / 11:20:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomUITestCaseCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUITestCaseSetUpCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,68 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomTestCaseSetUpCodeGenerator subclass:#CustomUITestCaseSetUpCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomUITestCaseSetUpCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomUITestCaseSetUpCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ ^ 'Generates initial #setUp for UI test cases'
+
+ "Created: / 16-09-2014 / 11:24:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ ^ 'TestCase setUp method (for UI Test Cases)'
+
+ "Created: / 16-09-2014 / 11:23:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUpdateTestCaseCategoryRefactoring.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,126 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomRefactoring subclass:#CustomUpdateTestCaseCategoryRefactoring
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomUpdateTestCaseCategoryRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomUpdateTestCaseCategoryRefactoring class methodsFor:'accessing-presentation'!
+
+description
+
+ ^ 'Updates TestCase subclasses category with respect to their classes to be tested'
+
+ "Modified: / 08-11-2014 / 18:49:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+
+ ^ 'Update TestCase Category'
+
+ "Modified: / 08-11-2014 / 17:28:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUpdateTestCaseCategoryRefactoring class methodsFor:'queries'!
+
+availableForClass:aClass
+
+ ^ (aClass isSubclassOf: Smalltalk::TestCase) and: [
+ aClass theNonMetaclass name endsWith: 'Tests'
+ ]
+
+ "Created: / 08-11-2014 / 19:03:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 20:43:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInContext:aCustomContext
+
+ ^ aCustomContext selectedClasses ? #() anySatisfy: [ :class |
+ self availableForClass: class
+ ]
+
+ "Modified: / 25-01-2015 / 15:10:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective: aCustomPerspective
+
+ ^ aCustomPerspective isClassPerspective
+
+ "Modified: / 08-11-2014 / 17:27:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUpdateTestCaseCategoryRefactoring methodsFor:'executing - private'!
+
+buildInContext: aCustomContext
+ | testCaseHelper |
+
+ testCaseHelper := CustomTestCaseHelper new.
+
+ aCustomContext selectedClasses ? #() do:[ :class |
+ (self class availableForClass: class) ifTrue: [
+ | testedClassName |
+
+ testedClassName := (class theNonMetaclass name removeSuffix: 'Tests') asSymbol.
+ (model includesClassNamed: testedClassName) ifTrue: [
+ | testCategory |
+
+ testCategory := testCaseHelper
+ testCategory: (model classNamed: testedClassName) category.
+
+ (testCategory = (class category)) ifFalse: [
+ refactoryBuilder changeCategoryOf: class to: testCategory
+ ]
+ ]
+ ]
+ ]
+
+ "Modified: / 08-11-2014 / 21:33:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUpdateTestCaseCategoryRefactoringTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,227 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomUpdateTestCaseCategoryRefactoringTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Refactorings-Tests'
+!
+
+!CustomUpdateTestCaseCategoryRefactoringTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomUpdateTestCaseCategoryRefactoringTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomUpdateTestCaseCategoryRefactoring new
+! !
+
+!CustomUpdateTestCaseCategoryRefactoringTests methodsFor:'tests'!
+
+test_available_for_class_fake_test
+
+ |class|
+
+ class := model createClassImmediate: #Dummy01Tests.
+
+ self deny: (generatorOrRefactoring class availableForClass: class).
+
+ "Created: / 08-11-2014 / 23:40:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_class_object
+
+ self deny: (generatorOrRefactoring class availableForClass: Object).
+
+ "Created: / 08-11-2014 / 23:40:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_class_test_case
+
+ self assert: (generatorOrRefactoring class availableForClass: self class).
+
+ "Modified: / 08-11-2014 / 23:39:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_empty
+
+ self deny: (generatorOrRefactoring class availableInContext: context).
+
+ "Modified: / 08-11-2014 / 23:42:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_with_test_class
+
+ context selectedClasses: (Array with: Object with: self class).
+
+ self assert: (generatorOrRefactoring class availableInContext: context).
+
+ "Created: / 08-11-2014 / 23:43:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_without_test_class
+
+ context selectedClasses: (Array with: Object).
+
+ self deny: (generatorOrRefactoring class availableInContext: context).
+
+ "Created: / 08-11-2014 / 23:44:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective
+
+ self assert: (generatorOrRefactoring class availableInPerspective: CustomPerspective classPerspective).
+
+ "Modified: / 08-11-2014 / 23:45:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_updated_model_classes
+ | expectedCategory actualCategory testClass |
+
+ model createClass
+ name: #DummyClass01;
+ category: #Category01;
+ compile.
+
+ testClass := model createClass
+ name: #DummyClass01Tests;
+ superclassName: #TestCase;
+ category: #Category02;
+ compile;
+ yourself.
+
+ expectedCategory := #'Category01-Tests'.
+
+ context selectedClasses: (Array with: testClass).
+
+ generatorOrRefactoring executeInContext: context.
+
+ actualCategory := testClass category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 08-11-2014 / 23:57:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:16:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_updated_model_classes_category_ok
+ | expectedCategory actualCategory testClass |
+
+ model createClass
+ name: #DummyClass01;
+ category: #Category01;
+ compile.
+
+ testClass := model createClass
+ name: #DummyClass01Tests;
+ superclassName: #TestCase;
+ category: #'Category01-Tests';
+ compile;
+ yourself.
+
+ expectedCategory := #'Category01-Tests'.
+
+ context selectedClasses: (Array with: testClass).
+
+ generatorOrRefactoring executeInContext: context.
+
+ actualCategory := testClass category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 08-11-2014 / 23:58:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:16:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_updated_model_classes_wrong_suffix
+ | expectedCategory actualCategory testClass |
+
+ model createClass
+ name: #DummyClass01;
+ category: #Category01;
+ compile.
+
+ testClass := model createClass
+ name: #DummyClass01Tested;
+ superclassName: #TestCase;
+ category: #Category01;
+ compile;
+ yourself.
+
+ expectedCategory := #Category01.
+
+ context selectedClasses: (Array with: testClass).
+
+ generatorOrRefactoring executeInContext: context.
+
+ actualCategory := testClass category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 09-11-2014 / 00:01:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 16:16:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_updated_real_classes
+ | expectedCategory actualCategory testClass |
+
+ model createClassImmediate: #DummyClass01 category: #Category01.
+ testClass := model createClassImmediate: #DummyClass01Tests superClassName: #TestCase.
+ testClass category: #Category02.
+
+ expectedCategory := #'Category01-Tests'.
+
+ context selectedClasses: (Array with: testClass).
+
+ generatorOrRefactoring executeInContext: context.
+
+ actualCategory := testClass category.
+
+ self assert: expectedCategory = actualCategory
+
+ "Created: / 08-11-2014 / 23:53:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:54:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUserDialog.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,166 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomDialog subclass:#CustomUserDialog
+ instanceVariableNames:'dialog'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-UI'
+!
+
+!CustomUserDialog class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ CustomDialog implementation with real dialogs to provide human interaction.
+ Currently it is a simple wrapper around DialogBox.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomUserDialog class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+! !
+
+!CustomUserDialog methodsFor:'accessing'!
+
+dialog
+ ^ dialog
+!
+
+dialog:something
+ dialog := something.
+! !
+
+!CustomUserDialog methodsFor:'construction-adding'!
+
+addAbortAndOkButtons
+ "Adds buttons Ok and Cancel"
+
+ dialog addAbortAndOkButtons
+
+ "Created: / 15-09-2014 / 16:21:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 09-11-2014 / 22:52:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+addComponent:aView
+ "Add given component. Component is automatically stretched to occupy windows' width"
+
+ ^ dialog addComponent: aView
+
+ "Created: / 15-09-2014 / 18:50:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addComponent:aView labeled:aString
+ "Add a label and some component side-by-side. Returns the component"
+
+"/ aString notEmptyOrNil ifTrue:[
+ ^ dialog
+ addLabelledField:aView
+ label:aString ? ''
+ adjust:#left
+ tabable:true
+ separateAtX:0.3
+"/ ] ifFalse:[
+"/ ^ dialog
+"/ addComponent:aView indent: 0.3
+"/ ].
+
+ "Created: / 15-09-2014 / 15:45:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 15-09-2014 / 19:44:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomUserDialog methodsFor:'initialization'!
+
+initialize
+
+ dialog := DialogBox new
+
+ "Modified: / 15-09-2014 / 16:23:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 21:09:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUserDialog methodsFor:'opening'!
+
+open
+ "Actually opens the dialog. Return true, if dialog has been accepted
+ of raises abort request if it has been cancelled."
+
+ dialog open.
+ dialog accepted ifFalse: [
+ AbortOperationRequest raiseRequest
+ ].
+
+ ^ dialog accepted
+
+ "Created: / 15-09-2014 / 16:23:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 14-11-2014 / 17:52:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 25-11-2014 / 21:08:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUserDialog methodsFor:'user interaction & notifications'!
+
+information: aString
+
+ ^ Dialog information: aString
+
+ "Created: / 02-06-2014 / 22:36:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 22-07-2014 / 21:25:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUserDialog class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderAccessMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderAccessMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Access Method(s) for ValueHolder and selected instance variables'
+
+ "Modified: / 13-07-2014 / 17:00:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Access Method(s) for ValueHolder'
+
+ "Modified: / 13-07-2014 / 17:00:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ "Creates access methods XX for given context"
+
+ self executeSubGeneratorOrRefactoringClasses:(Array
+ with:CustomValueHolderGetterMethodsCodeGenerator
+ with:CustomSimpleSetterMethodsCodeGenerator)
+ inContext:aCustomContext
+
+ "Modified: / 13-07-2014 / 16:59:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderAccessMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,114 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderAccessMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomValueHolderAccessMethodsCodeGenerator new
+! !
+
+!CustomValueHolderAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_access_methods_generated_with_comments
+ | expectedGetterSource expectedSetterSource |
+
+ userPreferences
+ generateCommentsForGetters: true;
+ generateCommentsForSetters: true.
+
+ expectedGetterSource := 'instanceVariable
+ "return/create the ''instanceVariable'' value holder (automatically generated)"
+
+ instanceVariable isNil ifTrue:[
+ instanceVariable := ValueHolder new.
+ ].
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ "set the value of the instance variable ''instanceVariable'' (automatically generated)"
+
+ instanceVariable := something'.
+
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+ "Created: / 13-07-2014 / 17:02:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_access_methods_generated_without_comments
+ | expectedGetterSource expectedSetterSource |
+
+ userPreferences
+ generateCommentsForGetters: false;
+ generateCommentsForSetters: false.
+
+ expectedGetterSource := 'instanceVariable
+ instanceVariable isNil ifTrue:[
+ instanceVariable := ValueHolder new.
+ ].
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ instanceVariable := something'.
+
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+ "Created: / 13-07-2014 / 17:03:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderGetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,126 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderGetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+ ^ 'Getter methods with ValueHolder for selected instance variables'
+
+ "Created: / 19-05-2014 / 20:56:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 30-06-2014 / 19:44:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Getters')
+
+ "Created: / 22-08-2014 / 18:55:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+ ^ 'Getter Method(s) for ValueHolder'
+
+ "Created: / 19-05-2014 / 20:56:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderGetterMethodsCodeGenerator methodsFor:'accessing'!
+
+protocol
+ "Returns protocol name in which will belong getter method"
+
+ ^ 'aspects'
+
+ "Created: / 19-05-2014 / 20:59:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns getter method source code with ValueHolder for given class and variable name"
+
+ | methodName comment |
+
+ methodName := self methodNameFor: aName.
+ comment := ''.
+
+ userPreferences generateCommentsForGetters ifTrue:[
+ comment := '"return/create the ''%1'' value holder (automatically generated)"'.
+ comment := comment bindWith: aName.
+ ].
+
+ ^ self sourceCodeGenerator
+ source: '`@methodName
+ `"comment
+
+ `variableName isNil ifTrue:[
+ `variableName := ValueHolder new.
+ ].
+ ^ `variableName';
+ replace: '`@methodName' with: methodName asSymbol;
+ replace: '`variableName' with: aName asString;
+ replace: '`"comment' with: comment;
+ newSource.
+
+ "Created: / 19-05-2014 / 20:52:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-09-2014 / 22:36:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderGetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,107 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderGetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomValueHolderGetterMethodsCodeGenerator new
+! !
+
+!CustomValueHolderGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_getter_method_generated_with_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: true.
+
+ expectedSource := 'instanceVariable
+ "return/create the ''instanceVariable'' value holder (automatically generated)"
+
+ instanceVariable isNil ifTrue:[
+ instanceVariable := ValueHolder new.
+ ].
+ ^ instanceVariable'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+ "Created: / 14-06-2014 / 11:34:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-06-2014 / 22:44:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_getter_method_generated_without_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: false.
+
+ expectedSource := 'instanceVariable
+ instanceVariable isNil ifTrue:[
+ instanceVariable := ValueHolder new.
+ ].
+ ^ instanceVariable'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+ "Created: / 14-06-2014 / 11:36:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-06-2014 / 22:12:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Access Method(s) for ValueHolder with Change Notification for selected instance variables'
+
+ "Modified: / 13-07-2014 / 17:13:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Access Method(s) for ValueHolder with Change Notification'
+
+ "Modified: / 13-07-2014 / 17:13:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ "Creates access methods XX for given context"
+
+ self executeSubGeneratorOrRefactoringClasses:(Array
+ with:CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator
+ with:CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator)
+ inContext:aCustomContext
+
+ "Modified: / 13-07-2014 / 17:12:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,153 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator new
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_access_methods_generated_with_comments
+ | expectedGetterSource expectedSetterSource |
+
+ userPreferences
+ generateCommentsForGetters: true;
+ generateCommentsForSetters: true.
+
+ expectedGetterSource := 'instanceVariable
+ "return/create the ''instanceVariable'' value holder with change notification (automatically generated)"
+
+ instanceVariable isNil ifTrue:[
+ instanceVariable := ValueHolder new.
+ instanceVariable addDependent:self.
+ ].
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ "set the ''instanceVariable'' value holder (automatically generated)"
+
+ |oldValue newValue|
+
+ instanceVariable notNil ifTrue:[
+ oldValue := instanceVariable value.
+ instanceVariable removeDependent:self.
+ ].
+ instanceVariable := something.
+ instanceVariable notNil ifTrue:[
+ instanceVariable addDependent:self.
+ ].
+ newValue := instanceVariable value.
+ oldValue ~~ newValue ifTrue:[
+ self
+ update:#value
+ with:newValue
+ from:instanceVariable.
+ ].'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+ "Created: / 13-07-2014 / 17:16:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_access_methods_generated_without_comments
+ | expectedGetterSource expectedSetterSource |
+
+ userPreferences
+ generateCommentsForGetters: false;
+ generateCommentsForSetters: false.
+
+ expectedGetterSource := 'instanceVariable
+ instanceVariable isNil ifTrue:[
+ instanceVariable := ValueHolder new.
+ instanceVariable addDependent:self.
+ ].
+ ^ instanceVariable'.
+
+ expectedSetterSource := 'instanceVariable:something
+ |oldValue newValue|
+
+ instanceVariable notNil ifTrue:[
+ oldValue := instanceVariable value.
+ instanceVariable removeDependent:self.
+ ].
+ instanceVariable := something.
+ instanceVariable notNil ifTrue:[
+ instanceVariable addDependent:self.
+ ].
+ newValue := instanceVariable value.
+ oldValue ~~ newValue ifTrue:[
+ self
+ update:#value
+ with:newValue
+ from:instanceVariable.
+ ].'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+ self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+ "Created: / 13-07-2014 / 17:23:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,133 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+ ^ 'Getter methods with ValueHolder and change notification for selected instance variables'
+
+ "Created: / 30-06-2014 / 19:31:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Getters')
+
+ "Created: / 22-08-2014 / 18:55:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+ ^ 'Getter Method(s) for ValueHolder with Change Notification'
+
+ "Created: / 30-06-2014 / 19:36:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator methodsFor:'accessing'!
+
+protocol
+ "Returns protocol name in which will belong getter method"
+
+ ^ 'aspects'
+
+ "Created: / 30-06-2014 / 19:48:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns getter method source code with ValueHolder and change notification for given class and variable name"
+
+ | methodName comment |
+
+ methodName := self methodNameFor: aName.
+ comment := ''.
+
+ userPreferences generateCommentsForGetters ifTrue:[
+ comment := '"return/create the ''%1'' value holder with change notification (automatically generated)"'.
+ comment := comment bindWith: aName.
+ ].
+
+ ^ self sourceCodeGenerator
+ source: '`@methodName
+ `"comment
+
+ `variableName isNil ifTrue:[
+ `variableName := ValueHolder new.
+ `variableName addDependent: self.
+ ].
+ ^ `variableName';
+ replace: '`@methodName' with: methodName asSymbol;
+ replace: '`variableName' with: aName asString;
+ replace: '`"comment' with: comment;
+ newSource.
+
+ "Created: / 30-06-2014 / 19:18:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 19-09-2014 / 22:37:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,107 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator new
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_getter_with_change_notification_method_generated_with_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: true.
+
+ expectedSource := 'instanceVariable
+ "return/create the ''instanceVariable'' value holder with change notification (automatically generated)"
+
+ instanceVariable isNil ifTrue:[
+ instanceVariable := ValueHolder new.
+ instanceVariable addDependent:self.
+ ].
+ ^ instanceVariable'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+ "Created: / 30-06-2014 / 19:54:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_getter_with_change_notification_method_generated_without_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForGetters: false.
+
+ expectedSource := 'instanceVariable
+ instanceVariable isNil ifTrue:[
+ instanceVariable := ValueHolder new.
+ instanceVariable addDependent:self.
+ ].
+ ^ instanceVariable'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+ "Created: / 30-06-2014 / 19:56:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,129 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+ "Returns more detailed description of the receiver"
+
+ ^ 'Setter methods for ValueHolder with Change Notification for selected instance variables'
+
+ "Modified: / 07-07-2014 / 00:02:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+ "Returns a collection strings describing a group to which
+ receiver belongs. A groups may be nested hence the array of
+ strings. For example for subgroup 'Accessors' in group 'Generators'
+ this method should return #('Generators' 'Accessors')."
+
+ "/ By default return an empty array which means the item will appear
+ "/ in top-level group.
+ ^ #('Accessors' 'Setters')
+
+ "Created: / 22-08-2014 / 18:55:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ "Returns show label describing the receiver. This label
+ is used in UI as menu item/tree item label."
+
+ ^ 'Setter Method(s) for ValueHolder with Change Notification'
+
+ "Modified: / 06-07-2014 / 23:59:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+ "Returns setter method for ValueHolder with change notification for given class and variable name"
+
+ | methodName comment argName |
+
+ methodName := self methodNameFor: aName.
+ argName := self argNameForMethodName: methodName.
+ comment := ''.
+
+ userPreferences generateCommentsForSetters ifTrue:[
+ comment := '"set the ''%1'' value holder (automatically generated)"'.
+ comment := comment bindWith: aName.
+ ].
+
+ ^ self sourceCodeGenerator
+ source: '`@methodName
+ `"comment
+
+ | oldValue newValue |
+
+ `variableName notNil ifTrue:[
+ oldValue := `variableName value.
+ `variableName removeDependent: self.
+ ].
+ `variableName := `argName.
+ `variableName notNil ifTrue:[
+ `variableName addDependent: self.
+ ].
+ newValue := `variableName value.
+ oldValue ~~ newValue ifTrue:[
+ self update:#value with:newValue from:`variableName.
+ ].';
+ replace: '`@methodName' with: (methodName, ': ', argName) asSymbol;
+ replace: '`argName' with: argName asString;
+ replace: '`variableName' with: aName asString;
+ replace: '`"comment' with: comment;
+ newSource.
+
+ "Modified: / 19-09-2014 / 22:37:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,131 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator new
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_with_change_notification_setter_method_generated_with_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: true.
+
+ expectedSource := 'instanceVariable:something
+ "set the ''instanceVariable'' value holder (automatically generated)"
+
+ |oldValue newValue|
+
+ instanceVariable notNil ifTrue:[
+ oldValue := instanceVariable value.
+ instanceVariable removeDependent:self.
+ ].
+ instanceVariable := something.
+ instanceVariable notNil ifTrue:[
+ instanceVariable addDependent:self.
+ ].
+ newValue := instanceVariable value.
+ oldValue ~~ newValue ifTrue:[
+ self
+ update:#value
+ with:newValue
+ from:instanceVariable.
+ ].'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+ "Created: / 07-07-2014 / 00:24:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_with_change_notification_setter_method_generated_without_comments
+ | expectedSource |
+
+ userPreferences generateCommentsForSetters: false.
+
+ expectedSource := 'instanceVariable:something
+ |oldValue newValue|
+
+ instanceVariable notNil ifTrue:[
+ oldValue := instanceVariable value.
+ instanceVariable removeDependent:self.
+ ].
+ instanceVariable := something.
+ instanceVariable notNil ifTrue:[
+ instanceVariable addDependent:self.
+ ].
+ newValue := instanceVariable value.
+ oldValue ~~ newValue ifTrue:[
+ self
+ update:#value
+ with:newValue
+ from:instanceVariable.
+ ].'.
+
+ self executeGeneratorInContext: #classWithInstanceVariable.
+ self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+ "Created: / 07-07-2014 / 00:23:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomVisitorCodeGenerator.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,152 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomVisitorCodeGenerator
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomVisitorCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomVisitorCodeGenerator class methodsFor:'accessing'!
+
+description
+ ^ 'Generate methods for visitor pattern'.
+
+ "Created: / 24-07-2013 / 16:39:23 / user"
+ "Modified: / 01-12-2013 / 00:22:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+ ^ 'Visitor and Visited Methods'.
+
+ "Created: / 01-12-2013 / 00:22:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 23-02-2014 / 22:40:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomVisitorCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+ "Returns true if the generator/refactoring is available in given
+ context, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ are available at given point. See class CustomContext for details."
+
+ ^ aCustomContext selectedClasses notEmptyOrNil
+
+ "Modified: / 23-02-2014 / 22:32:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+ "Returns true if the generator/refactoring is available in given
+ perspective, false otherwise.
+
+ Called by the UI to figure out what generators / refactorings
+ to show"
+
+ ^ aCustomPerspective isClassPerspective
+
+ "Created: / 26-01-2014 / 21:40:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 23-02-2014 / 22:33:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isAbstract
+ "Return if this class is an abstract class.
+ True is returned here for myself only; false for subclasses.
+ Abstract subclasses must redefine again."
+
+ ^ self == CustomVisitorCodeGenerator.
+! !
+
+!CustomVisitorCodeGenerator methodsFor:'code generation-individual methods'!
+
+buildAcceptVisitorMethod: selector withParameter: withParameter forClass: aClass
+ "Creates an acceptVisitor: method"
+
+ | comment parameterSelectorPart methodSelector |
+
+ comment := ''.
+ userPreferences generateComments ifTrue: [
+ comment := '"Double dispatch back to the visitor, passing my type encoded in
+ the selector (visitor pattern)"
+
+ "stub code automatically generated - please change if required"'.
+ ].
+
+ methodSelector := 'acceptVisitor: visitor'.
+ parameterSelectorPart := ''.
+ withParameter ifTrue: [
+ parameterSelectorPart := ' with: parameter'.
+ methodSelector := methodSelector, parameterSelectorPart.
+ ].
+
+ model createMethod
+ class: aClass;
+ protocol: 'visiting';
+ source: ('`@methodSelector
+ `"comment
+
+ ^ visitor `@selector self `@parameterSelectorPart
+ ');
+ replace: '`@methodSelector' with: methodSelector;
+ replace: '`@selector' with: selector asSymbol;
+ replace: '`"comment' with: comment;
+ replace: '`@parameterSelectorPart' with: parameterSelectorPart;
+ compile.
+
+ "Created: / 27-07-2014 / 01:08:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 08-10-2014 / 14:47:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomVisitorCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,89 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomVisitorCodeGenerator subclass:#CustomVisitorCodeGeneratorAcceptVisitor
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomVisitorCodeGeneratorAcceptVisitor class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomVisitorCodeGeneratorAcceptVisitor class methodsFor:'accessing'!
+
+description
+ ^ 'Method for visitor pattern - acceptVisitor'.
+
+ "Created: / 09-03-2014 / 20:38:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 27-07-2014 / 00:58:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+ ^ 'Visitor Method'.
+
+ "Created: / 09-03-2014 / 20:38:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomVisitorCodeGeneratorAcceptVisitor methodsFor:'executing'!
+
+buildInContext: aCustomContext
+ "Builds acceptVisitor method"
+
+ aCustomContext selectedClasses do: [ :class |
+ | selector |
+
+ selector := ('visit', class nameWithoutPrefix) asMutator.
+
+ self
+ buildAcceptVisitorMethod: selector
+ withParameter: false
+ forClass: class
+ ].
+
+ "Created: / 19-03-2014 / 18:32:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 03-08-2014 / 23:31:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomVisitorCodeGeneratorAcceptVisitorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,96 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomVisitorCodeGeneratorAcceptVisitorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomVisitorCodeGeneratorAcceptVisitorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomVisitorCodeGeneratorAcceptVisitorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomVisitorCodeGeneratorAcceptVisitor new
+! !
+
+!CustomVisitorCodeGeneratorAcceptVisitorTests methodsFor:'tests'!
+
+test_accept_visitor_method_generated_with_comments
+ |expectedSource|
+
+ userPreferences generateComments: true.
+
+ expectedSource := 'acceptVisitor:visitor
+ "Double dispatch back to the visitor, passing my type encoded in
+the selector (visitor pattern)"
+ "stub code automatically generated - please change if required"
+
+ ^ visitor visitDummyClassForGeneratorTestCase:self'.
+
+ self executeGeneratorInContext:#classWithInstanceVariable.
+ self assertMethodSource:expectedSource atSelector:#acceptVisitor:
+
+ "Created: / 03-08-2014 / 23:06:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 21:00:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_accept_visitor_method_generated_without_comments
+ |expectedSource|
+
+ userPreferences generateComments: false.
+
+ expectedSource := 'acceptVisitor:visitor
+ ^ visitor visitDummyClassForGeneratorTestCase:self'.
+
+ self executeGeneratorInContext:#classWithInstanceVariable.
+ self assertMethodSource:expectedSource atSelector:#acceptVisitor:
+
+ "Created: / 03-08-2014 / 23:33:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 21:13:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomVisitorCodeGeneratorTests.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,166 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomVisitorCodeGeneratorTests
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomVisitorCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!CustomVisitorCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+ ^ CustomVisitorCodeGenerator new
+! !
+
+!CustomVisitorCodeGeneratorTests methodsFor:'tests'!
+
+test_accept_visitor_method_generated_with_comment_and_with_parameter
+ "check if methods for visitor pattern are correctly generated"
+ | expectedSource class |
+
+ userPreferences generateComments: true.
+
+ expectedSource := 'acceptVisitor:visitor with:parameter
+ "Double dispatch back to the visitor, passing my type encoded in
+the selector (visitor pattern)"
+ "stub code automatically generated - please change if required"
+
+ ^ visitor visitDummyTestClassForVisitorMethod:self with:parameter'.
+
+ class := model createClassImmediate: 'DummyTestClassForVisitorMethod'.
+
+ generatorOrRefactoring
+ buildAcceptVisitorMethod: 'visitDummyTestClassForVisitorMethod:'
+ withParameter: true
+ forClass: class.
+
+ generatorOrRefactoring model execute.
+
+ self assertMethodSource: expectedSource atSelector: #acceptVisitor:with: forClass: class
+
+ "Created: / 27-07-2014 / 12:32:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 20:59:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_accept_visitor_method_generated_with_comment_and_without_parameter
+ "check if methods for visitor pattern are correctly generated"
+ | expectedSource class |
+
+ userPreferences generateComments: true.
+
+ expectedSource := 'acceptVisitor:visitor
+ "Double dispatch back to the visitor, passing my type encoded in
+the selector (visitor pattern)"
+ "stub code automatically generated - please change if required"
+
+ ^ visitor visitDummyTestClassForVisitorMethod:self'.
+
+ class := model createClassImmediate: 'DummyTestClassForVisitorMethod'.
+
+ generatorOrRefactoring
+ buildAcceptVisitorMethod: 'visitDummyTestClassForVisitorMethod:'
+ withParameter: false
+ forClass: class.
+
+ generatorOrRefactoring model execute.
+
+ self assertMethodSource: expectedSource atSelector: #acceptVisitor: forClass: class
+
+ "Created: / 03-08-2014 / 22:50:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 20:59:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_accept_visitor_method_generated_without_comment_and_with_parameter
+ "check if methods for visitor pattern are correctly generated"
+ | expectedSource class |
+
+ userPreferences generateComments: false.
+
+ expectedSource := 'acceptVisitor:visitor with:parameter
+ ^ visitor visitDummyTestClassForVisitorMethod:self with:parameter'.
+
+ class := model createClassImmediate: 'DummyTestClassForVisitorMethod'.
+
+ generatorOrRefactoring
+ buildAcceptVisitorMethod: 'visitDummyTestClassForVisitorMethod:'
+ withParameter: true
+ forClass: class.
+
+ generatorOrRefactoring model execute.
+
+ self assertMethodSource: expectedSource atSelector: #acceptVisitor:with: forClass: class
+
+ "Created: / 03-08-2014 / 22:53:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 20:59:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_accept_visitor_method_generated_without_comment_and_without_parameter
+ "check if methods for visitor pattern are correctly generated"
+ | expectedSource class |
+
+ userPreferences generateComments: false.
+
+ expectedSource := 'acceptVisitor:visitor
+ ^ visitor visitDummyTestClassForVisitorMethod:self'.
+
+ class := model createClassImmediate: 'DummyTestClassForVisitorMethod'.
+
+ generatorOrRefactoring
+ buildAcceptVisitorMethod: 'visitDummyTestClassForVisitorMethod:'
+ withParameter: false
+ forClass: class.
+
+ generatorOrRefactoring model execute.
+
+ self assertMethodSource: expectedSource atSelector: #acceptVisitor: forClass: class
+
+ "Created: / 03-08-2014 / 22:51:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-08-2014 / 21:00:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/abbrev.stc Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,127 @@
+# automagically generated by the project definition
+# this file is needed for stc to be able to compile modules independently.
+# it provides information about a classes filename, category and especially namespace.
+SmallSense::CustomBrowserEnvironmentTests SmallSense__CustomBrowserEnvironmentTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomChangeManager SmallSense__CustomChangeManager stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomClassQuery SmallSense__CustomClassQuery stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Helpers' 0
+SmallSense::CustomClassQueryTests SmallSense__CustomClassQueryTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Helpers-Tests' 1
+SmallSense::CustomCodeGeneratorOrRefactoring SmallSense__CustomCodeGeneratorOrRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomCodeGeneratorOrRefactoringTestCase SmallSense__CustomCodeGeneratorOrRefactoringTestCase stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomContext SmallSense__CustomContext stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomContextTests SmallSense__CustomContextTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomDialog SmallSense__CustomDialog stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI' 0
+SmallSense::CustomLocalChangeManagerTests SmallSense__CustomLocalChangeManagerTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomManager SmallSense__CustomManager stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomManagerTests SmallSense__CustomManagerTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomMenuBuilder SmallSense__CustomMenuBuilder stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI' 0
+SmallSense::CustomMenuBuilderTests SmallSense__CustomMenuBuilderTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI-Tests' 1
+SmallSense::CustomMock SmallSense__CustomMock stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 0
+SmallSense::CustomMockTests SmallSense__CustomMockTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomNamespace SmallSense__CustomNamespace stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomNewSystemBrowserTests SmallSense__CustomNewSystemBrowserTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI-Tests' 1
+SmallSense::CustomNoneSourceCodeFormatterTests SmallSense__CustomNoneSourceCodeFormatterTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomParseTreeRewriter SmallSense__CustomParseTreeRewriter stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomParseTreeRewriterTests SmallSense__CustomParseTreeRewriterTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomPerspective SmallSense__CustomPerspective stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 1
+SmallSense::CustomPerspectiveTests SmallSense__CustomPerspectiveTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBAbstractClassTests SmallSense__CustomRBAbstractClassTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBClassTests SmallSense__CustomRBClassTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBLocalSourceCodeFormatterTests SmallSense__CustomRBLocalSourceCodeFormatterTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBMetaclassTests SmallSense__CustomRBMetaclassTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBMethodTests SmallSense__CustomRBMethodTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRefactoryBuilder SmallSense__CustomRefactoryBuilder stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomRefactoryClassChangeTests SmallSense__CustomRefactoryClassChangeTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomSourceCodeFormatter SmallSense__CustomSourceCodeFormatter stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomSourceCodeGenerator SmallSense__CustomSourceCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomSourceCodeGeneratorTests SmallSense__CustomSourceCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomSourceCodeSelection SmallSense__CustomSourceCodeSelection stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomSourceCodeSelectionTests SmallSense__CustomSourceCodeSelectionTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomSubContextTests SmallSense__CustomSubContextTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomTestCaseHelper SmallSense__CustomTestCaseHelper stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Helpers' 0
+SmallSense::CustomTestCaseHelperTests SmallSense__CustomTestCaseHelperTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Helpers-Tests' 1
+jn_refactoring_custom jn_refactoring_custom stx:goodies/smallsense/refactoring_custom '* Projects & Packages *' 3
+SmallSense::CustomAccessMethodsCodeGeneratorTests SmallSense__CustomAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomAddClassChangeTests SmallSense__CustomAddClassChangeTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomAddMethodChangeTests SmallSense__CustomAddMethodChangeTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomBrowserChangeManager SmallSense__CustomBrowserChangeManager stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomBrowserContext SmallSense__CustomBrowserContext stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomBrowserContextTests SmallSense__CustomBrowserContextTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomChangeNotificationAccessMethodsCodeGeneratorTests SmallSense__CustomChangeNotificationAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomChangeNotificationSetterMethodsCodeGeneratorTests SmallSense__CustomChangeNotificationSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomCodeGenerator SmallSense__CustomCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeGeneratorClassGeneratorTests SmallSense__CustomCodeGeneratorClassGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomCodeGeneratorOrRefactoringTests SmallSense__CustomCodeGeneratorOrRefactoringTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomCodeGeneratorTests SmallSense__CustomCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomCodeGeneratorUserPreferencesTests SmallSense__CustomCodeGeneratorUserPreferencesTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomCodeSelectionToResourceTranslationTests SmallSense__CustomCodeSelectionToResourceTranslationTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings-Tests' 1
+SmallSense::CustomDefaultGetterMethodsCodeGeneratorTests SmallSense__CustomDefaultGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomIsAbstractCodeGeneratorTests SmallSense__CustomIsAbstractCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomLazyInitializationAccessMethodsCodeGeneratorTests SmallSense__CustomLazyInitializationAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomLazyInitializationGetterMethodsCodeGeneratorTests SmallSense__CustomLazyInitializationGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomLocalChangeManager SmallSense__CustomLocalChangeManager stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomMultiSetterMethodsCodeGeneratorTests SmallSense__CustomMultiSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomNamespaceTests SmallSense__CustomNamespaceTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomNewClassGeneratorTests SmallSense__CustomNewClassGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomNoneSourceCodeFormatter SmallSense__CustomNoneSourceCodeFormatter stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomRBLocalSourceCodeFormatter SmallSense__CustomRBLocalSourceCodeFormatter stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomRefactoring SmallSense__CustomRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomRefactoringClassGeneratorTests SmallSense__CustomRefactoringClassGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomRefactoryBuilderTests SmallSense__CustomRefactoryBuilderTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomReplaceIfNilWithIfTrueRefactoringTests SmallSense__CustomReplaceIfNilWithIfTrueRefactoringTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings-Tests' 1
+SmallSense::CustomSilentDialog SmallSense__CustomSilentDialog stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI' 0
+SmallSense::CustomSimpleAccessMethodsCodeGeneratorTests SmallSense__CustomSimpleAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomSimpleGetterMethodsCodeGeneratorTests SmallSense__CustomSimpleGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomSimpleSetterMethodsCodeGeneratorTests SmallSense__CustomSimpleSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomSubContext SmallSense__CustomSubContext stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomSubclassResponsibilityCodeGeneratorTests SmallSense__CustomSubclassResponsibilityCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomTestCaseCodeGeneratorTests SmallSense__CustomTestCaseCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomTestCaseMethodCodeGeneratorTests SmallSense__CustomTestCaseMethodCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomTestCaseSetUpCodeGeneratorTests SmallSense__CustomTestCaseSetUpCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomTestCaseTearDownCodeGeneratorTests SmallSense__CustomTestCaseTearDownCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomUpdateTestCaseCategoryRefactoringTests SmallSense__CustomUpdateTestCaseCategoryRefactoringTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings-Tests' 1
+SmallSense::CustomUserDialog SmallSense__CustomUserDialog stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI' 0
+SmallSense::CustomValueHolderAccessMethodsCodeGeneratorTests SmallSense__CustomValueHolderAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomValueHolderGetterMethodsCodeGeneratorTests SmallSense__CustomValueHolderGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomVisitorCodeGeneratorAcceptVisitorTests SmallSense__CustomVisitorCodeGeneratorAcceptVisitorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomVisitorCodeGeneratorTests SmallSense__CustomVisitorCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomAccessMethodsCodeGenerator SmallSense__CustomAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeSelectionRefactoring SmallSense__CustomCodeSelectionRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomInspectorTabCodeGenerator SmallSense__CustomInspectorTabCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomIsAbstractCodeGenerator SmallSense__CustomIsAbstractCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomJavaSimpleSetterMethodsCodeGenerator SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomNewClassGenerator SmallSense__CustomNewClassGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomReplaceIfNilWithIfTrueRefactoring SmallSense__CustomReplaceIfNilWithIfTrueRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomSubclassResponsibilityCodeGenerator SmallSense__CustomSubclassResponsibilityCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomTestCaseCodeGenerator SmallSense__CustomTestCaseCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomTestCaseMethodCodeGenerator SmallSense__CustomTestCaseMethodCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomTestCaseSetUpCodeGenerator SmallSense__CustomTestCaseSetUpCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomTestCaseTearDownCodeGenerator SmallSense__CustomTestCaseTearDownCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomUpdateTestCaseCategoryRefactoring SmallSense__CustomUpdateTestCaseCategoryRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomVisitorCodeGenerator SmallSense__CustomVisitorCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomChangeNotificationAccessMethodsCodeGenerator SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomChangeNotificationSetterMethodsCodeGenerator SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeGeneratorClassGenerator SmallSense__CustomCodeGeneratorClassGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeSelectionToResourceTranslation SmallSense__CustomCodeSelectionToResourceTranslation stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomDefaultGetterMethodsCodeGenerator SmallSense__CustomDefaultGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomLazyInitializationAccessMethodsCodeGenerator SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomLazyInitializationGetterMethodsCodeGenerator SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomMultiSetterMethodsCodeGenerator SmallSense__CustomMultiSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomPrintCodeSelectionRefactoring SmallSense__CustomPrintCodeSelectionRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomRefactoringClassGenerator SmallSense__CustomRefactoringClassGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomSimpleAccessMethodsCodeGenerator SmallSense__CustomSimpleAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomSimpleGetterMethodsCodeGenerator SmallSense__CustomSimpleGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomSimpleSetterMethodsCodeGenerator SmallSense__CustomSimpleSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomUITestCaseCodeGenerator SmallSense__CustomUITestCaseCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomUITestCaseSetUpCodeGenerator SmallSense__CustomUITestCaseSetUpCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderAccessMethodsCodeGenerator SmallSense__CustomValueHolderAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderGetterMethodsCodeGenerator SmallSense__CustomValueHolderGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomVisitorCodeGeneratorAcceptVisitor SmallSense__CustomVisitorCodeGeneratorAcceptVisitor stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGenerator SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/bc.mak Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,159 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# Notice, that the name bc.mak is historical (from times, when only borland c was supported).
+# This file contains make rules for the win32 platform using either borland-bcc or visual-c.
+# It shares common definitions with the unix-make in Make.spec.
+# The bc.mak supports the following targets:
+# bmake - compile all st-files to a classLib (dll)
+# bmake clean - clean all temp files
+# bmake clobber - clean all
+#
+# Historic Note:
+# this used to contain only rules to make with borland
+# (called via bmake, by "make.exe -f bc.mak")
+# this has changed; it is now also possible to build using microsoft visual c
+# (called via vcmake, by "make.exe -f bc.mak -DUSEVC")
+#
+TOP=..\..\stx
+INCLUDE_TOP=$(TOP)\..
+
+
+
+!INCLUDE $(TOP)\rules\stdHeader_bc
+
+!INCLUDE Make.spec
+
+LIBNAME=libstx_goodies_smallsense_refactoring_custom
+MODULE_PATH=refactoring_custom
+RESFILES=refactoring_custom.$(RES)
+
+
+
+LOCALINCLUDES= -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser -I$(INCLUDE_TOP)\stx\goodies\smallsense -I$(INCLUDE_TOP)\stx\goodies\sunit -I$(INCLUDE_TOP)\stx\libbasic -I$(INCLUDE_TOP)\stx\libbasic3 -I$(INCLUDE_TOP)\stx\libcomp -I$(INCLUDE_TOP)\stx\libjava -I$(INCLUDE_TOP)\stx\libjava\tools -I$(INCLUDE_TOP)\stx\libjavascript -I$(INCLUDE_TOP)\stx\libtool -I$(INCLUDE_TOP)\stx\libview -I$(INCLUDE_TOP)\stx\libview2 -I$(INCLUDE_TOP)\stx\libwidg -I$(INCLUDE_TOP)\stx\libwidg2
+LOCALDEFINES=
+
+STCLOCALOPT=-package=$(PACKAGE) -I. $(LOCALINCLUDES) -headerDir=. $(STCLOCALOPTIMIZATIONS) $(STCWARNINGS) $(LOCALDEFINES) -varPrefix=$(LIBNAME)
+LOCALLIBS=
+
+OBJS= $(COMMON_OBJS) $(WIN32_OBJS)
+
+ALL:: classLibRule
+
+classLibRule: $(OUTDIR) $(OUTDIR)$(LIBNAME).dll
+
+!INCLUDE $(TOP)\rules\stdRules_bc
+
+# build all mandatory prerequisite packages (containing superclasses) for this package
+prereq:
+ pushd ..\..\stx\libbasic & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\goodies\refactoryBrowser\changes & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\goodies\refactoryBrowser\helpers & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\goodies\refactoryBrowser\parser & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libbasic2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libbasic3 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libcomp & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libui & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libview & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libview2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\goodies\sunit & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libwidg & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libwidg2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+ pushd ..\..\stx\libtool & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+
+
+
+
+
+
+
+test: $(TOP)\goodies\builder\reports\NUL
+ pushd $(TOP)\goodies\builder\reports & $(MAKE_BAT)
+ $(TOP)\goodies\builder\reports\report-runner.bat -D . -r Builder::TestReport -p $(PACKAGE)
+
+clean::
+ del *.$(CSUFFIX)
+
+
+# BEGINMAKEDEPEND --- do not remove this line; make depend needs it
+$(OUTDIR)SmallSense__CustomChangeManager.$(O) SmallSense__CustomChangeManager.$(H): SmallSense__CustomChangeManager.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomClassQuery.$(O) SmallSense__CustomClassQuery.$(H): SmallSense__CustomClassQuery.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorOrRefactoring.$(O) SmallSense__CustomCodeGeneratorOrRefactoring.$(H): SmallSense__CustomCodeGeneratorOrRefactoring.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomContext.$(O) SmallSense__CustomContext.$(H): SmallSense__CustomContext.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomDialog.$(O) SmallSense__CustomDialog.$(H): SmallSense__CustomDialog.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomManager.$(O) SmallSense__CustomManager.$(H): SmallSense__CustomManager.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMenuBuilder.$(O) SmallSense__CustomMenuBuilder.$(H): SmallSense__CustomMenuBuilder.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMock.$(O) SmallSense__CustomMock.$(H): SmallSense__CustomMock.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNamespace.$(O) SmallSense__CustomNamespace.$(H): SmallSense__CustomNamespace.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBNamespace.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomParseTreeRewriter.$(O) SmallSense__CustomParseTreeRewriter.$(H): SmallSense__CustomParseTreeRewriter.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\ParseTreeRewriter.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\ParseTreeSearcher.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\ParseTreeSourceRewriter.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBProgramNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomPerspective.$(O) SmallSense__CustomPerspective.$(H): SmallSense__CustomPerspective.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoryBuilder.$(O) SmallSense__CustomRefactoryBuilder.$(H): SmallSense__CustomRefactoryBuilder.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeFormatter.$(O) SmallSense__CustomSourceCodeFormatter.$(H): SmallSense__CustomSourceCodeFormatter.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeGenerator.$(O) SmallSense__CustomSourceCodeGenerator.$(H): SmallSense__CustomSourceCodeGenerator.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBProgramNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\CodeGenerator.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeSelection.$(O) SmallSense__CustomSourceCodeSelection.$(H): SmallSense__CustomSourceCodeSelection.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseHelper.$(O) SmallSense__CustomTestCaseHelper.$(H): SmallSense__CustomTestCaseHelper.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)stx_goodies_smallsense_refactoring_custom.$(O) stx_goodies_smallsense_refactoring_custom.$(H): stx_goodies_smallsense_refactoring_custom.st $(INCLUDE_TOP)\stx\libbasic\LibraryDefinition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomBrowserChangeManager.$(O) SmallSense__CustomBrowserChangeManager.$(H): SmallSense__CustomBrowserChangeManager.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomChangeManager.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomBrowserContext.$(O) SmallSense__CustomBrowserContext.$(H): SmallSense__CustomBrowserContext.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomContext.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGenerator.$(O) SmallSense__CustomCodeGenerator.$(H): SmallSense__CustomCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLocalChangeManager.$(O) SmallSense__CustomLocalChangeManager.$(H): SmallSense__CustomLocalChangeManager.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomChangeManager.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNoneSourceCodeFormatter.$(O) SmallSense__CustomNoneSourceCodeFormatter.$(H): SmallSense__CustomNoneSourceCodeFormatter.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomSourceCodeFormatter.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRBLocalSourceCodeFormatter.$(O) SmallSense__CustomRBLocalSourceCodeFormatter.$(H): SmallSense__CustomRBLocalSourceCodeFormatter.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomSourceCodeFormatter.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoring.$(O) SmallSense__CustomRefactoring.$(H): SmallSense__CustomRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSilentDialog.$(O) SmallSense__CustomSilentDialog.$(H): SmallSense__CustomSilentDialog.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSubContext.$(O) SmallSense__CustomSubContext.$(H): SmallSense__CustomSubContext.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomContext.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUserDialog.$(O) SmallSense__CustomUserDialog.$(H): SmallSense__CustomUserDialog.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomAccessMethodsCodeGenerator.$(O) SmallSense__CustomAccessMethodsCodeGenerator.$(H): SmallSense__CustomAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeSelectionRefactoring.$(O) SmallSense__CustomCodeSelectionRefactoring.$(H): SmallSense__CustomCodeSelectionRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomInspectorTabCodeGenerator.$(O) SmallSense__CustomInspectorTabCodeGenerator.$(H): SmallSense__CustomInspectorTabCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomIsAbstractCodeGenerator.$(O) SmallSense__CustomIsAbstractCodeGenerator.$(H): SmallSense__CustomIsAbstractCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNewClassGenerator.$(O) SmallSense__CustomNewClassGenerator.$(H): SmallSense__CustomNewClassGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(O) SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(H): SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSubclassResponsibilityCodeGenerator.$(O) SmallSense__CustomSubclassResponsibilityCodeGenerator.$(H): SmallSense__CustomSubclassResponsibilityCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseCodeGenerator.$(O) SmallSense__CustomTestCaseCodeGenerator.$(H): SmallSense__CustomTestCaseCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseMethodCodeGenerator.$(O) SmallSense__CustomTestCaseMethodCodeGenerator.$(H): SmallSense__CustomTestCaseMethodCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseSetUpCodeGenerator.$(O) SmallSense__CustomTestCaseSetUpCodeGenerator.$(H): SmallSense__CustomTestCaseSetUpCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseTearDownCodeGenerator.$(O) SmallSense__CustomTestCaseTearDownCodeGenerator.$(H): SmallSense__CustomTestCaseTearDownCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(O) SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(H): SmallSense__CustomUpdateTestCaseCategoryRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomVisitorCodeGenerator.$(O) SmallSense__CustomVisitorCodeGenerator.$(H): SmallSense__CustomVisitorCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(O) SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(H): SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(O) SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(H): SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorClassGenerator.$(O) SmallSense__CustomCodeGeneratorClassGenerator.$(H): SmallSense__CustomCodeGeneratorClassGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomNewClassGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(O) SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(H): SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomTestCaseCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeSelectionToResourceTranslation.$(O) SmallSense__CustomCodeSelectionToResourceTranslation.$(H): SmallSense__CustomCodeSelectionToResourceTranslation.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeSelectionRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(O) SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(H): SmallSense__CustomDefaultGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(O) SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(H): SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(O) SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(H): SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMultiSetterMethodsCodeGenerator.$(O) SmallSense__CustomMultiSetterMethodsCodeGenerator.$(H): SmallSense__CustomMultiSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomPrintCodeSelectionRefactoring.$(O) SmallSense__CustomPrintCodeSelectionRefactoring.$(H): SmallSense__CustomPrintCodeSelectionRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeSelectionRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoringClassGenerator.$(O) SmallSense__CustomRefactoringClassGenerator.$(H): SmallSense__CustomRefactoringClassGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomNewClassGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(O) SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(H): SmallSense__CustomSimpleAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(O) SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(H): SmallSense__CustomSimpleGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUITestCaseCodeGenerator.$(O) SmallSense__CustomUITestCaseCodeGenerator.$(H): SmallSense__CustomUITestCaseCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomTestCaseCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUITestCaseSetUpCodeGenerator.$(O) SmallSense__CustomUITestCaseSetUpCodeGenerator.$(H): SmallSense__CustomUITestCaseSetUpCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomTestCaseSetUpCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(O) SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(H): SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomVisitorCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes\AddClassChange.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes\AddMethodChange.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes\RefactoryChange.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes\RefactoryClassChange.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBAbstractClass.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBClass.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBMetaclass.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBMethod.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\SystemBrowser.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__NewSystemBrowser.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(STCHDR)
+
+# ENDMAKEDEPEND --- do not remove this line
+
+# **Must be at end**
+
+# Enforce recompilation of package definition class if Mercurial working
+# copy state changes. Together with --guessVersion it ensures that package
+# definition class always contains correct binary revision string.
+!IFDEF HGROOT
+$(OUTDIR)stx_goodies_smallsense_refactoring_custom.$(O): $(HGROOT)\.hg\dirstate
+!ENDIF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/bmake.bat Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,12 @@
+@REM -------
+@REM make using Borland bcc32
+@REM type bmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+make.exe -N -f bc.mak %DEFINES% %*
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/extensions.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,998 @@
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"!
+
+!AddClassChange methodsFor:'private'!
+
+argumensBySelectorPartsFromMessage: aMessageNode
+ "Returns message arguments as dictionary indexed by selector part name.
+ For example: sel01:arg01 sel02:arg02 should be indexed
+ 'sel01:' -> 'arg01',
+ 'sel02:' -> 'arg02' "
+ | argumensBySelectorParts selectorParts |
+
+ argumensBySelectorParts := Dictionary new.
+ selectorParts := aMessageNode selectorParts ? #().
+ aMessageNode arguments ? #() keysAndValuesDo: [ :key :argument |
+ | part |
+
+ part := selectorParts at: key ifAbsent: key.
+ part == key ifFalse: [
+ "We found appropriate selector part"
+ part := part value asSymbol
+ ].
+ argumensBySelectorParts at: part put: argument.
+ ].
+
+ ^ argumensBySelectorParts
+
+ "Created: / 16-11-2014 / 14:47:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddClassChange methodsFor:'accessing'!
+
+package
+
+ ^ package
+
+ "Created: / 09-10-2014 / 23:45:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddClassChange methodsFor:'accessing'!
+
+package: aPackageName
+
+ package := aPackageName
+
+ "Created: / 08-10-2014 / 20:07:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddClassChange methodsFor:'accessing'!
+
+privateInClassName
+ "Returns privateIn class name (when this class is a private class of another class)"
+
+ ^ self objectAttributeAt: #privateInClassName
+
+ "Created: / 16-11-2014 / 14:18:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddClassChange methodsFor:'accessing'!
+
+privateInClassName:aClassName
+ "see privateInClassName"
+
+ self objectAttributeAt: #privateInClassName put: aClassName
+
+ "Created: / 16-11-2014 / 14:18:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddMethodChange methodsFor:'accessing'!
+
+package: aPackageName
+
+ package := aPackageName
+
+ "Created: / 08-10-2014 / 19:59:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+allClassVarNames
+ | variableNames |
+
+ variableNames := self allClassVariableNames.
+
+ variableNames isNil ifTrue: [
+ ^ #()
+ ].
+
+ ^ variableNames
+
+ "Created: / 01-06-2014 / 23:40:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 20-09-2014 / 19:26:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'enumerating'!
+
+allSuperclassesDo: aBlock
+ | superclass |
+
+ superclass := self superclass.
+
+ superclass notNil ifTrue: [
+ superclass withAllSuperclassesDo: aBlock
+ ].
+
+ "Created: / 21-04-2014 / 19:15:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 14:42:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'method accessing'!
+
+compileMethod: anRBMethod
+ "Creates new method for this class with RBClass"
+ | change method newSource |
+
+ newSource := anRBMethod newSource.
+
+ change := model
+ compile: newSource
+ in: self
+ classified: anRBMethod category.
+
+ change package: anRBMethod package.
+
+ method := anRBMethod deepCopy
+ source: newSource;
+ category: anRBMethod category;
+ package: anRBMethod package;
+ model: self model;
+ modelClass: self;
+ yourself.
+
+ self addMethod: method.
+
+ ^ change
+
+ "Created: / 10-10-2014 / 11:37:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 13:08:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing - classes'!
+
+compilerClass
+ "Answer a class suitable for compiling a source code in 'my' language"
+
+ ^ self realClass isNil ifTrue: [
+ "Return Smalltalk compiler, because we do not have multiple programming
+ support in this class (yet)"
+ self class compilerClass
+ ] ifFalse: [
+ self realClass compilerClass
+ ]
+
+ "Created: / 15-11-2014 / 16:58:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+inheritsFrom: aClass
+
+ ^ self isSubclassOf: aClass.
+
+ "Created: / 11-10-2014 / 00:25:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'enumerating'!
+
+instAndClassMethodsDo:aOneArgBlock
+ "see Behavior >> instAndClassMethodsDo:"
+
+ self theNonMetaclass methodsDo:aOneArgBlock.
+ self theMetaclass methodsDo:aOneArgBlock.
+
+ "Created: / 01-11-2014 / 21:35:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+instVarNames
+ "Returns instance variable names - STX compatibility"
+
+ ^ self instanceVariableNames
+
+ "Created: / 29-05-2014 / 23:46:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 24-09-2014 / 20:36:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 30-09-2014 / 19:30:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+instVarNames: aCollectionOfStrings
+ "Set instance variable names - STX compatibility"
+
+ self instanceVariableNames: aCollectionOfStrings
+
+ "Created: / 30-09-2014 / 19:30:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+isAbstract: aBoolean
+ "see isAbstract"
+
+ self theMetaclass isNil ifTrue: [
+ self error: 'This class is not defined in the model.'
+ ].
+
+ self theMetaclass objectAttributeAt: #isAbstract put: aBoolean
+
+ "Created: / 14-12-2014 / 16:39:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 14-12-2014 / 18:12:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'autoload check'!
+
+isLoaded
+ "Returns true when the class is auto-loaded.
+ see Metaclass >> isLoaded"
+
+ ^ self class isLoaded
+
+ "Created: / 15-11-2014 / 17:11:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+isSubclassOf: aClass
+ "see Behavior >> isSubclassOf: ( same purpose, but for model class )"
+
+ self allSuperclassesDo: [ :superclass |
+ "we are testing name here, because the class
+ can be from another namespace"
+ ((superclass name) = (aClass name)) ifTrue: [
+ ^ true
+ ]
+ ].
+
+ ^ false
+
+ "Created: / 11-10-2014 / 00:16:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+methodDictionary
+ "Stub method, returns real class MethodDictionary, although full MethodDictionary
+ implementation would be better here."
+
+ | methodDictionary |
+
+ methodDictionary := MethodDictionary new.
+
+ self realClass notNil ifTrue: [
+ self realClass methodDictionary do: [ :method |
+ methodDictionary := methodDictionary
+ at: method selector asSymbol
+ putOrAppend: (RBMethod
+ for: self
+ fromMethod: method
+ andSelector: method selector asSymbol)
+ ].
+ ].
+
+ removedMethods notNil ifTrue: [
+ removedMethods do: [ :removedMethod |
+ | method |
+
+ method := methodDictionary at: removedMethod asSymbol ifAbsent: [ nil ].
+ method notNil ifTrue: [
+ methodDictionary := methodDictionary removeKeyAndCompress: removedMethod asSymbol.
+ ]
+ ]
+ ].
+
+ newMethods notNil ifTrue: [
+ newMethods do: [ :newMethod |
+ methodDictionary := methodDictionary at: newMethod selector asSymbol putOrAppend: newMethod.
+ ]
+ ].
+
+ ^ methodDictionary
+
+ "Created: / 28-09-2014 / 22:57:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 14:42:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-05-2015 / 16:07:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'enumerating'!
+
+methodsDo:aOneArgBlock
+ "see Behavior >> methodsDo:"
+
+ self methodDictionary do:aOneArgBlock
+
+ "Created: / 02-11-2014 / 09:47:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+nameWithoutPrefix
+ "see ClassDescription >> nameWithoutPrefix"
+
+ ^ (Smalltalk at: #Class) nameWithoutPrefix: name
+
+ "Created: / 03-08-2014 / 23:29:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 20-09-2014 / 19:21:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+owningClass
+ "see Behavior >> owningClass"
+
+ ^ self theMetaclass owningClass
+
+ "Created: / 29-11-2014 / 13:17:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+owningClass: aClass
+ "Sets the owning class which is actually stored in the metaclass"
+
+ self theMetaclass owningClass: aClass
+
+ "Created: / 29-11-2014 / 13:21:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+owningClassOrYourself
+ "see Behavior >> owningClassOrYourself"
+
+ self owningClass notNil ifTrue:[^ self topOwningClass].
+ ^ self
+
+ "Created: / 29-11-2014 / 13:44:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+package
+ "see Class >> package ( same purpose, but for model class )"
+ | package |
+
+ package := self objectAttributeAt: #package.
+
+ (package isNil and: [ self realClass notNil ]) ifTrue: [
+ package := self realClass package.
+ ].
+
+ ^ package
+
+ "Created: / 09-10-2014 / 23:12:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+package: aPackage
+
+ self objectAttributeAt: #package put: aPackage
+
+ "Created: / 09-10-2014 / 23:12:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+privateClassesAt:aClassNameStringOrSymbol
+ "see Class >> privateClassesAt:"
+
+ | myName privateClassName |
+
+ myName := self name.
+ myName isNil ifTrue:[
+ "/ no name - there cannot be a corresponding private class
+ ^ nil
+ ].
+
+ privateClassName := (myName, '::' ,aClassNameStringOrSymbol) asSymbol.
+
+ ^ model classNamed: privateClassName.
+
+ "Created: / 15-11-2014 / 17:15:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 11:49:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+programmingLanguage
+ "Answer a language instance in which is this class programmed"
+
+ ^ self realClass isNil ifTrue: [
+ "Return Smalltalk language, because we do not have multiple programming
+ support in this class (yet)"
+ self class programmingLanguage
+ ] ifFalse: [
+ self realClass programmingLanguage
+ ]
+
+ "Created: / 22-12-2014 / 20:43:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+realSharedPoolNames
+ "see Behavior >> realSharedPoolNames"
+
+ ^ #()
+
+ "Created: / 15-11-2014 / 17:19:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 16-11-2014 / 16:37:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'method accessing'!
+
+sourceCodeAt: aSelector
+ "see Behavior >> sourceCodeAt:"
+
+ ^ self sourceCodeFor: aSelector
+
+ "Created: / 31-01-2015 / 19:05:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+superclassName: aName
+ "Assign superclass by its name"
+
+ self superclass: (self model classNamed: aName asSymbol)
+
+ "Created: / 28-09-2014 / 22:53:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+theMetaclass
+ "alias for theMetaClass - STX compatibility"
+
+ ^ self theMetaClass.
+
+ "Created: / 26-09-2014 / 16:26:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+theNonMetaclass
+ "alias for theNonMetaClass - STX compatibility"
+
+ ^ self theNonMetaClass
+
+ "Created: / 26-09-2014 / 16:36:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+topNameSpace
+ "see ClassDescription >> topNameSpace"
+
+ ^ self model
+
+ "Created: / 15-11-2014 / 17:26:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 16-11-2014 / 16:58:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+topOwningClass
+ "see Behavior >> topOwningClass"
+
+ ^ self theMetaclass topOwningClass
+
+ "Created: / 29-11-2014 / 13:48:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'enumerating'!
+
+withAllSuperclassesDo:aBlock
+ "evaluate aBlock for the class and all of its superclasses"
+
+ aBlock value:self.
+ self allSuperclassesDo:aBlock
+
+ "Created: / 29-09-2014 / 22:48:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBClass methodsFor:'compiling'!
+
+compile
+ "Updates class definition in the namespace along with code changes"
+ | change newClass |
+
+ change := model defineClass: self definitionString.
+ change package: self package.
+
+ (model respondsTo: #putModelClass:) ifTrue: [
+ model putModelClass: self
+ ] ifFalse: [
+ newClass := model classNamed: self name.
+ newClass package: self package
+ ].
+
+ ^ change
+
+ "Created: / 25-09-2014 / 22:31:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-11-2014 / 00:06:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBClass methodsFor:'accessing'!
+
+theNonMetaClass
+ "alias for theNonMetaclass - squeak compatibility"
+
+ ^ self theNonMetaclass
+
+ "Created: / 26-09-2014 / 16:50:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+owningClass
+ "see PrivateMetaclass >> owningClass"
+ | owningClass |
+
+ owningClass := self objectAttributeAt: #owningClass.
+ owningClass isNil ifTrue: [
+ self realClass notNil ifTrue: [
+ ^ self model classFor: self realClass owningClass
+ ]
+ ].
+
+ ^ owningClass.
+
+ "Created: / 29-11-2014 / 02:20:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+owningClass: aClass
+ "see owningClass"
+
+ self
+ objectAttributeAt: #owningClass
+ put: (self model classFor: aClass theNonMetaclass)
+
+ "Created: / 29-11-2014 / 02:23:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 29-11-2014 / 13:38:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+theMetaClass
+ "alias for metaclass - sqeak compatibility"
+
+ ^ self metaclass.
+
+ "Created: / 26-09-2014 / 21:32:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+theMetaclass
+ "alias for metaclass - STX compatibility"
+
+ ^ self metaclass.
+
+ "Created: / 26-09-2014 / 21:28:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'queries'!
+
+topOwningClass
+ "see PrivateMetaclass >> topOwningClass"
+
+ self owningClass isNil ifTrue:[^ nil].
+
+ self owningClass owningClass notNil ifTrue:[
+ ^ self owningClass topOwningClass
+ ].
+ ^ self owningClass
+
+ "Created: / 29-11-2014 / 13:52:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:24:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+category: aCategoryName
+ "Sets in which category/protocol does the method belongs within a class"
+
+ self objectAttributeAt: #category put: aCategoryName.
+
+ "Created: / 06-10-2014 / 07:54:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+class: aClass
+ "Helper for enabling usage of either real class or RBClass"
+
+ self modelClass: (self model classFor: aClass)
+
+ "Created: / 05-10-2014 / 21:04:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 08-11-2014 / 13:26:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'compiling'!
+
+compile
+ "Modifies/adds method in the model class."
+
+ ^ self modelClass compileMethod: self
+
+ "Created: / 06-10-2014 / 11:11:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 10-10-2014 / 12:28:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+mclass
+ "see Method >> mclass
+ Returns instace of RBClass, RBMetaclass or nil when unknown"
+
+ ^ self modelClass
+
+ "Created: / 27-11-2014 / 23:20:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+methodArgNames
+ "Returns collection of method argument names"
+
+ | methodNode arguments |
+
+ methodNode := RBParser
+ parseMethod: self source
+ onError: [ :str :pos |
+ self error: 'Cannot parse: ', str, ' at pos: ', pos asString
+ ].
+
+ "Transform arguments to what Method returns - keep compatibility"
+ arguments := methodNode arguments.
+
+ arguments isEmptyOrNil ifTrue: [
+ ^ nil
+ ].
+
+ ^ Array streamContents: [ :s |
+ arguments do: [ :argument |
+ s nextPut: argument name
+ ]
+ ]
+
+ "Created: / 07-10-2014 / 20:18:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 25-01-2015 / 15:35:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'queries'!
+
+methodDefinitionTemplate
+ "see Method >> methodDefinitionTemplate"
+
+ ^ Method
+ methodDefinitionTemplateForSelector:self selector
+ andArgumentNames:self methodArgNames
+
+ "Created: / 07-10-2014 / 20:18:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+model
+
+ ^ self objectAttributeAt: #model
+
+ "Created: / 05-10-2014 / 20:33:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+model: anRBSmalltalk
+
+ self objectAttributeAt: #model put: anRBSmalltalk
+
+ "Created: / 05-10-2014 / 20:32:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+newSource
+ "Returns new source code with performed modifications by CodeGenerator
+ ( replace: something with: anotherthing and custom formatting)."
+ | newSource generator |
+
+ newSource := self source.
+ generator := self sourceCodeGenerator.
+ generator notNil ifTrue: [
+ generator source: newSource.
+ newSource := generator newSource.
+ ].
+
+ "Fixes test CustomRBMethodTests >> test_compile_with_code_generator
+ when none selector and method is given then parse the selector from new source code"
+ (selector isNil and: [ compiledMethod isNil ] and: [ newSource notNil ]) ifTrue: [
+ selector := (Parser parseMethodSpecification: newSource) selector
+ ].
+
+ ^ newSource
+
+ "Created: / 10-10-2014 / 12:23:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified (comment): / 10-10-2014 / 15:31:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+package: aPackage
+
+ self objectAttributeAt: #package put: aPackage
+
+ "Created: / 10-10-2014 / 11:12:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'compiler interface'!
+
+programmingLanguage
+ "see CompiledCode >> programmingLanguage"
+
+ self method notNil ifTrue: [
+ ^ self method programmingLanguage
+ ].
+
+ self mclass notNil ifTrue: [
+ ^ self mclass programmingLanguage
+ ].
+
+ "None programming language found, assume Smalltalk as default"
+ ^ SmalltalkLanguage instance
+
+ "Created: / 26-12-2014 / 11:59:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+protocol
+ "Returns in which category/protocol does the method belongs within a class"
+
+ ^ self category
+
+ "Created: / 06-10-2014 / 07:46:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+protocol: aProtocolName
+ "Sets in which category/protocol does the method belongs within a class"
+
+ self category: aProtocolName.
+
+ "Created: / 06-10-2014 / 07:56:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+replace: placeholder with: code
+
+ self sourceCodeGenerator replace: placeholder with: code
+
+ "Created: / 06-10-2014 / 08:58:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'queries'!
+
+sends:selectorSymbol1 or:selectorSymbol2
+ "Returns true, if this method contains a message-send
+ to either selectorSymbol1 or selectorSymbol2.
+ ( non-optimized version of Message>>sends:or: )"
+
+ ^ (self sendsSelector: selectorSymbol1) or: [ self sendsSelector: selectorSymbol2 ]
+
+ "Created: / 04-10-2014 / 00:01:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+sourceCodeGenerator
+ "Returns helper tool for method source code manipulation like formatting and search & replace"
+
+ ^ self objectAttributeAt: #sourceCodeGenerator
+
+ "Created: / 06-10-2014 / 08:33:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+sourceCodeGenerator: aSourceCodeGenerator
+ "Set ... see method sourceCodeGenerator"
+
+ ^ self objectAttributeAt: #sourceCodeGenerator put: aSourceCodeGenerator
+
+ "Created: / 06-10-2014 / 08:37:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RefactoryChange methodsFor:'accessing'!
+
+model
+ "Returns reference to RBNamespace for retrieving model classes (RBClass, RBMetaclass)"
+
+ ^ self objectAttributeAt: #model
+
+ "Created: / 08-11-2014 / 14:00:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RefactoryChange methodsFor:'accessing'!
+
+model: aModel
+ "see model"
+
+ self objectAttributeAt: #model put: aModel
+
+ "Created: / 08-11-2014 / 14:00:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+classMenuExtensionCustomGenerators:aMenu
+ <menuextension: #classMenu>
+
+ self customMenuBuilder
+ perspective: SmallSense::CustomPerspective classPerspective;
+ menu: aMenu;
+ submenuLabel: 'Generate - Custom';
+ afterMenuItemLabelled: 'Generate';
+ generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomCodeGenerator ];
+ buildMenu.
+
+ "Created: / 26-08-2014 / 10:21:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:08:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:07:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+classMenuExtensionCustomRefactorings: aMenu
+ <menuextension: #classMenu>
+
+ self customMenuBuilder
+ perspective: SmallSense::CustomPerspective classPerspective;
+ menu: aMenu;
+ submenuLabel: 'Refactor - Custom';
+ afterMenuItemLabelled: 'Generate';
+ generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomRefactoring ];
+ buildMenu.
+
+ "Created: / 08-11-2014 / 21:24:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:08:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:16:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+classMenuExtensionNavigateToTestCase: aMenu
+ "Adds menu item to class list window and tries to guess test case class
+ name. If test case class exists then opens a new tab with this class selected."
+ <menuextension: #classMenu>
+
+ | item index |
+
+ item := MenuItem label: (resources string: 'Open Test Case Class')
+ itemValue: [
+ | className testClassName testClass |
+
+ className := self theSingleSelectedClass theNonMetaclass name.
+ testClassName := (className, 'Tests') asSymbol.
+ testClass := environment at: testClassName ifAbsent: [ nil ].
+ testClass isNil ifTrue: [
+ | extensionTestClassName |
+
+ "Small hack for my extension test cases"
+ extensionTestClassName := ('SmallSense::Custom', className, 'Tests') asSymbol.
+ testClass := environment at: extensionTestClassName ifAbsent: [ nil ].
+ ].
+
+ testClass notNil ifTrue: [
+ self createBuffer;
+ switchToClass: testClass;
+ selectProtocol: #tests
+ ] ifFalse: [
+ | info |
+
+ info := resources string: 'Test Case named %1 not found'.
+ self information: (info bindWith: testClassName)
+ ].
+ ].
+
+ item enabled: [ self theSingleSelectedClass notNil ].
+
+ index := aMenu indexOfMenuItemForWhich:[:each | each label = 'Generate' ].
+ index ~~ 0 ifTrue:[
+ aMenu addItem:item beforeIndex:index + 1.
+ ] ifFalse:[
+ aMenu addItem:item.
+ ].
+
+ "Created: / 26-12-2014 / 16:54:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 27-12-2014 / 19:01:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 12-06-2015 / 20:58:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+codeViewMenuExtensionCustomRefactorings:aMenu
+ <menuextension: #codeViewMenu>
+
+ self customMenuBuilder
+ perspective: SmallSense::CustomPerspective codeViewPerspective;
+ menu: aMenu;
+ submenuLabel: 'Refactor - Custom';
+ afterMenuItemLabelled: 'Refactor';
+ generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomRefactoring ];
+ buildMenu.
+
+ "Created: / 26-08-2014 / 22:44:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:08:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:17:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+customMenuBuilder
+ "Returns initialized instance of CustomMenuBuilder"
+
+ ^ SmallSense::CustomMenuBuilder new
+ navigationState: self navigationState;
+ resources: resources;
+ yourself
+
+ "Created: / 29-12-2014 / 00:04:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:06:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+selectorMenuExtensionCustomGenerators:aMenu
+ <menuextension: #selectorMenuCompareGenerateDebugSlice>
+
+ self customMenuBuilder
+ perspective: SmallSense::CustomPerspective methodPerspective;
+ menu: aMenu;
+ submenuLabel: 'Generate - Custom';
+ afterMenuItemLabelled: 'Generate';
+ generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomCodeGenerator ];
+ buildMenu.
+
+ "Created: / 26-08-2014 / 10:18:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:08:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:17:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+selectorMenuExtensionCustomRefactorings:aMenu
+ <menuextension: #selectorMenuCompareGenerateDebugSlice>
+
+ self customMenuBuilder
+ perspective: SmallSense::CustomPerspective methodPerspective;
+ menu: aMenu;
+ submenuLabel: 'Refactor - Custom';
+ afterMenuItemLabelled: 'Refactor';
+ generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomRefactoring ];
+ buildMenu.
+
+ "Created: / 24-08-2014 / 15:23:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:08:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:18:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+variablesMenuExtensionCustomGenerators:aMenu
+ <menuextension: #variablesMenu>
+
+ self customMenuBuilder
+ perspective: SmallSense::CustomPerspective instanceVariablePerspective;
+ menu: aMenu;
+ submenuLabel: 'Generate - Custom';
+ afterMenuItemLabelled: 'Generate';
+ buildMenu.
+
+ "Created: / 26-08-2014 / 10:21:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 04-01-2015 / 15:08:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 11-05-2015 / 09:09:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'documentation'!
+
+extensionsVersion_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/lccmake.bat Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,8 @@
+@REM -------
+@REM make using lcc compiler
+@REM type lccmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+make.exe -N -f bc.mak -DUSELCC=1 %*
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/libInit.cc Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,97 @@
+/*
+ * $Header$
+ *
+ * DO NOT EDIT
+ * automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+ */
+#define __INDIRECTVMINITCALLS__
+#include <stc.h>
+
+#ifdef WIN32
+# pragma codeseg INITCODE "INITCODE"
+#endif
+
+#if defined(INIT_TEXT_SECTION) || defined(DLL_EXPORT)
+DLL_EXPORT void _libstx_goodies_smallsense_refactoring_custom_Init() INIT_TEXT_SECTION;
+DLL_EXPORT void _libstx_goodies_smallsense_refactoring_custom_InitDefinition() INIT_TEXT_SECTION;
+#endif
+
+void _libstx_goodies_smallsense_refactoring_custom_InitDefinition(pass, __pRT__, snd)
+OBJ snd; struct __vmData__ *__pRT__; {
+__BEGIN_PACKAGE2__("libstx_goodies_smallsense_refactoring_custom__DFN", _libstx_goodies_smallsense_refactoring_custom_InitDefinition, "stx:goodies/smallsense/refactoring_custom");
+_stx_137goodies_137smallsense_137refactoring_137custom_Init(pass,__pRT__,snd);
+
+__END_PACKAGE__();
+}
+
+void _libstx_goodies_smallsense_refactoring_custom_Init(pass, __pRT__, snd)
+OBJ snd; struct __vmData__ *__pRT__; {
+__BEGIN_PACKAGE2__("libstx_goodies_smallsense_refactoring_custom", _libstx_goodies_smallsense_refactoring_custom_Init, "stx:goodies/smallsense/refactoring_custom");
+_SmallSense__CustomChangeManager_Init(pass,__pRT__,snd);
+_SmallSense__CustomClassQuery_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeGeneratorOrRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomContext_Init(pass,__pRT__,snd);
+_SmallSense__CustomDialog_Init(pass,__pRT__,snd);
+_SmallSense__CustomManager_Init(pass,__pRT__,snd);
+_SmallSense__CustomMenuBuilder_Init(pass,__pRT__,snd);
+_SmallSense__CustomMock_Init(pass,__pRT__,snd);
+_SmallSense__CustomNamespace_Init(pass,__pRT__,snd);
+_SmallSense__CustomParseTreeRewriter_Init(pass,__pRT__,snd);
+_SmallSense__CustomPerspective_Init(pass,__pRT__,snd);
+_SmallSense__CustomRefactoryBuilder_Init(pass,__pRT__,snd);
+_SmallSense__CustomSourceCodeFormatter_Init(pass,__pRT__,snd);
+_SmallSense__CustomSourceCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomSourceCodeSelection_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseHelper_Init(pass,__pRT__,snd);
+_stx_137goodies_137smallsense_137refactoring_137custom_Init(pass,__pRT__,snd);
+_SmallSense__CustomBrowserChangeManager_Init(pass,__pRT__,snd);
+_SmallSense__CustomBrowserContext_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomLocalChangeManager_Init(pass,__pRT__,snd);
+_SmallSense__CustomNoneSourceCodeFormatter_Init(pass,__pRT__,snd);
+_SmallSense__CustomRBLocalSourceCodeFormatter_Init(pass,__pRT__,snd);
+_SmallSense__CustomRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomSilentDialog_Init(pass,__pRT__,snd);
+_SmallSense__CustomSubContext_Init(pass,__pRT__,snd);
+_SmallSense__CustomUserDialog_Init(pass,__pRT__,snd);
+_SmallSense__CustomAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeSelectionRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomInspectorTabCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomIsAbstractCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomNewClassGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomReplaceIfNilWithIfTrueRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomSubclassResponsibilityCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseMethodCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseSetUpCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseTearDownCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomUpdateTestCaseCategoryRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomVisitorCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeGeneratorClassGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeSelectionToResourceTranslation_Init(pass,__pRT__,snd);
+_SmallSense__CustomDefaultGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomMultiSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomPrintCodeSelectionRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomRefactoringClassGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomSimpleAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomSimpleGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomSimpleSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomUITestCaseCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomUITestCaseSetUpCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomVisitorCodeGeneratorAcceptVisitor_Init(pass,__pRT__,snd);
+_SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+
+_stx_137goodies_137smallsense_137refactoring_137custom_extensions_Init(pass,__pRT__,snd);
+__END_PACKAGE__();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/mingwmake.bat Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,16 @@
+@REM -------
+@REM make using mingw gnu compiler
+@REM type mingwmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+
+@pushd ..\..\stx\rules
+@call find_mingw.bat
+@popd
+make.exe -N -f bc.mak %DEFINES% %USEMINGW_ARG% %*
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/refactoring_custom.rc Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,37 @@
+//
+// DO NOT EDIT
+// automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+//
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 6,2,32767,32767
+ PRODUCTVERSION 6,2,5,0
+#if (__BORLANDC__)
+ FILEFLAGSMASK VS_FF_DEBUG | VS_FF_PRERELEASE
+ FILEFLAGS VS_FF_PRERELEASE | VS_FF_SPECIALBUILD
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VS_USER_DEFINED
+#endif
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ BEGIN
+ VALUE "CompanyName", "My Company\0"
+ VALUE "FileDescription", "Class Library (LIB)\0"
+ VALUE "FileVersion", "6.2.32767.32767\0"
+ VALUE "InternalName", "stx:goodies/smallsense/refactoring_custom\0"
+ VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
+ VALUE "ProductName", "ProductName\0"
+ VALUE "ProductVersion", "6.2.5.0\0"
+ VALUE "ProductDate", "Thu, 19 Feb 2015 06:05:34 GMT\0"
+ END
+
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN // Language | Translation
+ VALUE "Translation", 0x409, 0x4E4 // U.S. English, Windows Multilingual
+ END
+END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/stx_goodies_smallsense_refactoring_custom.st Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,377 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"
+
+"{ NameSpace: Smalltalk }"
+
+LibraryDefinition subclass:#stx_goodies_smallsense_refactoring_custom
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'* Projects & Packages *'
+!
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+!
+
+documentation
+"
+ Package documentation:
+
+ API for custom code generation and refactoring.
+
+ [author:]
+ Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'description'!
+
+excludedFromPreRequisites
+ "list all packages which should be ignored in the automatic
+ preRequisites scan. See #preRequisites for more."
+
+ ^ #(
+ )
+!
+
+mandatoryPreRequisites
+ "list packages which are mandatory as a prerequisite.
+ This are packages containing superclasses of my classes and classes which
+ are extended by myself.
+ They are mandatory, because we need these packages as a prerequisite for loading and compiling.
+ This method is generated automatically,
+ by searching along the inheritance chain of all of my classes."
+
+ ^ #(
+ #'stx:goodies/refactoryBrowser/changes' "AddClassChange - extended"
+ #'stx:goodies/refactoryBrowser/helpers' "RBAbstractClass - extended"
+ #'stx:goodies/refactoryBrowser/parser' "ParseTreeRewriter - superclass of SmallSense::CustomParseTreeRewriter"
+ #'stx:goodies/sunit' "TestAsserter - superclass of SmallSense::CustomAccessMethodsCodeGeneratorTests"
+ #'stx:libbasic' "LibraryDefinition - superclass of stx_goodies_smallsense_refactoring_custom"
+ #'stx:libtool' "CodeGenerator - superclass of SmallSense::CustomSourceCodeGenerator"
+ #'stx:libview2' "ApplicationModel - extended"
+ )
+!
+
+referencedPreRequisites
+ "list packages which are a prerequisite, because they contain
+ classes which are referenced by my classes.
+ We do not need these packages as a prerequisite for compiling or loading,
+ however, a class from it may be referenced during execution and having it
+ unloaded then may lead to a runtime doesNotUnderstand error, unless the caller
+ includes explicit checks for the package being present.
+ This method is generated automatically,
+ by searching all classes (and their packages) which are referenced by my classes."
+
+ ^ #(
+ #'stx:goodies/smallsense' "SmallSense::TestCase - referenced by SmallSense::CustomTestCaseCodeGenerator class>>availableInContext:"
+ #'stx:libbasic3' "Change - referenced by SmallSense::CustomCodeGeneratorOrRefactoringTestCase>>assertSource:sameAs:"
+ #'stx:libcomp' "Parser - referenced by RBMethod>>newSource"
+ #'stx:libjava' "JavaClass - referenced by SmallSense::CustomCodeGeneratorOrRefactoringTests>>test_available_for_programming_languages_in_context_filled_with_class_perspective_java"
+ #'stx:libjava/tools' "JavaCompiler - referenced by SmallSense::CustomJavaSimpleSetterMethodsCodeGenerator>>buildInContext:"
+ #'stx:libjavascript' "JavaScriptCompiler - referenced by SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests>>setUp"
+ #'stx:libview' "WindowGroup - referenced by SmallSense::CustomCodeGeneratorOrRefactoring>>executeInContextWithWaitCursor:"
+ #'stx:libwidg' "DialogBox - referenced by SmallSense::CustomCodeGeneratorOrRefactoringTests>>test_execute_in_context_aborted"
+ #'stx:libwidg2' "CheckBox - referenced by SmallSense::CustomDialog>>addCheckBoxOn:labeled:"
+ )
+!
+
+subProjects
+ "list packages which are known as subprojects.
+ The generated makefile will enter those and make there as well.
+ However: they are not forced to be loaded when a package is loaded;
+ for those, redefine requiredPrerequisites"
+
+ ^ #(
+ )
+
+ "Modified: / 19-02-2015 / 06:04:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'description - contents'!
+
+classNamesAndAttributes
+ "lists the classes which are to be included in the project.
+ Each entry in the list may be: a single class-name (symbol),
+ or an array-literal consisting of class name and attributes.
+ Attributes are: #autoload or #<os> where os is one of win32, unix,..."
+
+ ^ #(
+ "<className> or (<className> attributes...) in load order"
+ (#'SmallSense::CustomBrowserEnvironmentTests' autoload)
+ #'SmallSense::CustomChangeManager'
+ #'SmallSense::CustomClassQuery'
+ (#'SmallSense::CustomClassQueryTests' autoload)
+ #'SmallSense::CustomCodeGeneratorOrRefactoring'
+ (#'SmallSense::CustomCodeGeneratorOrRefactoringTestCase' autoload)
+ #'SmallSense::CustomContext'
+ (#'SmallSense::CustomContextTests' autoload)
+ #'SmallSense::CustomDialog'
+ (#'SmallSense::CustomLocalChangeManagerTests' autoload)
+ #'SmallSense::CustomManager'
+ (#'SmallSense::CustomManagerTests' autoload)
+ #'SmallSense::CustomMenuBuilder'
+ (#'SmallSense::CustomMenuBuilderTests' autoload)
+ #'SmallSense::CustomMock'
+ (#'SmallSense::CustomMockTests' autoload)
+ #'SmallSense::CustomNamespace'
+ (#'SmallSense::CustomNewSystemBrowserTests' autoload)
+ (#'SmallSense::CustomNoneSourceCodeFormatterTests' autoload)
+ #'SmallSense::CustomParseTreeRewriter'
+ (#'SmallSense::CustomParseTreeRewriterTests' autoload)
+ #'SmallSense::CustomPerspective'
+ (#'SmallSense::CustomPerspectiveTests' autoload)
+ (#'SmallSense::CustomRBAbstractClassTests' autoload)
+ (#'SmallSense::CustomRBClassTests' autoload)
+ (#'SmallSense::CustomRBLocalSourceCodeFormatterTests' autoload)
+ (#'SmallSense::CustomRBMetaclassTests' autoload)
+ (#'SmallSense::CustomRBMethodTests' autoload)
+ #'SmallSense::CustomRefactoryBuilder'
+ (#'SmallSense::CustomRefactoryClassChangeTests' autoload)
+ #'SmallSense::CustomSourceCodeFormatter'
+ #'SmallSense::CustomSourceCodeGenerator'
+ (#'SmallSense::CustomSourceCodeGeneratorTests' autoload)
+ #'SmallSense::CustomSourceCodeSelection'
+ (#'SmallSense::CustomSourceCodeSelectionTests' autoload)
+ (#'SmallSense::CustomSubContextTests' autoload)
+ #'SmallSense::CustomTestCaseHelper'
+ (#'SmallSense::CustomTestCaseHelperTests' autoload)
+ #'stx_goodies_smallsense_refactoring_custom'
+ (#'SmallSense::CustomAccessMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomAddClassChangeTests' autoload)
+ (#'SmallSense::CustomAddMethodChangeTests' autoload)
+ #'SmallSense::CustomBrowserChangeManager'
+ #'SmallSense::CustomBrowserContext'
+ (#'SmallSense::CustomBrowserContextTests' autoload)
+ (#'SmallSense::CustomChangeNotificationAccessMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomChangeNotificationSetterMethodsCodeGeneratorTests' autoload)
+ #'SmallSense::CustomCodeGenerator'
+ (#'SmallSense::CustomCodeGeneratorClassGeneratorTests' autoload)
+ (#'SmallSense::CustomCodeGeneratorOrRefactoringTests' autoload)
+ (#'SmallSense::CustomCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomCodeGeneratorUserPreferencesTests' autoload)
+ (#'SmallSense::CustomCodeSelectionToResourceTranslationTests' autoload)
+ (#'SmallSense::CustomDefaultGetterMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomIsAbstractCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomLazyInitializationAccessMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomLazyInitializationGetterMethodsCodeGeneratorTests' autoload)
+ #'SmallSense::CustomLocalChangeManager'
+ (#'SmallSense::CustomMultiSetterMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomNamespaceTests' autoload)
+ (#'SmallSense::CustomNewClassGeneratorTests' autoload)
+ #'SmallSense::CustomNoneSourceCodeFormatter'
+ #'SmallSense::CustomRBLocalSourceCodeFormatter'
+ #'SmallSense::CustomRefactoring'
+ (#'SmallSense::CustomRefactoringClassGeneratorTests' autoload)
+ (#'SmallSense::CustomRefactoryBuilderTests' autoload)
+ (#'SmallSense::CustomReplaceIfNilWithIfTrueRefactoringTests' autoload)
+ #'SmallSense::CustomSilentDialog'
+ (#'SmallSense::CustomSimpleAccessMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomSimpleGetterMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomSimpleSetterMethodsCodeGeneratorTests' autoload)
+ #'SmallSense::CustomSubContext'
+ (#'SmallSense::CustomSubclassResponsibilityCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomTestCaseCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomTestCaseMethodCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomTestCaseSetUpCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomTestCaseTearDownCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomUpdateTestCaseCategoryRefactoringTests' autoload)
+ #'SmallSense::CustomUserDialog'
+ (#'SmallSense::CustomValueHolderAccessMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomValueHolderGetterMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests' autoload)
+ (#'SmallSense::CustomVisitorCodeGeneratorAcceptVisitorTests' autoload)
+ (#'SmallSense::CustomVisitorCodeGeneratorTests' autoload)
+ #'SmallSense::CustomAccessMethodsCodeGenerator'
+ #'SmallSense::CustomCodeSelectionRefactoring'
+ #'SmallSense::CustomInspectorTabCodeGenerator'
+ #'SmallSense::CustomIsAbstractCodeGenerator'
+ #'SmallSense::CustomJavaSimpleSetterMethodsCodeGenerator'
+ #'SmallSense::CustomNewClassGenerator'
+ #'SmallSense::CustomReplaceIfNilWithIfTrueRefactoring'
+ #'SmallSense::CustomSubclassResponsibilityCodeGenerator'
+ #'SmallSense::CustomTestCaseCodeGenerator'
+ #'SmallSense::CustomTestCaseMethodCodeGenerator'
+ #'SmallSense::CustomTestCaseSetUpCodeGenerator'
+ #'SmallSense::CustomTestCaseTearDownCodeGenerator'
+ #'SmallSense::CustomUpdateTestCaseCategoryRefactoring'
+ #'SmallSense::CustomVisitorCodeGenerator'
+ #'SmallSense::CustomChangeNotificationAccessMethodsCodeGenerator'
+ #'SmallSense::CustomChangeNotificationSetterMethodsCodeGenerator'
+ #'SmallSense::CustomCodeGeneratorClassGenerator'
+ #'SmallSense::CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator'
+ #'SmallSense::CustomCodeSelectionToResourceTranslation'
+ #'SmallSense::CustomDefaultGetterMethodsCodeGenerator'
+ #'SmallSense::CustomLazyInitializationAccessMethodsCodeGenerator'
+ #'SmallSense::CustomLazyInitializationGetterMethodsCodeGenerator'
+ #'SmallSense::CustomMultiSetterMethodsCodeGenerator'
+ #'SmallSense::CustomPrintCodeSelectionRefactoring'
+ #'SmallSense::CustomRefactoringClassGenerator'
+ #'SmallSense::CustomSimpleAccessMethodsCodeGenerator'
+ #'SmallSense::CustomSimpleGetterMethodsCodeGenerator'
+ #'SmallSense::CustomSimpleSetterMethodsCodeGenerator'
+ #'SmallSense::CustomUITestCaseCodeGenerator'
+ #'SmallSense::CustomUITestCaseSetUpCodeGenerator'
+ #'SmallSense::CustomValueHolderAccessMethodsCodeGenerator'
+ #'SmallSense::CustomValueHolderGetterMethodsCodeGenerator'
+ #'SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator'
+ #'SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator'
+ #'SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator'
+ #'SmallSense::CustomVisitorCodeGeneratorAcceptVisitor'
+ #'SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGenerator'
+ )
+!
+
+extensionMethodNames
+ "list class/selector pairs of extensions.
+ A correponding method with real names must be present in my concrete subclasses"
+
+ ^ #(
+ #'Tools::NewSystemBrowser' selectorMenuExtensionCustomRefactorings:
+ #'Tools::NewSystemBrowser' classMenuExtensionCustomGenerators:
+ #'Tools::NewSystemBrowser' codeViewMenuExtensionCustomRefactorings:
+ #'Tools::NewSystemBrowser' selectorMenuExtensionCustomGenerators:
+ #'Tools::NewSystemBrowser' variablesMenuExtensionCustomGenerators:
+ RBAbstractClass allClassVarNames
+ RBAbstractClass allSuperclassesDo:
+ RBAbstractClass instVarNames
+ RBAbstractClass methodDictionary
+ RBAbstractClass nameWithoutPrefix
+ RBAbstractClass superclassName:
+ RBAbstractClass theMetaclass
+ RBAbstractClass theNonMetaclass
+ RBAbstractClass withAllSuperclassesDo:
+ RBClass compile
+ RBClass theNonMetaClass
+ RBMetaclass theMetaClass
+ RBMetaclass theMetaclass
+ RBAbstractClass instVarNames:
+ RBMethod sends:or:
+ RBMethod category:
+ RBMethod class:
+ RBMethod compile
+ RBMethod methodArgNames
+ RBMethod methodDefinitionTemplate
+ RBMethod model
+ RBMethod model:
+ RBMethod protocol
+ RBMethod protocol:
+ RBMethod replace:with:
+ RBMethod sourceCodeGenerator
+ RBMethod sourceCodeGenerator:
+ AddClassChange package
+ AddClassChange package:
+ AddMethodChange package:
+ RBAbstractClass compileMethod:
+ RBAbstractClass package
+ RBAbstractClass package:
+ RBMethod newSource
+ RBMethod package:
+ RBAbstractClass inheritsFrom:
+ RBAbstractClass isSubclassOf:
+ RBAbstractClass instAndClassMethodsDo:
+ RBAbstractClass methodsDo:
+ RefactoryChange model
+ RefactoryChange model:
+ #'Tools::NewSystemBrowser' classMenuExtensionCustomRefactorings:
+ AddClassChange argumensBySelectorPartsFromMessage:
+ AddClassChange privateInClassName
+ AddClassChange privateInClassName:
+ RBAbstractClass compilerClass
+ RBAbstractClass isLoaded
+ RBAbstractClass privateClassesAt:
+ RBAbstractClass realSharedPoolNames
+ RBAbstractClass topNameSpace
+ RBMetaclass owningClass
+ RBMetaclass owningClass:
+ RBMethod mclass
+ RBAbstractClass owningClass
+ RBAbstractClass owningClass:
+ RBAbstractClass owningClassOrYourself
+ RBAbstractClass topOwningClass
+ RBMetaclass topOwningClass
+ RBAbstractClass isAbstract:
+ RBAbstractClass programmingLanguage
+ RBMethod programmingLanguage
+ #'Tools::NewSystemBrowser' classMenuExtensionNavigateToTestCase:
+ #'Tools::NewSystemBrowser' customMenuBuilder
+ RBAbstractClass sourceCodeAt:
+ )
+! !
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'description - project information'!
+
+companyName
+ "Return a companyname which will appear in <lib>.rc"
+
+ ^ 'My Company'
+!
+
+description
+ "Return a description string which will appear in vc.def / bc.def"
+
+ ^ 'Class Library'
+!
+
+legalCopyright
+ "Return a copyright string which will appear in <lib>.rc"
+
+ ^ 'Copyright Jakub Nesveda 2013-2015 & Jan Vrany 2013-now'
+
+ "Modified: / 05-05-2015 / 23:56:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+productName
+ "Return a product name which will appear in <lib>.rc"
+
+ ^ 'ProductName'
+! !
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'documentation'!
+
+version_HG
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/vcmake.bat Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,20 @@
+@REM -------
+@REM make using Microsoft Visual C compiler
+@REM type vcmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+
+@if not defined VSINSTALLDIR (
+ pushd ..\..\stx\rules
+ call vcsetup.bat
+ popd
+)
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+make.exe -N -f bc.mak -DUSEVC=1 %DEFINES% %*
+
+
+
+