如何使用Clang AST匹配器查找Setter和Getter方法?
使用Clang AST匹配器识别Getter和Setter方法
核心思路
基于cxxMethodDecl基础匹配器,通过嵌套子匹配器逐层检查函数体结构、语句类型、成员变量与参数的关联关系,精准筛选出符合要求的Getter和Setter。
Getter匹配器实现
匹配规则
- 属于类成员方法
- 函数体仅包含一条return语句
- return的是当前类的非静态成员变量
匹配表达式
cxxMethodDecl( // 函数体是仅含一条return语句的复合语句 hasBody(compoundStmt(hasExactly(1, returnStmt( // return的是当前对象的成员变量 hasReturnValue(memberExpr( isImplicitObjectArgument(cxxThisExpr()), refersToDeclaration(fieldDecl(isMemberOfClass(equalsNode(cast<CXXMethodDecl>(Node)->getParent())))) )) ))), // 返回类型非void returns(qualType(unless(isVoid()))) ).bind("getter")
关键匹配器解析
hasBody(compoundStmt(hasExactly(1, returnStmt(...)))):严格限制函数体只有一条有效语句(return)memberExpr(isImplicitObjectArgument(cxxThisExpr())):确保返回的成员属于当前实例(对应代码中的m_x或this->m_x)refersToDeclaration(fieldDecl(isMemberOfClass(...))):验证返回的成员变量归属于当前类returns(qualType(unless(isVoid()))):排除返回void的无效Getter
Setter匹配器实现
匹配规则
- 属于类成员方法
- 函数体仅包含一条赋值语句
- 赋值目标是当前类的非静态成员变量
- 赋值来源是方法的唯一参数
匹配表达式
cxxMethodDecl( // 函数体是仅含一条赋值语句的复合语句 hasBody(compoundStmt(hasExactly(1, binaryOperator( hasOperatorName("="), // 赋值左值是当前对象的成员变量 hasLHS(memberExpr( isImplicitObjectArgument(cxxThisExpr()), refersToDeclaration(fieldDecl(isMemberOfClass(equalsNode(cast<CXXMethodDecl>(Node)->getParent())))) )), // 赋值右值是方法的第一个(也是唯一)参数 hasRHS(declRefExpr( refersToDeclaration(parmVarDecl(equalsNode(cast<CXXMethodDecl>(Node)->getParamDecl(0))))) ) ))), // 返回类型为void returns(voidType()), // 仅包含一个参数 hasExactly(1, parmVarDecl()) ).bind("setter")
关键匹配器解析
hasExactly(1, parmVarDecl()):确保Setter只有一个入参binaryOperator(hasOperatorName("=")):精准匹配赋值操作hasLHS(memberExpr(...)):约束赋值的目标是当前类的成员变量hasRHS(declRefExpr(...)):确保赋值的来源是方法的唯一参数returns(voidType()):匹配常规Setter的void返回类型(若你的场景允许非void返回,可移除该约束)
扩展与优化
- 若需要匹配特定命名风格(如
getX/setX),可添加matchesName("^get[A-Z].*")或matchesName("^set[A-Z].*")到cxxMethodDecl的约束中 - 若函数体允许存在空语句(如额外的分号),可将
hasExactly(1, ...)调整为hasDescendant(...),并配合compoundStmt的语句数量过滤 - 对于继承自父类的成员变量,可结合
isDerivedFrom匹配器扩展isMemberOfClass的检查范围
内容的提问来源于stack exchange,提问作者Robert Ankeney
相关产品推荐
相关产品推荐

