|
Class: ParseTreeSearcher
Object
|
+--RBProgramNodeVisitor
|
+--ParseTreeSearcher
|
+--ParseTreeRewriter
- Package:
- stx:goodies/refactoryBrowser/parser
- Category:
- Refactory-ParseTree Matching
- Version:
- rev:
1.73
date: 2019/07/21 06:32:34
- 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 BlockClosure when its 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 BlockClosure when its found)
currentSearchContext the current search context (from checkMethod:) so that match rules can determine where they are (see RBToDoFillRule)
accessing
-
treeMatching: aString in: aParseTree
-
-
treeMatchingStatements: aString in: aParseTree
-
instance creation
-
allMessageSends
-
return a searcher which searches all messageSends
(collects messageSend nodes)
-
allMessageSendsForWhich: aFilter
-
return a searcher which searches all messageSends
(collects messageSend nodes)
-
allMessageSendsMatching: pattern ignoreCase: doIgnoreCase
-
return a searcher which searches all messageSends which match a given pattern
(collects messageSend nodes)
-
allMessageSendsMatchingAny: patternCollection ignoreCase: doIgnoreCase
-
return a searcher which searches all messageSends which match any pattern of a given set of patterns
(collects messageSend nodes)
-
allMessageSendsTo: searchSelector ignoreCase: doIgnoreCase
-
return a searcher which searches all messageSends with a particular selector
(collects messageSend nodes)
-
allMessageSendsToAny: selectorCollection ignoreCase: doIgnoreCase
-
return a searcher which searches all messageSends with a selector from a given set of selectors
(collects messageSend nodes)
-
allModificationsOfAnyVariableIn: aCollectionOfVariableNames
-
return a searcher which searches all modifications of any variable in aCollectionOfVariableNames
(collects assignment nodes)
-
allModificationsOfGlobalVariablesMatching: aFilter
-
return a searcher which searches all variable modifications
(collects assignement nodes)
-
allModificationsOfVariablesMatching: aFilter
-
return a searcher which searches all variable modifications
(collects assignement nodes)
-
allReadsOfAnyVariableIn: aCollectionOfVariableNames
-
return a searcher which searches all reads of any variable in aCollectionOfVariableNames
(collects variable nodes)
-
allReadsOfVariablesMatching: aFilter
-
return a searcher which searches all variable reads
(collects variable nodes)
-
allReferencesToAnyVariableIn: aCollectionOfVariableNames
-
return a searcher which searches all references to any variable in aCollectionOfVariableNames
(collects variable nodes)
-
allReferencesToVariablesMatching: aFilter
-
return a searcher which searches all variable references
(collects variable nodes)
-
getterMethod: aVarName
-
return a searcher which matches a getter method.
Returns nil if no match, the selector if it does.
-
handlesException
-
return a searcher which matches a method which handles an exception.
Returns false if no match, true otherwise.
-
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.
Returns false if no match, true if it does.
-
isGetterOrSetterMethod
-
return a searcher which matches a getter or setter method.
Returns false if no match, true if it does.
-
isGetterOrSetterMethod: aVarName
-
return a searcher which matches a getter or setter method for aVarName.
Returns false if no match, true if it does.
-
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. `@methods instead of `methods in the match pattern)
-
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
-
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)
-
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. `@methods instead of `methods in the match pattern)
-
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. `@methods instead of `methods in the match pattern)
-
isSetterMethod
-
return a searcher which matches a setter method.
Returns false if no match, true if it does.
-
isSubclassResponsibility
-
return a searcher which matches a simple 'self subclassResponsibility'.
Returns false if no match, true if it does.
-
justDelegates
-
return a searcher which matches a delegating method.
Returns false if no match, true if it does.
-
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.
-
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.
Returns nil if no match, the selector if it does.
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
-
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.
-
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
-
searching
-
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
-
-
visitNode: aNode
-
|