CodeQL 文档

用于处理 Ruby 程序的抽象语法树类

CodeQL 拥有大量用于表示 Ruby 程序抽象语法树的类。

抽象语法树 (AST) 表示程序的语法结构。AST 上的节点表示语句和表达式等元素。

以下描述使用以下约定和占位符。

  • 一个 IDENTIFIER 表示任意标识符。
  • 一个 CNAME 表示类或模块名称。
  • 一个 FNAME 表示方法名称。
  • 一个 TERM 是分号或换行符,用于终止语句。
  • « » 括起来的元素被分组,可能以 ?*+ 为后缀,分别表示 0 或 1 次出现、0 或多次出现和 1 或多次出现。

语句类

此表列出了 Stmt 的子类,这些子类表示 Ruby 语句。

语句语法 CodeQL 类 超类 备注
alias FNAME FNAME AliasStmt Stmt  
BEGIN { StmtSequence } BeginBlock StmtSequence  
begin StmtSequence end BeginExpr StmtSequence  
break «Expr»? BreakStmt ReturningStmt  
; EmptyStmt Stmt  
END { StmtSequence } EndBlock StmtSequence  
next «Expr»? NextStmt ReturningStmt  
redo RedoStmt Stmt  
retry RetryStmt Stmt  
return «Expr»? ReturnStmt ReturningStmt  
undef «FNAME ,»+ UndefStmt Stmt  

调用

此表列出了 Call 的子类,以及一些作为调用参数出现的表达式。

表达式语法 CodeQL 类 超类 备注
Expr [ Expr ] ElementReference MethodCall  
MethodName «Expr ,»* MethodCall Call  
LhsExpr = Expr SetterMethodCall MethodCall  
super SuperCall MethodCall  
yield «Expr ,»* YieldCall Call  
& IDENTIFIER BlockArgument Expr 用作调用参数
... ForwardedArguments Expr 用作调用参数

常量访问

本节中的所有类都是 ConstantAccess 的子类。

表达式语法 CodeQL 类 超类 备注
CNAME ConstantReadAccess ConstantAccess  
CNAME = Expr ConstantAssignment ConstantWriteAccess  

控制表达式

本节中的所有类都是 ControlExpr 的子类。

表达式语法 CodeQL 类 超类 备注
if Expr then StmtSequence «elsif Expr then StmtSequence»* «else StmtSequence»? end IfExpr ConditionalExprControlExpr  
while Expr do StmtSequence end WhileExpr ConditionalLoop  
until Expr do StmtSequence end UntilExpr ConditionalLoop  
for LhsExpr in Expr do StmtSequence end ForExpr Loop  
Stmt while Expr WhileModifierExpr ConditionalLoop  
Stmt until Expr UntilModifierExpr ConditionalLoop  
Stmt if Expr IfModifierExpr ConditionalExprControlExpr  
Stmt unless Expr UnlessModifierExpr ConditionalExprControlExpr  
Expr ? Stmt : Stmt TernaryIfExpr ConditionalExprControlExpr  
case Expr when Expr then StmtSequence «when Expr then StmtSequence»* «else StmtSequence»? end CaseExpr ControlExpr  
case when Expr then StmtSequence «else StmtSequence»? end CaseExpr ControlExpr  
case Expr in «TERM CaseExpr»+ end f CaseExpr ControlExpr  

二元运算符

本节中所有类都是 BinaryOperation 的子类。

