Skip to content

Commit 8a1987a

Browse files
authored
Merge pull request #19448 from d10c/d10c/ruby-printast-order-fix
Ruby printAst: fix order for synth children of real parents
2 parents f814849 + 96bdfbf commit 8a1987a

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: fix
3+
---
4+
### Bug Fixes
5+
6+
* The Ruby printAst.qll library now orders AST nodes slightly differently: child nodes that do not literally appear in the source code, but whose parent nodes do, are assigned a deterministic order based on a combination of source location and logical order within the parent. This fixes the non-deterministic ordering that sometimes occurred depending on evaluation order. The effect may also be visible in downstream uses of the printAst library, such as the AST view in the VSCode extension.

ruby/ql/lib/codeql/ruby/printAst.qll

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,22 @@ class PrintRegularAstNode extends PrintAstNode, TPrintRegularAstNode {
121121
}
122122

123123
private int getSynthAstNodeIndex() {
124-
this.parentIsSynthesized() and
125124
exists(AstNode parent |
126125
shouldPrintAstEdge(parent, _, astNode) and
127-
parent.isSynthesized() and
128126
synthChild(parent, result, astNode)
129127
)
130128
or
131-
not this.parentIsSynthesized() and
129+
not exists(AstNode parent |
130+
shouldPrintAstEdge(parent, _, astNode) and
131+
synthChild(parent, _, astNode)
132+
) and
132133
result = 0
133134
}
134135

136+
private int getSynthAstNodeIndexForSynthParent() {
137+
if this.parentIsSynthesized() then result = this.getSynthAstNodeIndex() else result = 0
138+
}
139+
135140
override int getOrder() {
136141
this =
137142
rank[result](PrintRegularAstNode p, Location l, File f |
@@ -140,8 +145,9 @@ class PrintRegularAstNode extends PrintAstNode, TPrintRegularAstNode {
140145
|
141146
p
142147
order by
143-
f.getBaseName(), f.getAbsolutePath(), l.getStartLine(), p.getSynthAstNodeIndex(),
144-
l.getStartColumn(), l.getEndLine(), l.getEndColumn()
148+
f.getBaseName(), f.getAbsolutePath(), l.getStartLine(),
149+
p.getSynthAstNodeIndexForSynthParent(), l.getStartColumn(), p.getSynthAstNodeIndex(),
150+
l.getEndLine(), l.getEndColumn()
145151
)
146152
}
147153

ruby/ql/test/library-tests/ast/Ast.expected

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,14 +3185,14 @@ params/params.rb:
31853185
# 106| getParameter: [HashSplatParameter] **kwargs
31863186
# 106| getDefiningAccess: [LocalVariableAccess] kwargs
31873187
# 107| getStmt: [SuperCall] super call to m
3188-
# 107| getArgument: [HashSplatExpr] ** ...
3189-
# 107| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] kwargs
3188+
# 107| getArgument: [LocalVariableAccess] y
3189+
# 107| getArgument: [SplatExpr] * ...
3190+
# 107| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] rest
31903191
# 107| getArgument: [Pair] Pair
31913192
# 107| getKey: [SymbolLiteral] k
31923193
# 107| getValue: [LocalVariableAccess] k
3193-
# 107| getArgument: [SplatExpr] * ...
3194-
# 107| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] rest
3195-
# 107| getArgument: [LocalVariableAccess] y
3194+
# 107| getArgument: [HashSplatExpr] ** ...
3195+
# 107| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] kwargs
31963196
# 111| getStmt: [MethodCall] call to m
31973197
# 111| getReceiver: [MethodCall] call to new
31983198
# 111| getReceiver: [ConstantReadAccess] Sub

0 commit comments

Comments
 (0)