RBParser 消息节点和目标接收者和参数?

RBParser message nodes and targeting the receiver and the argument?

尝试在 Pharo 中恢复我的一些旧代码和 运行。有些方法名称不同,但经过一番努力后,我设法找到了有效的等效方法。

我正在解析我的代码,我想检查接收者或任何参数是否为 aSymbol,以便将它们与受支持的替代项相匹配。我已经设法通过分析 RBMessageNode s

对选择器执行此操作
aNode selector == aSymbol ifTrue: [ aNode selector: replacementSymbol ].

如何对参数和接收者执行此操作?哪里有关于 RBParser 的综合指南?

通过直接操作

假设您正在寻找这样的案例:

aSymbol message: aSymbol message: aSymbol

对于接收者你应该做的:

(aNode isMessage and: [
aNode receiver isVariable and: [ 
aNode receiver name = 'aSymbol' ]]) ifTrue: [
   "do your job here" ]

这是另一个关于如何用 #newSymbol 替换 #aSymbol 参数的例子:

messageNode arguments: (messageNode arguments collect: [ :arg |
    (arg isLiteralNode and: [ arg value = #aSymbol ])
        ifFalse: [ arg ]
        ifTrue: [ | newNode |
            newNode := #aNewSymbol asLiteralNode.
            arg replaceSourceWith: newNode.
            newNode ] ]).

methodClass compile: ast newSource

replaceSourceWith: 确保只替换一个源,但是对于 newSource 实际上 return 一个新源,您还需要自己交换节点,这就是为什么我我正在收集参数,return 在需要时收集新参数。

您可以在 Word 菜单 > 帮助 > 帮助浏览器 > 重构框架中查看有关 RBParser 的帮助

你也可以通过检查

RBParser parseExpression: 'aSymbol message: aSymbol message: aSymbol'

并查看其内容

通过解析树变换

您可以使用模式代码来匹配和替换某些代码。例如,要更改 perform: 消息的符号参数,您可以这样做:

ast := yourMethod parseTree.

rewriter := RBParseTreeRewriter new 
        replace: '`receiver perform: #aSymbol'
        with: '`receiver perform: #newSelector'.

(rewriter executeTree: ast) ifTrue: [
    yourMethod class compile: ast newSource ]

您可以在帮助主题Word 菜单 > 帮助 > 帮助浏览器 > 重构框架 > 重构引擎 > RBPatternParser … 中了解更多关于模式匹配语法的信息。我认为 pharo 目录中的 MatchTool 可以极大地帮助您测试匹配表达式(它还有一个关于匹配语法的专门帮助主题),而 RewriteTool 可以帮助您预览您的代码将如何转换。