表达式语法 CodeQL 类 超类 备注
Expr + Expr AddExpr BinaryArithmeticOperation  
LhsExpr += Expr AssignAddExpr AssignArithmeticOperation  
LhsExpr &= Expr AssignBitwiseAndExpr AssignBitwiseOperation  
LhsExpr |= Expr AssignBitwiseOrExpr AssignBitwiseOperation  
LhsExpr ^= Expr AssignBitwiseXorExpr AssignBitwiseOperation  
LhsExpr /= Expr AssignDivExpr AssignArithmeticOperation  
LhsExpr **= Expr AssignExponentExpr AssignArithmeticOperation  
LhsExpr <<= Expr AssignLShiftExpr AssignBitwiseOperation  
LhsExpr &&= Expr AssignLogicalAndExpr BinaryLogicalOperation  
LhsExpr ||= Expr AssignLogicalOrExpr BinaryLogicalOperation  
LhsExpr %= Expr AssignModuloExpr AssignArithmeticOperation  
LhsExpr *= Expr AssignMulExpr AssignArithmeticOperation  
LhsExpr >>= Expr AssignRShiftExpr AssignBitwiseOperation  
LhsExpr -= Expr AssignSubExpr AssignArithmeticOperation  
Expr & Expr BitwiseAndExpr BinaryBitwiseOperation  
Expr | Expr BitwiseOrExpr BinaryBitwiseOperation  
Expr ^ Expr BitwiseXorExpr BinaryBitwiseOperation  
Expr === Expr CaseEqExpr EqualityOperation  
Expr / Expr DivExpr BinaryArithmeticOperation  
Expr === Expr EqExpr EqualityOperation  
Expr ^ Expr ExponentExpr BinaryArithmeticOperation  
Expr >= Expr GEExpr RelationalOperation  
Expr > Expr GTExpr RelationalOperation  
Expr <= Expr LEExpr RelationalOperation  
Expr << Expr LShiftExpr BinaryBitwiseOperation  
Expr < Expr LTExpr RelationalOperation  
Expr && Expr LogicalAndExpr BinaryLogicalOperation  
Expr and Expr LogicalAndExpr BinaryLogicalOperation  
Expr || Expr LogicalOrExpr BinaryLogicalOperation  
Expr or Expr LogicalOrExpr BinaryLogicalOperation  
Expr % Expr ModuloExpr BinaryArithmeticOperation  
Expr * Expr MulExpr BinaryArithmeticOperation  
Expr != Expr NEExpr RelationalOperation  
Expr !~ Expr NoRegExpMatchExpr BinaryOperation  
Expr >> Expr RShiftExpr BinaryBitwiseOperation  
Expr =~ Expr RegExpMatchExpr BinaryOperation  
Expr <=> Expr SpaceshipExpr BinaryOperation  
Expr - Expr SubExpr BinaryArithmeticOperation  
LhsExpr = Expr AssignExpr Assignment  

字面量

本节中所有类都是 Literal 的子类。

示例表达式语法 CodeQL 类 超类 备注
[1, 2] ArrayLiteral Literal  
true BooleanLiteral Literal  
?a CharacterLiteral Literal  
__ENCODING__ EncodingLiteral Literal  
__FILE__ FileLiteral Literal  
{ foo: 123, bar: 456 } HashLiteral Literal  
<<FOO
hello world
FOO
HereDoc StringlikeLiteral  
23 IntegerLiteral NumericLiteral  
3.1 FloatLiteral NumericLiteral  
3+2i ComplexLiteral NumericLiteral  
2/3r RationalLiteral NumericLiteral  
__LINE__ LineLiteral Literal  
nil NilLiteral Literal  
(1..10) RangeLiteral Literal  
/[a-z]+/ RegExpLiteral StringlikeLiteral  
"hello world" StringLiteral StringlikeLiteral  
`ls -l` SubshellLiteral StringlikeLiteral  
%x(/bin/sh foo.sh) SubshellLiteral StringlikeLiteral  
:foo SymbolLiteral StringlikeLiteral  

模块和 Ruby 类

本小节中的所有类都是 BodyStmtScope 的子类。

表达式语法 CodeQL 类 超类 备注
class CNAME «< Expr»? TERM StmtSequence TERM end 类声明 Namespace, ConstantWriteAccess  
module CNAME TERM StmtSequence TERM end 模块声明 Namespace, ConstantWriteAccess  
class << Expr TERM StmtSequence TERM end 单例类 模块基类  

可调用类

本小节中的所有类都是 Callable 的子类。

表达式语法 CodeQL 类 超类 备注
{ «| «Parameter ,»* |»? StmtSequence } 大括号块  
do «| «Parameter ,»* |»? BodyStmt end Do块 Block, BodyStmt  
-> ( «Parameter ,»* ) { StmtSequence } Lambda Callable, BodyStmt  
-> ( «Parameter ,»* ) do BodyStmt end Lambda Callable, BodyStmt  
def FNAME «Parameter ,»* TERM BodyStmt TERM end 方法 方法基类  
def self. FNAME «Parameter ,»* TERM BodyStmt TERM end 单例方法 方法基类  

