AST-Core

RBArrayNode
A RBArrayNode is xxxxxxxxx.
Instance Variables
left: <Object>
periods: <Object>
right: <Object>
statements: <Object>
left
- xxxxx
periods
- xxxxx
right
- xxxxx
statements
- xxxxx
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
children
copyInContext:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
isArray
lastIsReturn
left
left:
match:inContext:
needsParenthesis
periods
periods:
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
precedence
references:
replaceNode:withNode:
right
right:
startWithoutParentheses
statementComments
statements
statements:
stopWithoutParentheses
uses:
RBAssignmentNode
RBAssignmentNode is an AST node for assignment statements
Instance Variables:
assignment <Integer> position of the :=
value <RBValueNode> the value that we're assigning
variable <RBVariableNode> the variable being assigned
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
assignmentOperator
assignmentPosition
assigns:
bestNodeFor:
children
copyInContext:
directlyUses:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
isAssignment
match:inContext:
needsParenthesis
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
precedence
replaceNode:withNode:
replaceSourceWith:
Check if we need to convert the assignment. Also check if we are being replaced with a setter message send. If so, create the replacements to edit the original source.
startWithoutParentheses
stopWithoutParentheses
uses:
value
value:
variable
variable:
variable:value:
variable:value:position:
RBAssignmentToken
RBAssignmentToken is the first-class representation of the assignment token ':='
isAssignment
length
RBBinarySelectorToken
RBBinarySelectorToken is the first-class representation of a binary selector (e.g. +)
isBinary
RBBlockNode
RBBlockNode is an AST node that represents a block "[...]".
Instance Variables:
arguments <SequenceableCollection of: RBVariableNode> the arguments for the block
bar <Integer | nil> position of the | after the arguments
body <RBSequenceNode> the code inside the block
colons <SequenceableCollection of: Integer> positions of each : before each argument
left <Integer> position of [
right <Integer> position of ]
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
allArgumentVariables
allDefinedVariables
argumentNames
arguments
arguments:
arguments:body:
bar
bar:
blockVariables
body
body:
children
colons:
copyInContext:
defines:
directlyUses:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
isBlock
isImmediateNode
isLast:
left
left:
match:inContext:
needsParenthesis
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
precedence
references:
replaceNode:withNode:
right
right:
startWithoutParentheses
statementComments
stopWithoutParentheses
uses:
RBBlockReplaceRule
RBBlockReplaceRule replaces the matching node by the result of evaluating replaceBlock. This allows arbitrary computation to come up with a replacement.
Instance Variables:
replaceBlock <BlockClosure> The block that returns the node to replace to matching node with.
foundMatchFor:
initialize
Subclasses should redefine this method to perform initializations on instance creation
searchFor:replaceWith:
searchFor:replaceWith:when:
searchForMethod:replaceWith:
searchForMethod:replaceWith:when:
searchForTree:replaceWith:
searchForTree:replaceWith:when:
RBCascadeNode
RBCascadeNode is an AST node for cascaded messages (e.g., "self print1 ; print2").
Instance Variables:
messages <SequenceableCollection of: RBMessageNode> the messages
semicolons <SequenceableCollection of: Integer> positions of the ; between messages
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
bestNodeFor:
children
copyInContext:
directlyUses:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
isCascade
match:inContext:
messages
messages:
messages:semicolons:
needsParenthesis
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
precedence
receiver
replaceNode:withNode:
startWithoutParentheses
statementComments
stopWithoutParentheses
uses:
whichNodeIsContainedBy:
RBConfigurableFormatter
RBConfigurableFormatter formats the Refactoring Browser's parse trees. It has many more formatting options than the default formatter used by the RB. To change the RB to use this formatter, execute "RBProgramNode formatterClass: RBConfigurableFormatter". For some refactorings the RB must reformat the code after the change, so it is good to have a formatter configured to your tastes.
Instance Variables:
codeStream <PositionableStream> the stream we are writing our output to
indent <Integer> how many times are we indenting a new line -- indents are normally tabs but could be any whitespace string
lineStart <Integer> the position of the character that started the current line. This is used for calculating the line length.
lookaheadCode <Dictionary key: RBProgramNode value: String> sometimes we need to lookahead while formatting, this dictionary contains the nodes that have already been formatted by lookahead
originalSource <String> the original source before we started formatting. This is used to extract the comments from the original source.
acceptArrayNode:
acceptAssignmentNode:
acceptBlockNode:
acceptCascadeNode:
acceptLiteralArrayNode:
acceptLiteralNode:
acceptMessageNode:
acceptMethodNode:
acceptPatternBlockNode:
acceptPatternWrapperBlockNode:
acceptPragmaNode:
acceptReturnNode:
acceptSequenceNode:
acceptVariableNode:
addNewLinesBeforeStatementStartingAt:
bracketWith:around:
currentLineLength
format:
format:withIndents:
formatArray:
formatBlock:
formatBlockArgumentsFor:
formatCommentWithStatements
formatCommentWithStatements:
formatCommentsFor:
formatMethodBodyFor:
formatMethodCommentFor:
formatMethodPatternFor:
formatPragmasFor:
formatSelectorAndArguments:
formatSelectorAndArguments:firstSeparator:restSeparator:
formatSequenceCommentsFor:
formatSequenceNodeStatementsFor:
formatStatementCommentsFor:
formatTemporariesFor:
formattedSourceFor:
indent:
indent:around:
indentAround:
indentString
indentString:
indentsForKeywords
indentsForKeywords:
initialize
Subclasses should redefine this method to perform initializations on instance creation
isLineTooLong:
isMultiLineMessage:
lineUpBlockBrackets
lineUpBlockBrackets:
maxLineLength
maxLineLength:
methodSignatureOnMultipleLines
methodSignatureOnMultipleLines:
minimumNewLinesBetweenStatements
minimumNewLinesBetweenStatements:
multiLineMessages
multiLineMessages:
needsParenthesisFor:
newLine
newLineAfterCascade
newLineAfterCascade:
newLineBeforeFirstCascade
newLineBeforeFirstCascade:
newLineBeforeFirstKeyword
newLineBeforeFirstKeyword:
newLines:
newLinesAfterMethodComment
newLinesAfterMethodComment:
newLinesAfterMethodPattern
newLinesAfterMethodPattern:
newLinesAfterTemporaries
newLinesAfterTemporaries:
newLinesBeforeStartingAt:
numberOfArgumentsForMultiLine
numberOfArgumentsForMultiLine:
oneLineMessages
oneLineMessages:
periodsAsTerminators
periodsAsTerminators:
periodsAtEndOfBlock
periodsAtEndOfBlock:
periodsAtEndOfMethod
periodsAtEndOfMethod:
precedenceOf:greaterThan:
Put parenthesis around things that are preceived to have 'lower' precedence. For example, 'a + b * c'
-> '(a + b) * c' but 'a * b + c' -> 'a * b + c'
retainBlankLinesBetweenStatements
retainBlankLinesBetweenStatements:
settingsOn:
space
stringFollowingReturn
stringFollowingReturn:
stringInsideBlocks
stringInsideBlocks:
stringInsideParentheses
stringInsideParentheses:
traditionalBinaryPrecedence
traditionalBinaryPrecedence:
useTraditionalBinaryPrecedenceForParentheses
useTraditionalBinaryPrecedenceForParentheses:
visitNode:
willBeMultiline:
with:and:do:separatedBy:
writeString:
RBFormatter
RBFormatter formats a parse tree. It is an example of a Visitor. This is rarely called directly. Sending 'formattedCode' to a parse tree uses this algorithm to return a pretty-printed version.
Instance Variables:
codeStream <PositionableStream> The buffer where the output is accumulated.
firstLineLength <Integer> The length of the first line of a message send.
lineStart <Integer> The position of the current line's start.
tabs <Integer> The number of tabs currently indented.
acceptArrayNode:
acceptAssignmentNode:
acceptBlockNode:
acceptBlockNode:startBlockString:endBlockString:
acceptCascadeNode:
acceptLiteralArrayNode:
acceptLiteralNode:
acceptMessageNode:
acceptMethodNode:
acceptPatternBlockNode:
acceptPatternWrapperBlockNode:
acceptPragmaNode:
acceptReturnNode:
acceptSequenceNode:
acceptVariableNode:
firstLineLength
for:do:separatedBy:
This is implemented here since IBM Smalltalk doesn't implement a do:separatedBy: method
format:
formatMessage:cascade:
formatMessageSelector:withArguments:multiline:
formatMethodCommentFor:indentBefore:
formatMethodPatternFor:
formatPragmasFor:
formatStatementCommentFor:
formatStatementsFor:
formatTemporariesFor:
indent
indent:while:
indentWhile:
initialize
Subclasses should redefine this method to perform initializations on instance creation
isMultiLine
lastLineLength
lineLength
lineStart:
maxLineSize
maximumArgumentsPerLine
needsParenthesisFor:
newLinesFor:startingAt:
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
precedenceOf:greaterThan:
Put parenthesis around things that are preceived to have 'lower' precedence. For example, 'a + b * c'
-> '(a + b) * c' but 'a * b + c' -> 'a * b + c'
selectorsToLeaveOnLine
selectorsToStartOnNewLine
startMessageSendOnNewLine:
visitNode:
RBIdentifierToken
RBIdentifierToken is the first class representation of an identifier token (e.g. Class)
isIdentifier
isPatternVariable
RBKeywordToken
RBKeywordToken is the first-class representation of a keyword token (e.g. add:)
isKeyword
isPatternVariable
RBLiteralArrayNode
A RBLiteralArrayNode is xxxxxxxxx.
Instance Variables
contents: <Object>
isByteArray: <Object>
start: <Object>
stop: <Object>
contents
- xxxxx
isByteArray
- xxxxx
start
- xxxxx
stop
- xxxxx
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
children
contents
contents:
copyInContext:
equalTo:withMapping:
isForByteArray
isLiteralArray
match:inContext:
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
replaceNode:withNode:
replaceSourceWith:
startPosition:contents:stopPosition:isByteArray:
startWithoutParentheses
stopWithoutParentheses
value
value:
RBLiteralArrayToken
A RBLiteralArrayToken is xxxxxxxxx.
Instance Variables
isForByteArray
isLiteralArrayToken
RBLiteralNode
RBLiteralNode is an AST node that represents literals (e.g., #foo, #(1 2 3), true, etc.).
Instance Variables:
token <RBLiteralToken> the token that contains the literal value as well as its source positions
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
isImmediateNode
isLiteralNode
literalToken:
needsParenthesis
precedence
replaceSourceFrom:
replaceSourceWith:
value
value:
RBLiteralToken
RBLiteralToken is the first-class representation of a literal token (entire literals, even literal arrays, are a single token in the ST80 grammar.).
Instance Variables:
stopPosition <Integer> The position within the source code where the token terminates.
isLiteralToken
isMultiKeyword
length
realValue
stop:
storeOn:
Append to the argument aStream a sequence of characters that is an
expression whose evaluation creates an object similar to the receiver.
value:
value:start:stop:
RBLiteralValueNode
RBLiteralNode is an AST node that represents literals (e.g., #foo, #(1 2 3), true, etc.).
Instance Variables:
token <RBLiteralToken> the token that contains the literal value as well as its source positions
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
copyInContext:
literalToken:
startWithoutParentheses
stopWithoutParentheses
token
value
value:
RBMessageNode
RBMessageNode is an AST node that represents a message send.
Instance Variables:
arguments <SequenceableCollection of: RBValueNode> our argument nodes
receiver <RBValueNode> the receiver's node
selector <Symbol | nil> the selector we're sending (cached)
selectorParts <SequenceableCollection of: RBValueToken> the tokens for each keyword
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
arguments
arguments:
bestNodeFor:
buildSelector
children
copyInContext:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
isBinary
isCascaded
isContainmentReplacement:
isFirstCascaded
isKeyword
isMessage
isSelfSend
isSuperSend
isUnary
lastIsReturn
match:inContext:
needsParenthesis
numArgs
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
precedence
receiver
receiver:
receiver:selector:
receiver:selector:arguments:
receiver:selectorParts:arguments:
renameSelector:andArguments:
replaceContainmentSourceWith:
replaceNode:withNode:
If we're inside a cascade node and are changing the receiver, change all the receivers
replaceSourceWith:
replaceSourceWithMessageNode:
selector
selector:
selectorParts
selectorParts:
sentMessages
startWithoutParentheses
stopWithoutParentheses
RBMethodNode
RBMethodNode is the AST that represents a Smalltalk method.
Instance Variables:
arguments <SequenceableCollection of: RBVariableNode> the arguments to the method
body <BRSequenceNode> the body/statements of the method
nodeReplacements <Dictionary> a dictionary of oldNode -> newNode replacements
replacements <Collection of: RBStringReplacement> the collection of string replacements for each node replacement in the parse tree
selector <Symbol | nil> the method name (cached)
selectorParts <SequenceableCollection of: RBValueToken> the tokens for the selector keywords
source <String> the source we compiled
tags <Collection of: Interval> the source location of any resource/primitive tags
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
addNode:
addReplacement:
addReturn
addSelfReturn
allArgumentVariables
allDefinedVariables
argumentNames
arguments
arguments:
body
body:
buildSelector
changeSourceSelectors:arguments:
children
clearReplacements
copyInContext:
defines:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
initialize
Subclasses should redefine this method to perform initializations on instance creation
isLast:
isMethod
isPrimitive
lastIsReturn
map:to:
mappingFor:
match:inContext:
methodComments
methodNode
new
newSource
numArgs
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
pragmas
pragmas:
primitiveSources
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
references:
reformatSource
renameSelector:andArguments:
replaceNode:withNode:
selector
selector:
selector:arguments:body:
selector:body:
selectorParts
selectorParts:
selectorParts:arguments:
source
source:
start
stop
uses:
RBMultiKeywordLiteralToken
A RBMultiKeywordLiteralToken is xxxxxxxxx.
Instance Variables
isMultiKeyword
RBNumberLiteralToken
A RBNumberLiteralToken is xxxxxxxxx.
Instance Variables
source: <Object>
source
- xxxxx
source
source:
storeOn:
Append to the argument aStream a sequence of characters that is an
expression whose evaluation creates an object similar to the receiver.
value:start:stop:source:
RBParseTreeRewriter
ParseTreeRewriter walks over and transforms its RBProgramNode (tree). If the tree is modified, then answer is set to true, and the modified tree can be retrieved by the #tree method.
Instance Variables:
tree <RBProgramNode> the parse tree we're transforming
acceptArrayNode:
acceptAssignmentNode:
acceptBlockNode:
acceptCascadeNode:
acceptLiteralArrayNode:
acceptMessageNode:
acceptMethodNode:
acceptPragmaNode:
acceptReturnNode:
acceptSequenceNode:
executeTree:
Save our current context, in case someone is performing another search inside a match.
foundMatch
lookForMoreMatchesInContext:
removeTemporaryNamed:
rename:to:
rename:to:handler:
replace:with:
replace:with:in:
replace:with:in:onInterval:
replace:with:method:
replace:with:when:
replace:withValueFrom:
replace:withValueFrom:when:
replaceArgument:with:
replaceArgument:with:when:
replaceArgument:withValueFrom:
replaceArgument:withValueFrom:when:
replaceLiteral:with:
replaceMethod:with:
replaceMethod:with:when:
replaceMethod:withValueFrom:
replaceMethod:withValueFrom:when:
replaceStatements:with:in:onInterval:
replaceTree:withTree:
replaceTree:withTree:when:
tree
variable:getter:setter:
variable:getter:setter:receiver:
visitArguments:
RBParseTreeRule
RBParseTreeRule is the abstract superclass of all of the parse tree searching rules. A parse tree rule is the first class representation of a particular rule to search for. The owner of a rule is the algorithm that actually executes the search. This arrangement allows multiple searches to be conducted by a single Searcher.
Instance Variables:
owner <ParseTreeSearcher> The searcher that is actually performing the search.
searchTree <RBProgramNode> The parse tree to be searched.
canMatch:
context
foundMatchFor:
methodSearch:
methodSearchString:
owner:
performOn:
search:
searchString:
sentMessages
RBParseTreeSearcher
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: RBProgramNode value: BlockClosure)> argument searches (search for the BRProgramNode and perform the BlockClosure when its found)
context <RBSmallDictionary> 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).
messages <Collection> the sent messages in our searches
searches <Collection of: (Association key: RBProgramNode value: BlockClosure)> non-argument searches (search for the BRProgramNode and perform the BlockClosure when its found)
addArgumentRule:
addArgumentRules:
addRule:
addRules:
answer
answer:
buildSelectorString:
buildSelectorTree:
buildTree:method:
canMatchMethod:
context
executeMethod:initialAnswer:
executeTree:
Save our current context, in case someone is performing another search inside a match.
executeTree:initialAnswer:
foundMatch
getterMethod:
hasRules
initialize
Subclasses should redefine this method to perform initializations on instance creation
justSendsSuper
lookForMoreMatchesInContext:
matches:do:
matchesAnyArgumentOf:do:
matchesAnyMethodOf:do:
matchesAnyOf:do:
matchesAnyTreeOf:do:
matchesArgument:do:
matchesArgumentTree:do:
matchesMethod:do:
matchesTree:do:
messages
performSearches:on:
recusivelySearchInContext
We need to save the matched context since the other searches might overwrite it.
returnSetterMethod:
setterMethod:
treeMatching:in:
treeMatchingStatements:in:
visitArgument:
Here to allow subclasses to detect arguments or temporaries.
visitNode:
RBParser
RBParser takes a source code string and generates an AST for it. This is a hand-written, recursive descent parser and has been optimized for speed. The simplest way to call this is either 'RBParser parseExpression: aString' if you want the AST for an expression, or 'RBParser parseMethod: aString' if you want to parse an entire method.
Instance Variables:
currentToken <RBToken> The current token being processed.
emptyStatements <Boolean> True if empty statements are allowed. In IBM, they are, in VW they aren't.
errorBlock <BlockClosure> The block to evaluate on a syntax error.
nextToken <RBToken> The next token that will be processed. This allows one-token lookahead.
scanner <RBScanner> The scanner that generates a stream of tokens to parse.
source <String> The source code to parse
tags <Collection of: Interval> The source intervals of the tags appearing at the top of a method (e.g. Primitive calls)
Shared Variables:
ParserType <Symbol> the type code we are parsing
addCommentsTo:
arrayNodeClass
assignmentNodeClass
atEnd
blockNodeClass
cascadeNodeClass
errorBlock
errorBlock:
errorPosition
initialize
Subclasses should redefine this method to perform initializations on instance creation
initializeParserWith:
literalArrayNodeClass
literalNodeClass
messageNodeClass
methodNodeClass
nextToken
parseArgs
parseArray
parseAssignment
Need one token lookahead to see if we have a ':='. This method could
make it possible to assign the literals true, false and nil.
parseBinaryMessage
parseBinaryMessageWith:
parseBinaryPattern
parseBinaryPragma
parseBlock
parseBlockArgsInto:
parseCascadeMessage
parseExpression:
parseExpression:onError:
parseKeywordMessage
parseKeywordMessageWith:
parseKeywordPattern
parseKeywordPragma
parseLiteralArray
parseLiteralArrayObject
parseLiteralByteArray
parseLiteralByteArrayObject
parseMessagePattern
parseMethod
parseMethod:
parseMethod:onError:
parseMethodPattern:
parseNegatedNumber
parseParenthesizedExpression
parsePragma
parsePragmas
parsePrimitiveIdentifier
parsePrimitiveLiteral
parsePrimitiveObject
parseRewriteExpression:
parseRewriteExpression:onError:
parseRewriteMethod:
parseRewriteMethod:onError:
parseStatementList:into:
parseStatements:
parseUnaryMessage
parseUnaryMessageWith:
parseUnaryPattern
parseUnaryPragma
parseVariableNode
parserError:
Evaluate the block. If it returns raise an error
patchLiteralArrayToken
patchLiteralMessage
patchNegativeLiteral
Handle the special negative number case for binary message sends.
pragmaNodeClass
returnNodeClass
scanner:
scannerClass
sequenceNodeClass
step
variableNodeClass
RBPatternBlockNode
RBPatternBlockNode is the node in matching parse trees (it never occurs in normal Smalltalk code) that executes a block to determine if a match occurs. valueBlock takes two arguments, the first is the actual node that we are trying to match against, and second node is the dictionary that contains all the metavariable bindings that the matcher has made thus far.
Instance Variables:
valueBlock <BlockClosure> The block to execute when attempting to match this to a node.
acceptVisitor:
addArgumentWithNameBasedOn:to:
constructLookupNodeFor:in:
copyInContext:
createBlockFor:
createMatchingBlock
createReplacingBlock
lookupMatchFor:in:
match:inContext:
matchingBlock
replacePatternNodesIn:
replacingBlock
sentMessages
RBPatternBlockToken
RBPatternBlockToken is the first-class representation of the pattern block token.
isPatternBlock
RBPatternMessageNode
RBPatternMessageNode is a RBMessageNode that will match other message nodes without their selectors being equal.
Instance Variables:
isCascadeList <Boolean> are we matching a list of message nodes in a cascaded message
isList <Boolean> are we matching each keyword or matching all keywords together (e.g., `keyword1: would match a one argument method whereas `@keywords: would match 0 or more arguments)
copyInContext:
isList
isPatternNode
isSelectorList
match:inContext:
matchArgumentsAgainst:inContext:
matchSelectorAgainst:inContext:
matchingClass
receiver:selectorParts:arguments:
sentMessages
RBPatternMethodNode
RBPatternMethodNode is a RBMethodNode that will match other method nodes without their selectors being equal.
Instance Variables:
isList <Boolean> are we matching each keyword or matching all keywords together (e.g., `keyword1: would match a one argument method whereas `@keywords: would match 0 or more arguments)
copyInContext:
isPatternNode
isSelectorList
match:inContext:
matchArgumentsAgainst:inContext:
matchSelectorAgainst:inContext:
matchingClass
selectorParts:arguments:
RBPatternParser
RBPatternParser is a subclass of RBParser that allows the extended syntax that creates matching trees. These trees can be used by the ParseTreeMatcher to search and transform source code.
messageNodeClass
methodNodeClass
parseLiteralByteArrayObject
parsePatternBlock:
parsePrimitiveLiteral
parsePrimitiveObject
parseUnaryMessage
patchLiteralArrayToken
scannerClass
variableNodeClass
RBPatternScanner
RBPatternScanner is a subclass of RBScanner that allows the extended syntax of pattern matching trees.
scanToken
fast-n-ugly. Don't write stuff like this. Has been found to cause cancer in laboratory rats. Basically a
case statement. Didn't use Dictionary because lookup is pretty slow.
RBPatternVariableNode
RBPatternVariableNode is an AST node that is used to match several other types of nodes (literals, variables, value nodes, statement nodes, and sequences of statement nodes).
The different types of matches are determined by the name of the node. If the name contains a # character, then it will match a literal. If it contains, a . then it matches statements. If it contains no extra characters, then it matches only variables. These options are mutually exclusive.
The @ character can be combined with the name to match lists of items. If combined with the . character, then it will match a list of statement nodes (0 or more). If used without the . or # character, then it matches anything except for list of statements. Combining the @ with the # is not supported.
Adding another ` in the name will cause the search/replace to look for more matches inside the node that this node matched. This option should not be used for top level expressions since that would cause infinite recursion (e.g., searching only for "``@anything").
Instance Variables:
isAnything <Boolean> can we match any type of node
isList <Boolean> can we match a list of items (@)
isLiteral <Boolean> only match a literal node (#)
isStatement <Boolean> only match statements (.)
recurseInto <Boolean> search for more matches in the node we match (`)
copyInContext:
identifierToken:
initializePatternVariables
isAnything
isList
isLiteralNode
isPatternNode
isStatement
match:inContext:
matchLiteral:inContext:
matchStatement:inContext:
matchingClass
parent:
Fix the case where '``@node' should match a single node, not a sequence node.
recurseInto
RBPatternWrapperBlockNode
RBPatternWrapperBlockNode allows further matching using a block after a node has been matched by a pattern node.
Instance Variables:
wrappedNode <RBProgramNode> The original pattern node to match
acceptVisitor:
copyInContext:
I don't know what this would mean, so ignore it.
match:inContext:
precedence
wrappedNode
wrappedNode:
RBPragmaNode
A RBPragmaNode is xxxxxxxxx.
Instance Variables
arguments: <Object>
left: <Object>
right: <Object>
selector: <Object>
selectorParts: <Object>
arguments
- xxxxx
left
- xxxxx
right
- xxxxx
selector
- xxxxx
selectorParts
- xxxxx
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
arguments
arguments:
buildSelector
children
copyInContext:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
isBinary
isKeyword
isPragma
isPrimitive
isUnary
left
left:
match:inContext:
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
replaceNode:withNode:
right
right:
selector
selector:
selectorParts
selectorParts:
selectorParts:arguments:
start
stop
RBProgramNode
RBProgramNode is an abstract class that represents an abstract syntax tree node in a Smalltalk program.
Subclasses must implement the following messages:
accessing
start
stop
visitor
acceptVisitor:
The #start and #stop methods are used to find the source that corresponds to this node. "source copyFrom: self start to: self stop" should return the source for this node.
The #acceptVisitor: method is used by RBProgramNodeVisitors (the visitor pattern). This will also require updating all the RBProgramNodeVisitors so that they know of the new node.
Subclasses might also want to redefine match:inContext: and copyInContext: to do parse tree searching and replacing.
Subclasses that contain other nodes should override equalTo:withMapping: to compare nodes while ignoring renaming temporary variables, and children that returns a collection of our children nodes.
Instance Variables:
comments <Collection of: Interval> the intervals in the source that have comments for this node
parent <RBProgramNode> the node we're contained in
Shared Variables:
FormatterClass <Behavior> the formatter class that is used when we are formatted
acceptVisitor:
addReplacement:
allArgumentVariables
allChildren
allDefinedVariables
allTemporaryVariables
asReturn
Change the current node to a return node.
assigns:
bestNodeFor:
blockVariables
canMatchMethod:
cascadeListCharacter
children
clearReplacements
collect:
Hacked to fit collection protocols
comments
comments:
containedBy:
containsReturn
copyCommentsFrom:
Add all comments from aNode to us. If we already have the comment, then don't add it.
copyInContext:
copyList:inContext:
defines:
directlyUses:
do:
Hacked to fit collection protocols
equalTo:exceptForVariables:
equalTo:withMapping:
evaluatedFirst:
formattedCode
formatterClass
formatterClass:
hasMultipleReturns
hasProperty:
Test if the property aKey is present.
intersectsInterval:
isArray
isAssignment
isBlock
isCascade
isDirectlyUsed
This node is directly used as an argument, receiver, or part of an assignment.
isEvaluatedFirst
Return true if we are the first thing evaluated in this statement.
isImmediate
isImmediateNode
isLast:
isList
isLiteral
Answer whether the receiver has a literal text form recognized by the
compiler.
isLiteralArray
isLiteralNode
isMessage
isMethod
isPatternNode
isPragma
isReturn
isSequence
isUsed
Answer true if this node could be used as part of another expression. For example, you could use the
result of this node as a receiver of a message, an argument, the right part of an assignment, or the
return value of a block. This differs from isDirectlyUsed in that it is conservative since it also includes
return values of blocks.
isValue
isVariable
lastIsReturn
listCharacter
literalCharacter
mappingFor:
match:inContext:
matchList:against:inContext:
matchList:index:against:index:inContext:
methodComments
methodNode
newSource
nodesDo:
optimizedSelectors
parent
parent:
parents
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
precedence
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
propertyAt:
Answer the property value associated with aKey.
propertyAt:ifAbsent:
Answer the property value associated with aKey or, if aKey isn't found, answer the result of evaluating aBlock.
propertyAt:ifAbsentPut:
Answer the property associated with aKey or, if aKey isn't found store the result of evaluating aBlock as new value.
propertyAt:put:
Set the property at aKey to be anObject. If aKey is not found, create a new entry for aKey and set is value to anObject. Answer anObject.
recurseInto
recurseIntoCharacter
references:
removeDeadCode
removeProperty:
Remove the property with aKey. Answer the property or raise an error if aKey isn't found.
removeProperty:ifAbsent:
Remove the property with aKey. Answer the value or, if aKey isn't found, answer the result of evaluating aBlock.
replaceMethodSource:
We are being replaced with aNode -- if possible try to perform an in place edit of the source.
replaceNode:withNode:
replaceSourceFrom:
replaceSourceWith:
replaceWith:
selfMessages
sentMessages
settingsOn:
size
Hacked to fit collection protocols
source
sourceInterval
start
statementCharacter
statementComments
statementNode
Return your topmost node that is contained by a sequence node.
stop
superMessages
temporaryVariables
uses:
whichNodeIsContainedBy:
whoDefines:
RBProgramNodeVisitor
RBProgramNodeVisitor is an abstract visitor for the RBProgramNodes.
acceptArrayNode:
acceptAssignmentNode:
acceptBlockNode:
acceptCascadeNode:
acceptLiteralArrayNode:
acceptLiteralNode:
acceptMessageNode:
acceptMethodNode:
acceptPatternBlockNode:
acceptPatternWrapperBlockNode:
acceptPragmaNode:
acceptReturnNode:
acceptSequenceNode:
acceptVariableNode:
visitArgument:
Here to allow subclasses to detect arguments or temporaries.
visitArguments:
visitNode:
RBReadBeforeWrittenTester
RBReadBeforeWrittenTester is a visitor that identifies variables that may have been read before they are initialized.
Instance Variables:
checkNewTemps <Boolean> description of checkNewTemps
read <Collection> description of read
scopeStack <OrderedCollection> description of scopeStack
acceptAssignmentNode:
acceptBlockNode:
acceptMessageNode:
acceptSequenceNode:
acceptVariableNode:
checkNewTemps:
copyDictionary:
We could send aDictionary the copy message, but that doesn't copy the associations.
createScope
currentScope
executeTree:
initialize
Subclasses should redefine this method to perform initializations on instance creation
initializeVars:
isVariable:readBeforeWrittenIn:
isVariable:writtenBeforeReadIn:
processBlock:
processIfTrueIfFalse:
processStatementNode:
read
readBeforeWritten:in:
removeScope
variableRead:
variableWritten:
variablesReadBeforeWrittenIn:
RBReplaceRule
RBReplaceRule is the abstract superclass of all of the transforming rules. The rules change the source code by replacing the node that matches the rule. Subclasses implement different strategies for this replacement.
Subclasses must implement the following messages:
matching
foundMatchFor:
Instance Variables:
verificationBlock <BlockClosure> Is evaluated with the matching node. This allows for further verification of a match beyond simple tree matching.
canMatch:
foundMatchFor:
initialize
Subclasses should redefine this method to perform initializations on instance creation
replace:with:
RBReturnNode
RBReturnNode is an AST node that represents a return expression.
Instance Variables:
return <Integer> the position of the ^ character
value <RBValueNode> the value that is being returned
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
children
containsReturn
copyInContext:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
isReturn
match:inContext:
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
replaceNode:withNode:
return:value:
start
stop
value
value:
RBScanner
RBScanner is a stream that returns a sequence of token from the string that it is created on. The tokens know where they came from in the source code and which comments were attached to them.
Instance Variables:
buffer <PositionableStream> Accumulates the text for the current token.
characterType <ByteSymbol> The type of the next character. (e.g. #alphabetic, etc.)
classificationTable <Array of: Symbol> Mapping from Character values to their characterType.
comments <Collection of: Interval> Source intervals of scanned comments that must be attached to the next token.
currentCharacter <Character> The character currently being processed.
errorBlock <BlockClosure> The block to execute on lexical errors.
extendedLiterals <Boolean> True if IBM-type literals are allowed. In VW, this is false.
nameSpaceCharacter <Character> The character used to separate namespaces.
numberType <ByteSymbol> The method to perform: to scan a number.
separatorsInLiterals <Boolean> True if separators are allowed within literals.
stream <PositionableStream> Contains the text to be scanned.
tokenStart <Integer> The source position of the beginning of the current token
Class Instance Variables:
classificationTable <Array> the default classification table for all characters
Shared Variables:
PatternVariableCharacter <Character> the character that starts a pattern node
atEnd
classificationTable
classify:
contents
errorBlock
errorBlock:
errorPosition
flush
getComments
initialize
Subclasses should redefine this method to perform initializations on instance creation
initializeChars:to:
initializeClassificationTable
isReadable
isSelector:
isVariable:
isWritable
next
nextPut:
Provide an error notification that the receiver does not
implement this message.
on:
on:errorBlock:
patternVariableCharacter
previousStepPosition
scanAnySymbol
scanBinary:
scanIdentifierOrKeyword
scanKeyword
scanLiteral
scanLiteralArrayToken
scanLiteralCharacter
scanLiteralString
scanName
scanNumber
scanPatternVariable
scanSpecialCharacter
scanStringSymbol
scanSymbol
scanToken
fast-n-ugly. Don't write stuff like this. Has been found to cause cancer in laboratory rats. Basically a
case statement. Didn't use Dictionary because lookup is pretty slow.
scannerError:
Evaluate the block. If it returns raise an error
step
stripComment
stripSeparators
RBSearchRule
RBSearchRule is a parse tree rule that simply searches for matches to the rule. Every time a match is found, answerBlock is evaluated with the node that matches and the cureent answer. This two-argument approach allows a collection to be formed from all of the matches (Think inject:into:).
Instance Variables:
answerBlock <BlockClosure> Block to evaluate with the matching node and the current answer.
canMatch:
searchFor:thenDo:
searchForMethod:thenDo:
searchForTree:thenDo:
RBSequenceNode
RBSequenceNode is an AST node that represents a sequence of statements. Both RBBlockNodes and RBMethodNodes contain these.
Instance Variables:
leftBar <Integer | nil> the position of the left | in the temporaries definition
periods <SequenceableCollection of: Integer> the positions of all the periods that separate the statements
rightBar <Integer | nil> the position of the right | in the temporaries definition
statements <SequenceableCollection of: RBStatementNode> the statement nodes
temporaries <SequenceableCollection of: RBVariableNode> the temporaries defined
=
Can't send = to the temporaries and statements collection since they might change from arrays to OCs
acceptVisitor:
addNode:
addNode:before:
addNodeFirst:
addNodes:
addNodes:before:
addNodesFirst:
addReturn
addSelfReturn
addTemporariesNamed:
addTemporaryNamed:
allDefinedVariables
allTemporaryVariables
bestNodeFor:
children
copyInContext:
defines:
directlyUses:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
indexOfNode:
Try to find the node by first looking for ==, and then for =
isLast:
isSequence
lastIsReturn
leftBar:temporaries:rightBar:
match:inContext:
methodComments
periods
periods:
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
references:
removeDeadCode
removeNode:
removeTemporaryNamed:
replaceNode:withNode:
replaceNode:withNodes:
start
statements
statements:
stop
temporaries
temporaries:
temporaries:statements:
temporaryNames
temporaryVariables
uses:
whichNodeIsContainedBy:
RBShortAssignmentToken
A RBShortAssignmentToken is xxxxxxxxx.
Instance Variables
length
RBSmallDictionary
RBSmallDictionary is a special dictionary optimized for small collections. In addition to the normal dictionary protocol, it also supports an #empty message which "empties" the collection but may hang on to the original elements (so it could collect garbage). Without #empty we would either need to create a new dictionary or explicitly remove everything from the dictionary. Both of these take more time and #empty.
Instance Variables:
array <Array of: Object> array of keys (we don't use Associations for our key value pairs)
tally <Integer> the size of the dictionary
values <Array of: Object> array of our values
at:
Answer the value associated with aKey. Raise an exception, if no such key is defined.
at:ifAbsent:
Answer the value associated with aKey. Evaluate aBlock, if no such key is defined.
at:ifAbsentPut:
Answer the value associated with aKey. Evaluate aBlock, if no such key is defined and store the return value.
at:put:
Set the value of aKey to be aValue.
empty
errorKeyNotFound
findIndexFor:
grow
includesKey:
Answer whether the receiver has a key equal to aKey.
initialize:
isEmpty
keys
keysAndValuesDo:
keysDo:
new
new:
postCopy
self is a shallow copy, subclasses should copy fields as necessary to complete the full copy
privateAt:put:
removeKey:
Remove aKey from the receiver, raise an exception if the element is missing.
removeKey:ifAbsent:
Remove aKey from the receiver, evaluate aBlock if the element is missing.
size
Primitive. Answer the number of indexable variables in the receiver.
This value is the same as the largest legal subscript. Essential. See Object
documentation whatIsAPrimitive.
values
valuesDo:
RBSpecialCharacterToken
RBSpecialCharacterToken is the first class representation of special characters.
isSpecial
length
RBStringReplaceRule
RBStringReplaceRule replaces a matched tree with another tree (which may include metavariable from the matching tree). This is a very succint syntax for specifying most rewrites.
Instance Variables:
replaceTree <RBProgramNode> The tree to replace the matched tree with.
foundMatchFor:
methodReplaceString:
replaceString:
searchFor:replaceWith:
searchFor:replaceWith:when:
searchForMethod:replaceWith:
searchForMethod:replaceWith:when:
searchForTree:replaceWith:
searchForTree:replaceWith:when:
RBStringReplacement
RBStringReplacement represents replacing source in the original method with a different string. These are used when reformatting code after a parse tree change has been made. Depending on the change, it may be possible to minimally change the parse tree without needing to format it.
Instance Variables:
startPosition <Integer> the start position in the original source
stopPosition <Integer> the end position in the original source
string <String> replaces everything from the startPosition to the endPosition with this string
replaceFrom:to:with:
startPosition
startPosition:
stopPosition
stopPosition:
string
string:
RBToken
RBToken is the abstract superclass of all of the RB tokens. These tokens (unlike the standard parser's) remember where they came from in the original source code.
Subclasses must implement the following messages:
accessing
length
Instance Variables:
sourcePointer <Integer> The position in the original source code where this token began.
comments
comments:
isAssignment
isBinary
isIdentifier
isKeyword
isLiteral
Answer whether the receiver has a literal text form recognized by the
compiler.
isLiteralArrayToken
isLiteralToken
isPatternBlock
isPatternVariable
isSpecial
length
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
removePositions
start
start:
stop
RBValueNode
RBValueNode is an abstract class that represents a node that returns some value.
Subclasses must implement the following messages:
accessing
startWithoutParentheses
stopWithoutParentheses
testing
needsParenthesis
Instance Variables:
parentheses <SequenceableCollection of: Inteval> the positions of the parethesis around this node. We need a collection of intervals for stupid code such as "((3 + 4))" that has multiple parethesis around the same expression.
addParenthesis:
containedBy:
hasParentheses
isValue
needsParenthesis
parentheses
start
startWithoutParentheses
stop
stopWithoutParentheses
RBValueToken
RBValueToken is the abstract superclass of all tokens that have additional information attached. For example, the BinarySelector token holds onto the actual character (e.g. $+).
Instance Variables:
value <String> The value of this token
length
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
value
value:
value:start:
RBVariableNode
RBVariableNode is an AST node that represent a variable (global, inst var, temp, etc.).
Instance Variables:
token <RBValueToken> the token that contains our name and position
=
Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash.
acceptVisitor:
copyInContext:
equalTo:withMapping:
hash
Answer a SmallInteger whose value is related to the receiver's identity.
May be overridden, and should be overridden in any classes that define =
identifierToken:
isImmediateNode
isRead
isVariable
isWrite
name
Answer a name for the receiver. This is used generically in the title of certain inspectors, such as the referred-to inspector, and specificially by various subsystems. By default, we let the object just print itself out..
named:
needsParenthesis
precedence
references:
replaceSourceFrom:
replaceSourceWith:
startWithoutParentheses
stopWithoutParentheses