A SystemBrowser can also be opened on a previously saved snapshot image (via the FileBrowser's
'Snapshot Image Browser' menu item, or by evaluating:
SystemBrowser openOnSnapShotImage:
anImageFileName
This is a readOnly browser, which uses the information contained in the file instead of
accessing class/method objects directly.
This browser is useful to extract code from old images - especially, if an old image
is no longer executable, due to a recompilation of the ST/X executable.
- select the class category, where the new class shall be included in
(if you want to add a new category, use the "new class category" menu
function in the class category list).
- select the "new class" item in the class list popUp menu
(if a class is currently selected, its found in the "new ..." submenu)
This will show a class definition template in the codeview.
- edit the template (change the superclasses name, your classes name
and add instance and/or class variables if any).
- "accept" (use the "accept" menu function in the codeview)
- it is a good idea to add some documentation now (see below)
Notice:
If the new class is installed in a namespace AND hides a corresponding global class,
methods within that namespace which access the class by its name are recompiled
(possibly then accessing the new namespace-class).
- select the class and apply the class lists "rename ..." menu
function. You will be asked for a new name.
- After the rename, the browser will search for all references to the old class
and (if any are found) open a browser on the referencing methods.
You may or may not want to change those references to the new name.
Notice:
If the rename implies a change of the namespace, all methods which access
the class by its old name are recompiled (possibly then accessing the previously
hidden global class with the same name).
Do not rename classes programmatically, by changing a classes name and/or
storing it under another key in the Smalltalk dictionary,
because this will not take care of accessors and especially not recompile them.
(a program should use "Smalltalk renameClass:...to:"
, instead)
- select the class and apply the class lists "remove" menu
function. You are asked to confirm the removal.
Notice:
If the removed class was located in some namespace, and a global class
exists with the same name (i.e. the class has hidden the global class within
the namespace), all methods which access
the class by its old name are recompiled (possibly then accessing the previously
hidden global class).
Do not remove classes programmatically, by removing it from the Smalltalk dictionary,
because this will not take care of accessors and especially not recompile them.
(a program should use "Smalltalk removeClass:..."
, instead)
We suggest you stay with Smalltalk/X's philosophy of putting the
documentation into empty methods under the 'documentation
' category.
To do so:
- select the class
- use the method category list popup menu function "add documentation stubs".
- edit these documentation methods and "accept" them
- select the class
- select the method category (or create a new method category, by
using the "new category" menu function in the method category list)
- type in the method into the codeview
You can also get a method template with the "new method"
menu function in the method lists popup menu. Alternatively, copy and paste some
code from any other textView, and modify it as appropriate.
- "accept"
- select class, method category and method; this will bring the
methods source into the codeview.
- edit the methods code as required
- "accept"
"accept" installs whatever is currently visible;
if the methods selector has been changed, a corresponding (possibly new)
method will be generated - independent of the method which was
selected in the first place.
Thus, you can select any other method, to take its source code as a starting
point for new methods.
- select class, method category and method; this will bring the
methods source into the codeview.
- use the "remove" function from the method lists popup menu
Notice, that the system cannot itself find out, if the method is still
required - i.e. if there are any message sends which would possibly invoke
that method (since message sends could be constructed by a #perform
,
or by evaluating a Smalltalk expression from a string).
Therefore, looking at all senders
before actually removing any method may not always ensure that the method
is not needed.
A good approach is to change the methods visibility to
"ignored" instead of removing it. This marks the method as being
invisible with respect to the method lookup - its still shown in the browser,
but ignored by the program. Ignored methods may later be removed (or changed back to
"public").
- select the class (this will show its definition in the codeview)
- edit the
'instanceVariableNames'
or 'classVariableNames'
-string
as required.
- "accept"
Notice:
existing instances of the class will not be affected by this change.
Instead, the original class will get its category
changed to "obsolete"
and a new class is installed under the
original name.
This means, that existing instances still have a valid class definition around,
but methods can no longer be added, removed or changed to the old class.
In case of a changed class definition (which affects the instance layout),
the system will recompile all methods that require recompilation.
Have a look at the Transcript, to see what is going on.
If the changed class has many subclasses, this may take a while, since
all subclasses may have to be recompiled.
- select the "senders" item in the method menu
This opens a DialogBox asking for the selector of interest.
- fill in selector to search for. You can use wildcards (i.e. a matchpattern).
(the box will offer a reasonable default text, depending on
the context in which you use this function. It will either
use the current selection from the code view or the currently
selected method. It will even try to interpret the currently selected text
and extract the selector from partial expressions).
- select the "implementors item in the method menu
This opens a DialogBox asking for the selector of interest.
- fill in selector to search for. You can use wildcards (i.e. a matchpattern).
Use this to search up the class inheritance for an implementor
of a particular message.
- select the "find method" item in the method menu
This opens a DialogBox asking for the selector of interest.
- fill in the selector to search for
- select any of the
"variable search"
menu items in the
variable list popup menu.
A dialog appears, asking for the variables name (matchPatterns are allowed),
and the set of classes to limit the search.
Since searching involves parsing the source code, these functions
may take a while to show the result. Limiting the search to the current class
or category helps here.
Notice:
Simply selecting a variables name in this list will
highlight all methods in which that variable is accessed.
- select the "globals" menu item in the method list
- enter the name of the global (matchpatterns are allowed)
Notice:
since classes are (almost) always referenced by globals,
this will also find explicit uses of classes.
(for example: try searching for "Array"
)
The outcome of the search will be presented in a browser, which
has its search pattern preset to the globals name.
Thus a search-next (i.e. "CMD-F") will place the cursor to the
next occurence of the string.
- Select the "classRefs" menu item from the class list.
This menu function is just a shortcut for searching global references to
the current classes name.
This question is often asked, if you have some method producing a message
or output to some stream, and you want to find out quickly where that happens.
For example, which method is responsible for the "compiled: ..."
message appearing
on the transcript when methods are accepted.
There is no direct search function available for this kind of query.
However, you can use the substring search functions to (at least) limit the
number of methods that have to be investigated.
- Select the "string search" item from the method list.
Notice, that since all source code has to be processed,
this function takes somewhat longer than other queries (senders/implementors);
therefore, if you know the selector which is used,
the senders function is probably better.
Also, if you have any idea of which class (or superclass) the method is
contained in, limit the search
to the current class or category.
Often, when you need some specific functionality, you know (or feel to know)
that there must be some code for this in the system,
but do not know exactly the name of the method.
For example, it may happen that you need some "string-concatenation" functionality,
but do not remember what the message selector is.
To help in this situation, use the apropos function, which allows
searching for a keyword in method selectors and method comments.
Try the above example, searching for 'concat'
.
Notice, that this function too may take some time, since all source code has
to be processed. You may limit the search
to the current class or category.
In the above example, it seems obvious that concatenation is an operation
on collections - therefore you could select the Collection
class
and do an apropos there (on all subclasses).
For fast search, methods can be tagged with a "resource:"
definition;
this has no semantic meaning, but methods tagged this way can be quickly found,
without a need to scan its source (there is a corresponding resource-tag-bit in
the method object, which is much faster to check).
Within ST/X, methods are marked with the following tags:
- #keyboard
methods which do some keyboard event handling and somehow depend on the keyboard map.
- #style
methods which access the view styleSheet and somehow depend on those definitions.
Therefore, to find all methods which do keyboard event handling,
search for a resource named "keyboard"
.
You may either search for a resources key (as above)
or for some particuler value item;
for example, all methods which handle the "Accept"
key
are found by a search for the resource "keyboard"
and a value of "Accept"
.
You can mark your methods with any resource; for example, in a project it
may be useful to tag methods with things like "toBeReviewed"
,
"toBeTested"
, "preliminary"
or whatever.
These methods are later quickly found by searching for an appropriate resource.
Sorry, there is no resource search menu item in the browser;
instead, the launcher offers this in its classes pull down menu.
This is done by renaming the class, prepending the namespace-prefix to the
new name.
For example, to move a class called "Foo"
into the "MyPrivateClasses
" namespace,
simply rename the class to "MyPrivateClasses::Foo"
.
The rename dialog is found in the classLists popUpMenu.
Get the classes definition (by reselecting the class, or toggling one of the
class/instance toggles), change the string after the category argument
and accept.
You can start a browser manually, and pass a searchBlock (which is supposed to return true/false)
to open a browser on any subset of methods.
Currently, there is no special menu item for this, so you have to enter
an expression into a workspace, and evaluate it there.
For example, a browser on all methods with 3 arguments can be opened with:
SystemBrowser browseAllSelect:[:cls :method :sel |
sel numArgs == 3
]
if you are interested in methods with more than 10 arguments, try:
SystemBrowser browseAllSelect:[:cls :method :sel |
sel numArgs > 10
]
or, to find all methods which have 'at:' in their name:
SystemBrowser browseAllSelect:[:cls :method :sel |
'*[aA]t:*' match:sel
]
Beside browseAllSelect:
,
there are other special startup messages to be found in
SystemBrowsers
class protocol. Have a look at them - you may find some of them
useful when searching for methods.
Extra hint:
The Launcher's class menu offers an item to open a browser on all methods which
access a particular resource. Since resource-access is defined symbolically
(with a Resource directirve in the method), any arbitrary symbol can be used
there. For example, you can mark your method with:
<Resource: #toBeRevieved>
and find all methods which need a review by entering "toBeRevieved
" as
as the resource you are looking for.
(of course, you can also use the browser's string search function - but that is much
slower, since all of the systems sourceCode has to be investigated ...)
Mark your changed methods
when adding methods to existing system classes, you should mark them
(either by name or their category) to ease finding those later.
For example, you may later want to fileout all of your added methods.
This can be done automatically if all of them have a distinct category.
("fileOut-all" function in the method category list).
Starting with version 2.10.4, methods and classes include a package field.
This makes it very easy, to identify classes and methods which belong to a
package for fileOut. Set the current projects packageName to some unique name and
use the ProjectViews "browse" function to see what has been
changed within that project. There are also menu functions to selectively
fileOut per-project changes to your projects directory.
Prepare use of the stc machine code compiler
If you plan to compile your classes later to binary modules, use the
"fileout-each" function instead of "fileOut" in the class category list.
This one will create separate sourcefiles for each class instead of
putting all of them into one big file.
The reason is that the stc-compiler (currently) cannot compile multiple
classes, but requires one class per sourcefile.
Use project directories
If you are working in multiple projects, define some per project directory
in the project view.
The systemBrowser will always save files into the active projects directory.
This avoids having all of your filedOut sourcefile being saved in one
big directory, and helps to structure your project.
Keep your sourcefiles consistent
Be careful about overwriting existing sourcefiles when filing out:
since the methods source is typically extracted from some sourcefile,
overwriting one of tme will lead to funny results. All fileOut functions
will be changed in upcoming versions to take care about this, but currently
you should never fileOut into the "source"
or one of the "libXXX"
directories.
Be very careful when editing existing sourcefiles with the fileBrowser or
another (non-ST/X) editor. Since methods do not keep the source
as a string (but instead the filename and filePosition), editing a sourcefile
makes this sourceInfo invalid (you will see funny code in the systemBrowser)
in the current Smalltalk executable.
You have to recompile that file and relink a new Smalltalk executable
to fix things.
If you see funny sourcecode in the browser, do NEVER fileOut these -
the resulting sourcefile may be completely useless.
The above consistency problem does not apply, if the sourceCode manager is
used; if enabled, the sourceCode manager can figure out the classes actual
version, and extract the corresponding source version from the
repository - even if newer versions of the same class are present
in local source files or in the repository.
The sourceCode manager is only provided with the commercial release -
therefore, demo-version and private-version users should be very careful.
Doc $Revision: 1.19 $ $Date: 2016/09/14 09:41:13 $