Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit ce0cc31

Browse files
committed
PrintAst: order parameter and result declarations
This adds support for generally overriding the default AstNode child ordering, and uses it to sort parameter and result declarations in the context of a FuncTypeExpr in left-to-right textual order.
1 parent 830f83f commit ce0cc31

4 files changed

Lines changed: 46 additions & 39 deletions

File tree

ql/src/semmle/go/AST.qll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,40 @@ class AstNode extends @node, Locatable {
3535
*/
3636
int getNumChild() { result = count(getAChild()) }
3737

38+
/**
39+
* Gets a child with the given index and of the given kind, if one exists.
40+
* Note that a given parent can have multiple children with the same index but differing kind.
41+
*/
42+
private AstNode getChildOfKind(string kind, int i) {
43+
kind = "expr" and result = this.(ExprParent).getChildExpr(i)
44+
or
45+
kind = "gomodexpr" and result = this.(GoModExprParent).getChildGoModExpr(i)
46+
or
47+
kind = "stmt" and result = this.(StmtParent).getChildStmt(i)
48+
or
49+
kind = "decl" and result = this.(DeclParent).getDecl(i)
50+
or
51+
kind = "spec" and result = this.(GenDecl).getSpec(i)
52+
or
53+
kind = "field" and result = this.(FieldParent).getField(i)
54+
or
55+
kind = "commentgroup" and result = this.(File).getCommentGroup(i)
56+
or
57+
kind = "comment" and result = this.(CommentGroup).getComment(i)
58+
}
59+
60+
/**
61+
* Get an AstNode child, ordered by child kind and then by index.
62+
*/
63+
AstNode getUniquelyNumberedChild(int index) {
64+
result =
65+
rank[index + 1](AstNode child, string kind, int i |
66+
child = getChildOfKind(kind, i)
67+
|
68+
child order by kind, i
69+
)
70+
}
71+
3872
/** Gets the parent node of this AST node, if any. */
3973
AstNode getParent() { this = result.getAChild() }
4074

ql/src/semmle/go/Expr.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,13 @@ class FuncTypeExpr extends @functypeexpr, TypeExpr, ScopeNode, FieldParent {
884884
override string toString() { result = "function type" }
885885

886886
override string getAPrimaryQlClass() { result = "FuncTypeExpr" }
887+
888+
/** Gets the `i`th child of this node, parameters first followed by results. */
889+
override AstNode getUniquelyNumberedChild(int i) {
890+
if i < getNumParameter()
891+
then result = getParameterDecl(i)
892+
else result = getResultDecl(i - getNumParameter())
893+
}
887894
}
888895

889896
/**

ql/src/semmle/go/PrintAst.qll

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -100,40 +100,6 @@ private string qlClass(AstNode el) {
100100
result = "[" + concat(el.getAPrimaryQlClass(), ", ") + "] "
101101
}
102102

103-
/**
104-
* Gets a child with the given index and of the given kind, if one exists.
105-
* Note that a given parent can have multiple children with the same index but differing kind.
106-
*/
107-
private AstNode getChildOfKind(AstNode parent, string kind, int i) {
108-
kind = "expr" and result = parent.(ExprParent).getChildExpr(i)
109-
or
110-
kind = "gomodexpr" and result = parent.(GoModExprParent).getChildGoModExpr(i)
111-
or
112-
kind = "stmt" and result = parent.(StmtParent).getChildStmt(i)
113-
or
114-
kind = "decl" and result = parent.(DeclParent).getDecl(i)
115-
or
116-
kind = "spec" and result = parent.(GenDecl).getSpec(i)
117-
or
118-
kind = "field" and result = parent.(FieldParent).getField(i)
119-
or
120-
kind = "commentgroup" and result = parent.(File).getCommentGroup(i)
121-
or
122-
kind = "comment" and result = parent.(CommentGroup).getComment(i)
123-
}
124-
125-
/**
126-
* Get an AstNode child, ordered by child kind and then by index
127-
*/
128-
private AstNode getUniquelyNumberedChild(AstNode node, int index) {
129-
result =
130-
rank[index + 1](AstNode child, string kind, int i |
131-
child = getChildOfKind(node, kind, i)
132-
|
133-
child order by kind, i
134-
)
135-
}
136-
137103
/**
138104
* A graph node representing a real AST node.
139105
*/
@@ -147,7 +113,7 @@ class BaseAstNode extends PrintAstNode, TAstNode {
147113
// nodes have multiple different types of child (e.g. a File has a
148114
// child expression, the package name, and child declarations whose
149115
// indices may clash), so we renumber them:
150-
result = TAstNode(getUniquelyNumberedChild(ast, childIndex))
116+
result = TAstNode(ast.getUniquelyNumberedChild(childIndex))
151117
}
152118

153119
override string toString() { result = qlClass(ast) + ast }

ql/test/library-tests/semmle/go/PrintAst/PrintAst.expected

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,14 @@ input.go:
262262
# 65| 0: [FunctionName, Ident] test7
263263
# 65| Type = func(int) int
264264
# 65| 1: [FuncTypeExpr] function type
265-
# 65| 0: [ResultVariableDecl] result variable declaration
266-
# 65| 0: [Ident, TypeName] int
267-
# 65| Type = int
268-
# 65| 1: [ParameterDecl] parameter declaration
265+
# 65| 0: [ParameterDecl] parameter declaration
269266
# 65| 0: [Ident, TypeName] int
270267
# 65| Type = int
271268
# 65| 1: [Ident, VariableName] x
272269
# 65| Type = int
270+
# 65| 1: [ResultVariableDecl] result variable declaration
271+
# 65| 0: [Ident, TypeName] int
272+
# 65| Type = int
273273
# 65| 2: [BlockStmt] block statement
274274
# 66| 0: [IfStmt] if statement
275275
# 66| 0: [GtrExpr] ...>...

0 commit comments

Comments
 (0)