参数类

本小节中的所有类都是 Parameter 的子类。

表达式语法 CodeQL 类 超类 备注
& IDENTIFIER 块参数 命名参数  
( «IDENTIFIER ,»+ ) 解构参数    
... 转发参数    
**nil 哈希 Splat Nil 参数   表示没有关键字参数或关键字模式
** IDENTIFIER 哈希 Splat 参数 命名参数  
IDENTIFIER : «Expr»? 关键字参数 命名参数  
IDENTIFIER = Expr 可选参数 命名参数  
IDENTIFIER 简单参数 命名参数  
* IDENTIFIER Splat 参数 命名参数  

模式类

本小节中的所有类都是 CasePattern 的子类。这些表达式通常出现在 case 使用模式匹配语法时。

表达式语法 CodeQL 类 超类 备注
CasePattern «| CasePattern»+ 备用模式 案例模式  
[ «CasePattern ,»* «* IDENTIFIER»? ] 数组模式 案例模式  
CasePattern => IDENTIFIER As 模式 案例模式  
[ * «IDENTIFIER»? (, CasePattern)* , * «IDENTIFIER»? ] 查找模式 案例模式  
{ «StringlikeLiteral : CasePattern ,»* «** IDENTIFIER»? } 哈希模式 案例模式  
( CasePattern ) 带括号的模式 案例模式  
^ Expr 引用模式 案例模式  

表达式类

本小节中的所有类都是 Expr 的子类。

表达式语法 CodeQL 类 超类 备注
«Expr ,»+ 参数列表 Expr 赋值的右侧或 returnbreaknext 语句
StmtSequence «RescueClause»? «else StmtSequence»? «ensure StmtSequence»? BodyStmt StmtSequence  
Expr «, Expr»+ 解构左值表达式 左值表达式  
Expr 左值表达式 Expr 出现在各种操作左侧的 Expr。可以采用多种形式。
Expr : Expr Expr 例如在哈希中或作为关键字参数
( StmtSequence ) 带括号的表达式 StmtSequence  
rescue StmtSequence 救援条款 Expr  
Stmt rescue Stmt 救援修饰符表达式 Expr  
StmtSequence TERM Stmt StmtSequence Expr 0 个或多个语句的序列,由分号或换行符分隔
StringLiteral StringLiteral 字符串连接 Expr 连续字符串文字的隐式连接

语法糖和反糖化

某些 Ruby 语言特性是常见操作的简写形式,也可以用其他更冗长的形式表达。这类语言特性通常被称为“语法糖”,使程序员更容易编写和阅读代码。这对程序员来说很棒。但是,对于源代码分析器来说,这会导致额外的工作,因为它们需要理解简写符号以及长形式。为了简化分析,CodeQL 会自动对 Ruby 代码进行“反糖化”,有效地将丰富的语法结构重写为使用更简单语法结构的等效代码。

例如,假设 x 是一个具有属性 foo 的对象,则赋值

x.foo = y

将反糖化为类似于以下代码

x.foo=(__synth_0 = y);
__synth_0;

换句话说,实际上是对 x 进行了一个 SetterMethodCall foo= 调用,其参数为 __synth_0 = y,然后读取 __synth_0 变量。

在 CodeQL 中,这是通过合成对应于此反糖化版本代码的 AstNode 实例来实现的。

请注意,原始的 AssignExpr 和反糖化的 SetterMethodCall 版本都可以在 CodeQL 查询中使用,通常您无需了解可能发生的任何反糖化。但是,如果代码库明确使用 x.foo=(y) SetterMethodCall 语法,则无法通过搜索 AssignExpr 的实例来找到此语法。

还存在其他合成的 AstNode 实例,有关详细信息,请参阅 isSynthesizedgetDesugared 谓词。

  • ©GitHub, Inc.
  • 条款
  • 隐私