假设我正在遍历抽象语法树并遇到方法调用
[self.view backgroundColor] = UIColor.redColor;
如何判断我是否向self
或其他某个对象发送消息(可能是超类,某些属性,无关紧要)。
我找到了一种方法,根据其名称,将一个接收器返回给消息。
Expr * getInstanceReceiver ()
它返回实例消息的对象表达式(接收者),或者对于不是实例消息的消息返回null。
现在从这个Expr *我需要了解它是否是自我。 有没有人有任何想法如何?
答案 0 :(得分:0)
在文件中提供这个简单的程序" main.m":
--server.password "your-password-goes-here"
您可以使用以下命令打印出AST:
int puts(const char *);
__attribute__((objc_root_class))
@interface Robot
@property char *model;
@end
@implementation Robot
- (void)say:(char *)x {
puts(x);
}
- (void)hello {
[self say:"hello"];
}
- (char *)model {
return "49209192";
}
- (void)whoAmI {
puts(self.model);
}
- (void)setModel:(char *)model {
puts("setModel test");
}
- (void)setModelTest {
self.model = "123";
}
@end
int main() {
return 0;
}
然后看到"你好"方法AST如下所示:
clang -cc1 -ast-dump main.m
所以"自我"是"你好"的隐含的第一个参数。方法,它在方法调用中被解析为 DeclRefExpr - ObjCMessageExpr,但也包含在ImplicitCastExpr中。
对于属性访问,它看起来不同。 "模型"的AST部分;内部的财产访问" whoAmI"函数包含在 PseudoObjectExpr :
中| |-ObjCMethodDecl 0x7fe1c905bdb0 <line:21:1, line:23:1> line:21:1 - hello 'void'
| | |-ImplicitParamDecl 0x7fe1c90806e8 <<invalid sloc>> <invalid sloc> implicit used self 'Robot *'
| | |-ImplicitParamDecl 0x7fe1c9080748 <<invalid sloc>> <invalid sloc> implicit _cmd 'SEL':'SEL *'
| | `-CompoundStmt 0x7fe1c90808a0 <col:15, line:23:1>
| | `-ObjCMessageExpr 0x7fe1c9080868 <line:22:5, col:22> 'void' selector=say:
| | |-ImplicitCastExpr 0x7fe1c9080838 <col:6> 'Robot *' <LValueToRValue>
| | | `-DeclRefExpr 0x7fe1c90807a8 <col:6> 'Robot *' lvalue ImplicitParam 0x7fe1c90806e8 'self' 'Robot *'
| | `-ImplicitCastExpr 0x7fe1c9080850 <col:15> 'char *' <ArrayToPointerDecay>
| | `-StringLiteral 0x7fe1c9080808 <col:15> 'char [6]' lvalue "hello"
对于&#34; self&#34;你也有相同的 DeclRefExpr 。这里包含在ObjCMessageExpr(或ObjCPropertyRefExpr)中,但现在还有一层额外的包装--OpaqueValueExpr。
对于&#34; setModelTest&#34;中的属性设置器调用方法更加复杂:
`-PseudoObjectExpr 0x7fe844080640 <col:10, col:15> 'char *'
|-ObjCPropertyRefExpr 0x7fe8440805e0 <col:10, col:15> '<pseudo-object type>' lvalue objcproperty Kind=PropertyRef Property="model" Messaging=Getter
| `-OpaqueValueExpr 0x7fe8440805c0 <col:10> 'Robot *'
| `-ImplicitCastExpr 0x7fe844080578 <col:10> 'Robot *' <LValueToRValue>
| `-DeclRefExpr 0x7fe844080550 <col:10> 'Robot *' lvalue ImplicitParam 0x7fe844080468 'self' 'Robot *'
|-OpaqueValueExpr 0x7fe8440805c0 <col:10> 'Robot *'
| `-ImplicitCastExpr 0x7fe844080578 <col:10> 'Robot *' <LValueToRValue>
| `-DeclRefExpr 0x7fe844080550 <col:10> 'Robot *' lvalue ImplicitParam 0x7fe844080468 'self' 'Robot *'
`-ObjCMessageExpr 0x7fe844080610 <col:15> 'char *' selector=model
`-OpaqueValueExpr 0x7fe8440805c0 <col:10> 'Robot *'
`-ImplicitCastExpr 0x7fe844080578 <col:10> 'Robot *' <LValueToRValue>
`-DeclRefExpr 0x7fe844080550 <col:10> 'Robot *' lvalue ImplicitParam 0x7fe844080468 'self' 'Robot *'
最后一个ObjCMessageExpr的结构类似于getter case。
似乎如果你遍历树并找到所有引用名为self的ImplicitParam(ImplicitParamDecl)的 DeclRefExpr 节点,你就会发现&#34; self&#34的所有出现;