Code Search Patterns

Help Index


Introduction

The code searcher allows for more complex searches compared to simple string or pattern searches - it allows you to enter a smalltalk code fragment and search on the code-tree level (i.e. smalltalk-syntax aware searching).

For example, you can search for assignments of the value 1234 to a variable named myVar with the following pattern:

    myVar := 1234
This will find the assignments even if the code is formatted with whiteSpace or comments in between or both.

Likewise, you can search for all creations of three-element Arrays, using a constant array size, with the pattern:

    Array new:3
Try using the codeSearcher on some of your own code (and place comments or whitespace into your code).

Meta Characters/Variables

The above (simple) example were searching for exact code matches. Although useful, most of the time we need the search to be more flexible, for example if we want to search for "any message" or "any literal value" or "any something". (for example, we would like to search for any Array instance creation with a constant size).

To allow for those to be specified in the search-code pattern, the search-syntax supports pattern variables (also called meta variables).

Each metaPattern-variable must begin with a ` (backquote) character. Immediately following the ` character, other characters can be entered to specify what type of node this metaPattern-variable can match. After all the special character have been entered, you must then enter a valid variable name. (the matched code is actually bound to this name inside the searcher and later used by the code-rewriter.)
The special characters currently supported are listed in the following table:

@ - list
When applied to a variable node, this will match a literal, variable, or a sequence of messages sent to a literal or variable

When applied to a keyword in a message, it will match a list of keyword messages (i.e., any message send)

When applied with a statement character, it will match a list of statements

For example:

    | `@Temps | 
matches list of temps

    `@.Statements
matches list of statements

    `@object
matches any message node, literal node or block node

    foo `@message: `@args
matches any message sent to foo.

. - statement
matches a statement in a sequence node

For example:

    `.Statement
matches a single statement

# - literal
matches only literal objects

For example:

    `#literal
matches any literal (#(), #foo, 1, etc.)

` (backquote) - recurse into
Whenever a match is found, look inside this matched node for more matches.
For example:
    `@object foo
matches a foo message sent to any expression on the outer level. However, the code "self foo foo" will be matched only once.

In contrast,

    ``@object foo
also matches foo sent to any object, plus for each match found, it will look for more matches in the ``@object part. Thus, this will match twice for the "self foo foo" example.

Method- vs. Expression search

The searcher can either search inside a methods body or include the methods message pattern (the selector definition) in the search.
For example, to search for getter messages (which return a variable which is named the same as the methods name), we need the following search pattern:
    `sel
	^ `sel
AND we must specify that the search should be a "method-search", by setting the "Method"-CheckBox field in the dialog.

Examples

Search for a particular message being sent with a particular argument

Search for Array instance creations with a constant size of 3 (same as above):
    Array new:3
Search for Array instance creations with any constant size:
    Array new: `#n
Search for Array instance creations where a variable specifies the size:
    Array new: `v
Search for all Array instance creations (any expression as size):
    Array new: `@e

Search for a particular message being sent to a global

Search for at:put: being sent to the Smalltalk-global, with a variables value as argument, use
    Smalltalk at:`key put:`val
the above does not match for literal values or expression values as argument(s).
To match those, use
    Smalltalk at:`@key put:`@val
to even look into the argument and look for sends there too, use:
    Smalltalk at:``@key put:``@val

Search for any message send

To search for any message send:
    ``@rec `@msg: ``@args

To search for exception handlers

    ``@rec on: ``@arg1 do: ``@arg2
and:
    ``@rec handle: ``@arg1 do: ``@arg2
or, for a particular class:
    StreamError handle: ``@arg1 do: ``@arg2

To search for empty exception handlers

   Error handle: [ :``@args | ] do: ``@blk
and:
   ``@blk on: Error do: [ :``@args | ]

Some examples of searches for bad (intention revealing) code

    ``@object not ifTrue: ``@block
and:
    ``@object not ifFalse: ``@block
are obviously easier written by negating the if-test message. As a final example, of a more complex pattern, the following searches for collect:-messages which collect the results of a simple message send (i.e. are effectively map: operations):
    ``@expr collect:[:`v | `v `@sel: ``@args]

Copyright © eXept Software AG, all rights reserved


Doc $Revision: 1.4 $ $Date: 2003/10/27 08:52:17 $