|
Class: ParseTreeSearcher
Object
|
+--RBProgramNodeVisitor
|
+--ParseTreeSearcher
|
+--ParseTreeRewriter
- Package:
- stx:goodies/refactoryBrowser/parser
- Category:
- Refactory-ParseTree Matching
- Version:
- rev:
1.89
date: 2024/01/22 14:20:55
- user: cg
- file: ParseTreeSearcher.st directory: goodies/refactoryBrowser/parser
- module: stx stc-classLibrary: parser
ParseTreeSearcher walks over a normal source code parse tree using the visitor pattern, and then matches these nodes against the meta-nodes using the match:inContext: methods defined for the meta-nodes.
Instance Variables:
answer <Object>
the 'answer' that is propagated between matches
argumentSearches <Collection of: (Association key: BRProgramNode value: BlockClosure)>
argument searches (search for the BRProgramNode and perform the Block when it is found)
context <BRSmallDictionary>
a dictionary that contains what each meta-node matches against. This could be a normal Dictionary that is created for each search, but is created once and reused (efficiency).
searches <Collection of: (Association key: BRProgramNode value: BlockClosure)>
non-argument searches (search for the BRProgramNode and perform the Block when its found)
currentSearchContext
the current search context (from checkMethod:)
so that match rules can determine where they are (see RBToDoFillRule)
suppressQuickStringSearches
can be set to suppress quick string searches in the SearchRules;
this must be set to search in the expanded code of synthetic messageSends
(eg. to find the i'xxx' expressions when searching for senders of #resources).
accessing
-
treeMatching: aString in: aParseTree
-
-
treeMatchingStatements: aString in: aParseTree
-
instance creation
-
allMessageSends
-
return a searcher which searches all messageSends
(collects messageSend nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m self foo. self bar. self baz:(self foe)'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allMessageSends.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allMessageSendsForWhich: aFilter
-
return a searcher which searches all messageSends
(collects messageSend nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m self foo. self bar. self baz:(self foe)'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allMessageSendsForWhich:[:aNode | aNode selector numArgs == 0].
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allMessageSendsMatching: pattern ignoreCase: doIgnoreCase
-
return a searcher which searches all messageSends which GLOB match a given pattern
(collects messageSend nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m self foo. self barFoe. self baz:(self foe)'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allMessageSendsMatching:'*fo*' ignoreCase:false.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m self foo. self barFoe. self baz:(self foe)'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allMessageSendsMatching:'*fo*' ignoreCase:true.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allMessageSendsMatchingAny: patternCollection ignoreCase: doIgnoreCase
-
return a searcher which searches all messageSends which GLOB match any pattern of a given set of patterns
(collects messageSend nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m self foo. self fOO. self barFoe. self xFoe. self baz:(self foe)'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allMessageSendsMatchingAny:#('fo*' 'b*Fo*') ignoreCase:false.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
searcher := ParseTreeSearcher allMessageSendsMatchingAny:#('fo*' 'b*Fo*') ignoreCase:true.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allMessageSendsTo: searchSelector ignoreCase: doIgnoreCase
-
return a searcher which searches all messageSends with a particular selector
(collects messageSend nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m self foo. self barFoe. self xFoe. self baz:(self foe)'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allMessageSendsTo:#'xfoe' ignoreCase:true.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allMessageSendsToAny: selectorCollection ignoreCase: doIgnoreCase
-
return a searcher which searches all messageSends with a selector from a given set of selectors
(collects messageSend nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m self foo. self barFoe. self xFoe. self baz:(self foe)'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allMessageSendsToAny:#('foe' 'xfoe') ignoreCase:true.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allModificationsOfAnyVariableIn: aCollectionOfVariableNames
-
return a searcher which searches all modifications of any variable in aCollectionOfVariableNames
(collects assignment nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz faz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := faz := 5.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allModificationsOfAnyVariableIn:#('foo' 'baz').
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz faz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := faz := 5.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allModificationsOfAnyVariableIn:#('f*' '*z').
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allModificationsOfGlobalVariablesMatching: aFilter
-
return a searcher which searches all variable modifications
(collects assignement nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| Array := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := 5.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allModificationsOfGlobalVariablesMatching:[:aNode | true].
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allModificationsOfVariable: aVariableNameOrPattern
-
return a searcher which searches all modifications of a variable
(collects assignment nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz faz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := faz := 5.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allModificationsOfVariable:'foo'.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allModificationsOfVariablesMatching: aFilter
-
return a searcher which searches all variable modifications
(collects assignement nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := 5.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allModificationsOfVariablesMatching:[:aNode | true].
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allReadsOfAnyVariableIn: aCollectionOfVariableNames
-
return a searcher which searches all reads of any variable in aCollectionOfVariableNames
(collects variable nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReadsOfAnyVariableIn:#('foo').
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := 5. self bar. self bar:baz'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReadsOfAnyVariableIn:#('foo' 'bar').
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := 5. self bar. self bar:baz'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReadsOfAnyVariableIn:#('b*').
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allReadsOfVariablesMatching: aFilter
-
return a searcher which searches all variable reads
(collects variable nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := 5.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReadsOfVariablesMatching:[:aNode | true].
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1. bar := foo. foo := foo.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReadsOfVariablesMatching:[:aNode | true].
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allReferencesToAnyVariableIn: aCollectionOfVariableNames
-
return a searcher which searches all references to any variable in aCollectionOfVariableNames
(collects variable nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReferencesToAnyVariableIn:#('foo').
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := 5. self bar. self bar:baz'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReferencesToAnyVariableIn:#('foo' 'bar').
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := 5. self bar. self bar:baz'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReferencesToAnyVariableIn:#('b*').
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
allReferencesToVariablesMatching: aFilter
-
return a searcher which searches all variable references
(collects variable nodes)
Usage example(s):
|tree searcher nodes|
tree := RBParser
parseSearchMethod:'m |foo bar baz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := 5.'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher allReferencesToVariablesMatching:[:aNode | true].
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|
-
getterMethod: aVarName
-
return a searcher which matches a getter method for a variable named aVarName.
Returns nil if no match,
or the selector of the method (which may be different from varName) if it does.
Slightly different from isGetterMethod, which requires that the method's name is the same as the variable's
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ foo'
onError: [:str :pos | nil].
searcher := self getterMethod:'foo'.
searcher executeTree:tree.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ bar'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher getterMethod:'foo'.
searcher executeTree:tree.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ bar'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher getterMethod:'bar'.
searcher executeTree:tree.
|
-
handlesException
-
return a searcher which matches a method which handles an exception.
Returns false if no match, true otherwise.
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg [ foo := arg ] on:Error do:[]'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher handlesException.
searcher executeTree:tree.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg foo := arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher handlesException.
searcher executeTree:tree.
|
-
hasGuardingIf
-
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg arg ifTrue:[ arg fooBar ]'
onError: [:str :pos | nil].
searcher := self hasGuardingIf.
searcher executeTree:tree initialAnswer:false.
tree := RBParser
parseSearchMethod:'foo:arg arg fooBar'
onError: [:str :pos | nil].
searcher := self hasGuardingIf.
searcher executeTree:tree initialAnswer:false.
-
isGetterMethod
-
return a searcher which matches any getter method (just gets a variable and has the same name).
Returns false if no match, true if it does.
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ foo'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isGetterMethod.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ bar'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isGetterMethod.
searcher executeTree:tree initialAnswer:false.
|
-
isGetterMethod: aVarName
-
return a searcher which matches a getter method for aVarName.
Returns false if no match, true if it does.
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ foo'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isGetterMethod:'foo'.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ foo + 1'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isGetterMethod:'foo'.
searcher executeTree:tree initialAnswer:false.
|
-
isGetterOrSetterMethod
-
return a searcher which matches a getter or setter method.
Returns false if no match, true if it does.
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg foo := arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isGetterOrSetterMethod.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ foo'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isGetterOrSetterMethod.
searcher executeTree:tree initialAnswer:false.
|
-
isGetterOrSetterMethod: aVarName
-
return a searcher which matches a getter or setter method for aVarName.
Returns false if no match, true if it does.
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg foo := arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isGetterOrSetterMethod:'foo'.
searcher executeTree:tree initialAnswer:false.
|
-
isJustReturningBoolean
-
return a searcher which matches a simple ^true or ^false method (i.e. a tester).
Returns false if no match, true if it does.
ATTENTION:
the original implementation (from RefactoryInc/Squeak) only matched unary methods;
this was changed in ST/X to also match methods with arguments
(i.e. `@method instead of `method in the match pattern)
Usage example(s):
|tree searcher|
searcher := ParseTreeSearcher isJustReturningBoolean.
tree := RBParser
parseSearchMethod:'foo ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
tree := RBParser
parseSearchMethod:'foo ^false'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
tree := RBParser
parseSearchMethod:'foo:bla ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
|
-
isJustReturningFalse
-
return a searcher which matches a simple ^false method (i.e. a tester).
Returns false if no match, true if it does.
ATTENTION:
the original implementation (from RefactoryInc/Squeak) only matched unary methods;
this was changed in ST/X to also match methods with arguments
(i.e. `@method instead of `method in the match pattern)
Usage example(s):
|tree searcher|
searcher := ParseTreeSearcher isJustReturningFalse.
tree := RBParser
parseSearchMethod:'foo ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false) not.
tree := RBParser
parseSearchMethod:'foo ^false'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
tree := RBParser
parseSearchMethod:'foo:bla ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false) not.
|
-
isJustReturningItsArgument
-
return a searcher which matches a simple ^ arg.
That method definitely has no side effects.
Returns false if no match, true if it does.
Usage example(s):
should match
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg ^arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningItsArgument.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
should NOT match
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg1 foo:arg2 ^arg1'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningItsArgument.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
should NOT match
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^123'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningItsArgument.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
should NOT match
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ bar'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningItsArgument.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
should NOT match
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ 123 bla'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningItsArgument.
searcher executeTree:tree initialAnswer:false.
|
-
isJustReturningLiteralString: aLiteralString
-
return a searcher which matches a simple ^ literal.
Returns false if no match, true if it does.
Notice the somewhat misleading name of this method:
not a string-literal, but the string of a literal is passed in;
i.e. to test for a true-returner, pass 'true',
but for a true-string returner, pass '''true''' (with quotes).
ATTENTION:
the original implementation (from RefactoryInc/Squeak) only matched unary methods;
this was changed in ST/X to also match methods with arguments
(i.e. `@method instead of `method in the match pattern)
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^true'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningLiteralString:'0'.
self assert:( searcher executeTree:tree initialAnswer:false ) not.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^true'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningLiteralString:'true'.
self assert:( searcher executeTree:tree initialAnswer:false ).
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ 0'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningLiteralString:'0'.
self assert:( searcher executeTree:tree initialAnswer:false ).
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ ''true'''
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningLiteralString:'''true'''.
self assert:( searcher executeTree:tree initialAnswer:false ).
|
-
isJustReturningSelf
-
return a searcher which matches a simple ^ self.
That method definitely has no side effects.
Returns false if no match, true if it does.
ATTENTION:
matches methods with or without arguments
Usage example(s):
|tree searcher|
searcher := ParseTreeSearcher isJustReturningSelf.
tree := RBParser
parseSearchMethod:'foo ^self'
onError: [:str :pos | nil].
searcher executeTree:tree initialAnswer:false.
tree := RBParser
parseSearchMethod:'foo:bla ^self'
onError: [:str :pos | nil].
searcher executeTree:tree initialAnswer:false.
|
-
isJustReturningSomething
-
return a searcher which matches a simple ^ something.
That method definitely has no side effects.
Returns false if no match, true if it does.
ATTENTION:
the original implementation (from RefactoryInc/Squeak) only matched unary methods;
this was changed in ST/X to also match methods with arguments
(i.e. `@method instead of `method in the match pattern)
Usage example(s):
|tree searcher|
searcher := ParseTreeSearcher isJustReturningSomething.
tree := RBParser
parseSearchMethod:'foo ^true'
onError: [:str :pos | nil].
searcher executeTree:tree initialAnswer:false.
tree := RBParser
parseSearchMethod:'foo:bla ^true'
onError: [:str :pos | nil].
searcher executeTree:tree initialAnswer:false.
tree := RBParser
parseSearchMethod:'foo:bla ^self'
onError: [:str :pos | nil].
searcher executeTree:tree initialAnswer:false.
tree := RBParser
parseSearchMethod:'foo self assert:true. ^true'
onError: [:str :pos | nil].
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^123'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningSomething.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ bar'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningSomething.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ 123 bla'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningSomething.
searcher executeTree:tree initialAnswer:false.
|
-
isJustReturningTrue
-
return a searcher which matches a simple ^true method (i.e. a tester).
Returns false if no match, true if it does.
ATTENTION:
the original implementation (from RefactoryInc/Squeak) only matched unary methods;
this was changed in ST/X to also match methods with arguments
(i.e. `@method instead of `method in the match pattern)
Usage example(s):
|tree searcher|
searcher := ParseTreeSearcher isJustReturningTrue.
tree := RBParser
parseSearchMethod:'foo ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
tree := RBParser
parseSearchMethod:'foo:bla ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^123'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningTrue.
self assert:(searcher executeTree:tree initialAnswer:false) not
|
-
isJustReturningTrueOrFalse
-
return a searcher which matches a simple ^true or ^false method (i.e. a tester).
Returns false if no match, true if it does.
ATTENTION:
the original implementation (from RefactoryInc/Squeak) only matched unary methods;
this was changed in ST/X to also match methods with arguments
(i.e. `@method instead of `method in the match pattern)
Usage example(s):
|tree searcher|
searcher := ParseTreeSearcher isJustReturningTrueOrFalse.
tree := RBParser
parseSearchMethod:'foo ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
tree := RBParser
parseSearchMethod:'foo:bla ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^123'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isJustReturningTrueOrFalse.
searcher executeTree:tree initialAnswer:false.
|
-
isJustReturningVariable
-
return a searcher which matches a simple ^ <var>
(i.e. a getter but not required to be named after the variable).
Returns false if no match, true if it does.
ATTENTION:
the original implementation (from RefactoryInc/Squeak) only matched unary methods;
this was changed in ST/X to also match methods with arguments
(i.e. `@method instead of `method in the match pattern)
Usage example(s):
|tree searcher|
searcher := ParseTreeSearcher isJustReturningVariable.
tree := RBParser
parseSearchMethod:'foo ^true'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false) not.
tree := RBParser
parseSearchMethod:'foo ^x'
onError: [:str :pos | nil].
self assert:(searcher executeTree:tree initialAnswer:false).
|
-
isSetterMethod
-
return a searcher which matches a setter method (just sets a variable and has the same name).
Returns false if no match, true if it does.
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg foo := arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isSetterMethod.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg bar := arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isSetterMethod.
searcher executeTree:tree initialAnswer:false.
|
-
isSubclassResponsibility
-
return a searcher which matches a simple 'self subclassResponsibility'.
Returns false if no match, true if it does.
Usage example(s):
|tree searcher matches|
searcher := ParseTreeSearcher isSubclassResponsibility.
matches := OrderedCollection new.
Method allInstancesDo:[:m |
|tree|
(tree := m parseTree) notNil ifTrue:[
(searcher executeTree:(m parseTree) initialAnswer:false) ifTrue:[
matches add:m
]
]
].
Tools::NewSystemBrowser browseMethods:matches.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^self subclassResponsibility'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isSubclassResponsibility.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo self subclassResponsibility'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isSubclassResponsibility.
searcher executeTree:tree initialAnswer:false.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ self bla subclassResponsibility'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher isSubclassResponsibility.
searcher executeTree:tree initialAnswer:false.
|
-
isUsingValueFromMessage: aSelector
-
return a searcher which searches for
senders of aSelector AND which use the returned value.
This is useful if one isn't sure, if self or sth. else should be returned from
a method. Especially, if one (re-)defines a methid which is already present in other
classes in the system; such as add:/do: etc.
Returns false if no match, true if it does.
ATTENTION:
matches methods with or without arguments
Usage example(s):
|tree searcher|
searcher := ParseTreeSearcher isUsingValueFromMessage:#add:.
tree := RBParser
parseSearchMethod:'foo:arg ^arg add:10'
onError: [:str :pos | nil].
searcher executeTree:tree initialAnswer:false.
tree := RBParser
parseSearchMethod:'foo:arg arg add:10. ^self'
onError: [:str :pos | nil].
searcher executeTree:tree initialAnswer:false.
|
-
justDelegates
-
return a searcher which matches a delegating method;
that is one which simply forwards the message to someone else.
Returns false if no match, true if it does.
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ instvar foo'
onError: [:str :pos | nil].
searcher := self justDelegates.
searcher executeTree:tree.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo ^ self foo + 1'
onError: [:str :pos | nil].
searcher := self justDelegates.
searcher executeTree:tree
|
-
justSendsSuper
-
return a searcher which matches a super-sending method.
Returns false if no match, true if it does.
-
raisesException
-
return a searcher which matches a method which raises an exception.
Returns false if no match, true otherwise.
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg [ foo := arg ] on:Error do:[ Error raiseRequest ]'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher raisesException.
searcher executeTree:tree.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg foo := arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher raisesException.
searcher executeTree:tree.
|
-
returnSetterMethod: aVarName
-
return a searcher which matches a returning setter method.
Returns nil if no match, the selector if it does.
-
setterMethod: aVarName
-
return a searcher which matches a setter method for a variable named aVarName.
Returns nil if no match,
or the selector of the method (which may be different from varName) if it does.
Slightly different from isSetterMethod, which requires that the method's name is the same as the variable's
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg foo := arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher setterMethod:'foo'.
searcher executeTree:tree.
|
Usage example(s):
|tree searcher|
tree := RBParser
parseSearchMethod:'foo:arg bar := arg'
onError: [:str :pos | nil].
searcher := ParseTreeSearcher setterMethod:'foo'.
searcher executeTree:tree.
|
private
-
buildSelectorString: aSelector
-
-
buildSelectorTree: aSelector
-
-
buildTree: aString method: aBoolean
-
utilities
-
isDefinitelyGetterMethod: aMethod
-
checks a method for being a true getter (name equals variable returned)
-
matchMethod: aMethod with: aMatcher
-
common helper for common matches.
aMather (which was probably create with one of my isJustReturningSomething, is*** methods)
is applied to aMethod, and true is returned if it matches.
-
methodIsGetterMethod: aMethod
-
checks a method for being a true getter (name equals variable returned)
-
methodIsJustReturningSomething: aMethod
-
checks a method for being a simple return something method
(i.e. definitely no side effects)
Usage example(s):
self methodIsJustReturningSomething:(Workflow::AbstractPin compiledMethodAt:#owner)
|
-
methodIsJustReturningTrue: aMethod
-
checks a method for being a simple return true method
(i.e. definitely no side effects)
Usage example(s):
self methodIsJustReturningTrue:(TimeDuration compiledMethodAt:#isTimeDuration)
|
-
methodIsSetterMethod: aMethod
-
checks a method for being a true setter (name equals variable returned)
accessing
-
addArgumentRule: aParseTreeRule
-
-
addArgumentRules: ruleCollection
-
-
addArgumentSearches: aSearchCondition
-
-
addMethodSearches: aSearchCondition
-
-
addRule: aParseTreeRule
-
-
addRules: ruleCollection
-
-
addSearches: aSearchCondition
-
-
answer
-
-
computeQuickSearchStrings
-
Compute a collection of OR-strings to search for.
Each is a string or collection of AND-strings.
This is collected from the individual searches,
of which each may return a collection of AND-strings.
OR means: if any of the elements is present, do a full match;
otherwise reject.
AND means: all of the elements must be present for a full match,
otherwise reject
-
context
-
-
currentSearchContext
-
-
currentSearchContext: aSearchContext
-
-
executeMethod: aParseTree
-
-
executeMethod: aParseTree initialAnswer: anObject
-
-
executeTree: aParseTree
-
Save our current context, in case someone is performing another search inside a match.
Notice: kept for backward compatibility;
cannot forward this to executeTree:in: here, because not everyone (SmallLint and others)
are guaranteed to implement it (but instead redefine executeTree:).
-
executeTree: aParseTree in: optionalClassBeingProcessed
-
Save our current context, in case someone is performing another search inside a match.
-
executeTree: aParseTree initialAnswer: aValue
-
-
messages
-
in ST/X, optimized messages are also in the literal array..
-
moreAnswers
-
if the rule found multiple places, this returns the other answers
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
searches
-
-
setMessages: aCollection
-
converting
-
asSearcher
-
enumerating
-
matchingNodesForSource: aString tree: anRBProgramNode do: aBlock
-
Evaluate block for each node in source and its corresponding tree that matches
-
selectionIntervalsForSource: aString tree: anRBProgramNode do: aBlock
-
Evaluate block for each node's sourceInterval (for highlighting)
-
selectionIntervalsForSource: aString tree: anRBProgramNode in: aClass do: aBlock
-
Evaluate block for each node's sourceInterval (for highlighting)
-
selectionIntervalsForSource: aString tree: anRBProgramNode rule: aRuleOrNil in: aClass do: aBlock
-
Evaluate block for each node's sourceInterval (for highlighting).
If aRuleOrNil is not nil, it is given a chance to provide a better interval
for highlighting the seletor of the node only
initialize-release
-
answer: anObject
-
probably am only interested in the very first answer
-
initialize
-
obsolete
-
addArgumentSearch: aSearchCondition
-
-
addMethodSearch: aSearchCondition
-
-
addSearch: aSearchCondition
-
-
buildMethodParseTreeRuleFor: aSearchCondition
-
-
buildParseTreeRuleFor: aSearchCondition
-
private
-
foundMatch
-
-
lookForMoreMatchesInContext: oldContext
-
-
performSearches: aSearchCollection on: aNode
-
please read the comment in alwaysPerformAllSearches
-
recusivelySearchInContext
-
We need to save the matched context since the other searches might overwrite it.
-
visitNode: aNode matching: aSearchCollection
-
-
withSavedContextDo: aBlock
-
Protect our current context, in case someone is performing another search inside a match.
-
withSavedContextDo: aBlock in: optionalClassBeingProcessed
-
Protect our current context, in case someone is performing another search inside a match.
searching - setup
-
matches: aString do: aBlock
-
-
matchesAnyArgumentOf: stringCollection do: aBlock
-
-
matchesAnyMethodOf: aStringCollection do: aBlock
-
-
matchesAnyOf: aStringCollection do: aBlock
-
-
matchesAnyTreeOf: treeCollection do: aBlock
-
-
matchesArgument: aString do: aBlock
-
-
matchesArgumentTree: aBRProgramNode do: aBlock
-
-
matchesMethod: aString do: aBlock
-
-
matchesTree: aBRProgramNode do: aBlock
-
testing
-
alwaysPerformAllSearches
-
a flag, to fix a bug? in the performSearches,
which stops after the first matching searchRule, even if there are more rules to be
considered.
This bug affects the literal replacements, inside literal arrays,
in case multiple such replaces have been defined
eg. a rewriter like:
replacer := ParseTreeSourceRewriter new.
replacer replaceLiteral: #lit1 with: #newLit1.
replacer replaceLiteral: #lit2 with: #newLit2.
The original searcher would only replace one literal and stop performing other replaces,
after the first hit. However, if there is a single literal array with both lit1 and lit2 inside,
all other replaces must also be performed.
As I have no idea on what other effects an unconditional change in performSearches might have,
this new behavior is made conditional on the return value of this method
(and it is redefined in ParseTreeSourceRewriter
-
canMatchMethod: aCompiledMethod
-
this does a quickReject based on the set of sent messages
(in the searches vs. messages in the method)
-
canQuicklyReject: sourceCode
-
if I have quickSearchStrings, try a quick reject based on them.
This may generate false negatives (i.e. lets source pass, even though
it should not), but still reduces the amount of parser work in the order
of 90%, thus making code searches 10 times faster.
visiting
-
visitArgument: aNode
-
(comment from inherited method)
Here to allow subclasses to detect arguments or temporaries.
-
visitNode: aNode
-
|tree searcher nodes|
'the tree to search'.
tree := RBParser
parseSearchMethod:'m |foo bar baz faz| foo := 1. bar := 2. foo := 3. bar := foo := 4. foo := bar := faz := 5.'
onError: [:str :pos | nil].
'setup the searcher'.
searcher := ParseTreeSearcher allModificationsOfVariable:'foo'.
'do the search'.
searcher executeTree:tree initialAnswer:(nodes := OrderedCollection new).
nodes.
|