Make CommentGroups AST-children of Files

Previously they were roots, with children hanging off them. Now they are children of Files, and both CommentGroups and Comments can be discovered using AstNode.getAChild.

The PrintAst pass is also adapted to account for their new position.
This commit is contained in:
Chris Smowton
2020-07-07 18:23:53 +01:00
parent 650cb5e626
commit 6bf3802b3f
14 changed files with 2214 additions and 998 deletions

View File

@@ -706,7 +706,9 @@ var HasLocationTable = NewTable("has_location",
// CommentGroupsTable is the table defining comment group entities
var CommentGroupsTable = NewTable("comment_groups",
EntityColumn(CommentGroupType, "id").Key(),
)
EntityColumn(FileType, "parent"),
IntColumn("idx"),
).KeySet("parent", "idx")
// CommentsTable is the table defining comment entities
var CommentsTable = NewTable("comments",

View File

@@ -532,8 +532,8 @@ func extractFileNode(tw *trap.Writer, nd *ast.File) {
extractDecl(tw, decl, lbl, i)
}
for _, cg := range nd.Comments {
extractCommentGroup(tw, cg)
for i, cg := range nd.Comments {
extractCommentGroup(tw, cg, lbl, i)
}
extractDoc(tw, nd.Doc, lbl)
@@ -548,9 +548,9 @@ func extractDoc(tw *trap.Writer, doc *ast.CommentGroup, elt trap.Label) {
}
// extractCommentGroup extracts information about a doc comment group
func extractCommentGroup(tw *trap.Writer, cg *ast.CommentGroup) {
func extractCommentGroup(tw *trap.Writer, cg *ast.CommentGroup, parent trap.Label, idx int) {
lbl := tw.Labeler.LocalID(cg)
dbscheme.CommentGroupsTable.Emit(tw, lbl)
dbscheme.CommentGroupsTable.Emit(tw, lbl, parent, idx)
extractNodeLocation(tw, cg, lbl)
for i, c := range cg.List {
extractComment(tw, c, lbl, i)

View File

@@ -144,7 +144,7 @@ func extractGoModComments(tw *trap.Writer, expr modfile.Expr, exprlbl trap.Label
// extract a pseudo `@commentgroup` for each expr that contains their associated comments
grouplbl := tw.Labeler.LocalID(GoModExprCommentWrapper{expr})
dbscheme.CommentGroupsTable.Emit(tw, grouplbl)
dbscheme.CommentGroupsTable.Emit(tw, grouplbl, tw.Labeler.FileLabel(), 0)
dbscheme.DocCommentsTable.Emit(tw, exprlbl, grouplbl)
var allComments []modfile.Comment

View File

@@ -49,7 +49,8 @@ containerparent(int parent: @container ref, unique int child: @container ref);
has_location(unique int locatable: @locatable ref, int location: @location ref);
comment_groups(unique int id: @comment_group);
#keyset[parent, idx]
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,9 @@ class AstNode extends @node, Locatable {
result = this.(StmtParent).getChildStmt(i) or
result = this.(DeclParent).getDecl(i) or
result = this.(GenDecl).getSpec(i) or
result = this.(FieldParent).getField(i)
result = this.(FieldParent).getField(i) or
result = this.(File).getCommentGroup(i) or
result = this.(CommentGroup).getComment(i)
}
/**

View File

@@ -51,6 +51,11 @@ class Comment extends @comment, AstNode {
* </pre>
*/
class CommentGroup extends @comment_group, AstNode {
/**
* Gets the file to which this comment group belongs.
*/
override File getParent() { this = result.getACommentGroup() }
/** Gets the `i`th comment in this group (0-based indexing). */
Comment getComment(int i) { comments(result, _, this, i, _) }

View File

@@ -208,5 +208,14 @@ class File extends Container, @file, Documentable, ExprParent, GoModExprParent,
/** Gets the URL of this file. */
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
/** Gets the `i`th child comment group. */
CommentGroup getCommentGroup(int i) { comment_groups(result, this, i) }
/** Gets a child comment group. */
CommentGroup getACommentGroup() { result = getCommentGroup(_) }
/** Gets the number of child comment groups of this file. */
int getNumCommentGroups() { result = count(getACommentGroup()) }
override string getAPrimaryQlClass() { result = "File" }
}

View File

@@ -115,7 +115,11 @@ private AstNode getChildOfKind(AstNode parent, string kind, int i) {
or
kind = "spec" and result = parent.(GenDecl).getSpec(i)
or
kind = "field" and fields(result, parent, i)
kind = "field" and result = parent.(FieldParent).getField(i)
or
kind = "commentgroup" and result = parent.(File).getCommentGroup(i)
or
kind = "comment" and result = parent.(CommentGroup).getComment(i)
}
/**

View File

@@ -1,9 +1,29 @@
input.go:
# 0| [File] library-tests/semmle/go/PrintAst/input.go
# 3| 0: [ImportDecl] import declaration
# 5| 0: [CommentGroup] comment group
# 5| 0: [SlashSlashComment] comment
# 7| 1: [CommentGroup] comment group
# 7| 0: [SlashSlashComment] comment
# 9| 2: [DocComment] comment group
# 9| 0: [SlashSlashComment] comment
# 17| 3: [CommentGroup] comment group
# 17| 0: [SlashSlashComment] comment
# 45| 4: [DocComment] comment group
# 45| 0: [SlashSlashComment] comment
# 64| 5: [DocComment] comment group
# 64| 0: [SlashSlashComment] comment
# 74| 6: [DocComment] comment group
# 74| 0: [SlashSlashComment] comment
# 111| 7: [DocComment] comment group
# 111| 0: [SlashSlashComment] comment
# 127| 8: [DocComment] comment group
# 127| 0: [SlashSlashComment] comment
# 132| 9: [DocComment] comment group
# 132| 0: [SlashSlashComment] comment
# 3| 10: [ImportDecl] import declaration
# 3| 0: [ImportSpec] import specifier
# 3| 0: [StringLit] "fmt"
# 10| 1: [FuncDecl] function declaration
# 10| 11: [FuncDecl] function declaration
# 10| 0: [FunctionName, Ident] test5
# 10| Type = func(bool)
# 10| 1: [FuncTypeExpr] function type
@@ -128,7 +148,7 @@ input.go:
# 40| 1: [BlockStmt] block statement
# 41| 0: [GotoStmt] goto statement
# 41| 0: [Ident, LabelName] outer
# 46| 2: [FuncDecl] function declaration
# 46| 12: [FuncDecl] function declaration
# 46| 0: [FunctionName, Ident] test6
# 46| Type = func(chan int, chan float32)
# 46| 1: [FuncTypeExpr] function type
@@ -238,7 +258,7 @@ input.go:
# 58| Value = [IntLit] 42
# 61| 3: [SelectStmt] select statement
# 61| 0: [BlockStmt] block statement
# 65| 3: [FuncDecl] function declaration
# 65| 13: [FuncDecl] function declaration
# 65| 0: [FunctionName, Ident] test7
# 65| Type = func(int) int
# 65| 1: [FuncTypeExpr] function type
@@ -303,7 +323,7 @@ input.go:
# 71| 0: [IntLit] 42
# 71| Type = int
# 71| Value = [IntLit] 42
# 75| 4: [FuncDecl] function declaration
# 75| 14: [FuncDecl] function declaration
# 75| 0: [FunctionName, Ident] test8
# 75| Type = func(int)
# 75| 1: [FuncTypeExpr] function type
@@ -423,7 +443,7 @@ input.go:
# 107| 0: [ConstantName, Ident] true
# 107| Type = bool
# 107| Value = [ConstantName, Ident] true
# 112| 5: [FuncDecl] function declaration
# 112| 15: [FuncDecl] function declaration
# 112| 0: [FunctionName, Ident] test9
# 112| Type = func(interface { })
# 112| 1: [FuncTypeExpr] function type
@@ -494,7 +514,7 @@ input.go:
# 123| 1: [ConstantName, Ident] false
# 123| Type = bool
# 123| Value = [ConstantName, Ident] false
# 128| 6: [FuncDecl] function declaration
# 128| 16: [FuncDecl] function declaration
# 128| 0: [FunctionName, Ident] test10
# 128| Type = func(func() )
# 128| 1: [FuncTypeExpr] function type
@@ -509,7 +529,7 @@ input.go:
# 129| Type = ()
# 129| 0: [Ident, VariableName] f
# 129| Type = func()
# 133| 7: [FuncDecl] function declaration
# 133| 17: [FuncDecl] function declaration
# 133| 0: [FunctionName, Ident] test11
# 133| Type = func([]int)
# 133| 1: [FuncTypeExpr] function type
@@ -571,24 +591,4 @@ input.go:
# 145| 0: [Ident, VariableName] xs
# 145| Type = []int
# 145| 1: [BlockStmt] block statement
# 1| 8: [Ident] main
# 9| [DocComment] comment group
# 45| [DocComment] comment group
# 64| [DocComment] comment group
# 74| [DocComment] comment group
# 111| [DocComment] comment group
# 127| [DocComment] comment group
# 132| [DocComment] comment group
# 5| [CommentGroup] comment group
# 5| [SlashSlashComment] comment
# 7| [CommentGroup] comment group
# 7| [SlashSlashComment] comment
# 9| [SlashSlashComment] comment
# 17| [CommentGroup] comment group
# 17| [SlashSlashComment] comment
# 45| [SlashSlashComment] comment
# 64| [SlashSlashComment] comment
# 74| [SlashSlashComment] comment
# 111| [SlashSlashComment] comment
# 127| [SlashSlashComment] comment
# 132| [SlashSlashComment] comment
# 1| 18: [Ident] main

View File

@@ -0,0 +1,431 @@
/** Auto-generated dbscheme; do not edit. */
/** Duplicate code **/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity;
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/** External data **/
externalData(
int id : @externalDataElement,
varchar(900) path : string ref,
int column: int ref,
varchar(900) value : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
int endLine: int ref, int endColumn: int ref);
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
files(unique int id: @file, string name: string ref, string simple: string ref, string ext: string ref, int fromSource: int ref);
folders(unique int id: @folder, string name: string ref, string simple: string ref);
containerparent(int parent: @container ref, unique int child: @container ref);
has_location(unique int locatable: @locatable ref, int location: @location ref);
#keyset[parent, idx]
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
#keyset[parent, idx]
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
#keyset[parent, idx]
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
#keyset[parent, idx]
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
#keyset[parent, idx]
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
scopes(unique int id: @scope, int kind: int ref);
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
objects(unique int id: @object, int kind: int ref, string name: string ref);
objectscopes(unique int object: @object ref, int scope: @scope ref);
objecttypes(unique int object: @object ref, int tp: @type ref);
methodreceivers(unique int method: @object ref, int receiver: @object ref);
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
methodhosts(int method: @object ref, int host: @namedtype ref);
defs(int ident: @ident ref, int object: @object ref);
uses(int ident: @ident ref, int object: @object ref);
types(unique int id: @type, int kind: int ref);
type_of(unique int expr: @expr ref, int tp: @type ref);
typename(unique int tp: @type ref, string name: string ref);
key_type(unique int map: @maptype ref, int tp: @type ref);
element_type(unique int container: @containertype ref, int tp: @type ref);
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
underlying_type(unique int named: @namedtype ref, int tp: @type ref);
#keyset[parent, index]
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
array_length(unique int tp: @arraytype ref, string len: string ref);
type_objects(unique int tp: @type ref, int object: @object ref);
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
#keyset[parent, idx]
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
#keyset[parent, idx]
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
#keyset[package, idx]
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
@container = @file | @folder;
@locatable = @node | @localscope;
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @scopenode
| @comment_group | @comment;
@documentable = @file | @field | @spec | @gendecl | @funcdecl | @modexpr;
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @spec;
@modexprparent = @file | @modexpr;
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
@stmtparent = @funcdef | @stmt | @decl;
@declparent = @file | @declstmt;
@funcdef = @funclit | @funcdecl;
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
@location = @location_default;
@sourceline = @locatable;
case @comment.kind of
0 = @slashslashcomment
| 1 = @slashstarcomment;
case @expr.kind of
0 = @badexpr
| 1 = @ident
| 2 = @ellipsis
| 3 = @intlit
| 4 = @floatlit
| 5 = @imaglit
| 6 = @charlit
| 7 = @stringlit
| 8 = @funclit
| 9 = @compositelit
| 10 = @parenexpr
| 11 = @selectorexpr
| 12 = @indexexpr
| 13 = @sliceexpr
| 14 = @typeassertexpr
| 15 = @callorconversionexpr
| 16 = @starexpr
| 17 = @keyvalueexpr
| 18 = @arraytypeexpr
| 19 = @structtypeexpr
| 20 = @functypeexpr
| 21 = @interfacetypeexpr
| 22 = @maptypeexpr
| 23 = @plusexpr
| 24 = @minusexpr
| 25 = @notexpr
| 26 = @complementexpr
| 27 = @derefexpr
| 28 = @addressexpr
| 29 = @arrowexpr
| 30 = @lorexpr
| 31 = @landexpr
| 32 = @eqlexpr
| 33 = @neqexpr
| 34 = @lssexpr
| 35 = @leqexpr
| 36 = @gtrexpr
| 37 = @geqexpr
| 38 = @addexpr
| 39 = @subexpr
| 40 = @orexpr
| 41 = @xorexpr
| 42 = @mulexpr
| 43 = @quoexpr
| 44 = @remexpr
| 45 = @shlexpr
| 46 = @shrexpr
| 47 = @andexpr
| 48 = @andnotexpr
| 49 = @sendchantypeexpr
| 50 = @recvchantypeexpr
| 51 = @sendrcvchantypeexpr;
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
@logicalunaryexpr = @notexpr;
@bitwiseunaryexpr = @complementexpr;
@arithmeticunaryexpr = @plusexpr | @minusexpr;
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
@logicalbinaryexpr = @lorexpr | @landexpr;
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
@shiftexpr = @shlexpr | @shrexpr;
@comparison = @equalitytest | @relationalcomparison;
@equalitytest = @eqlexpr | @neqexpr;
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
case @stmt.kind of
0 = @badstmt
| 1 = @declstmt
| 2 = @emptystmt
| 3 = @labeledstmt
| 4 = @exprstmt
| 5 = @sendstmt
| 6 = @incstmt
| 7 = @decstmt
| 8 = @gostmt
| 9 = @deferstmt
| 10 = @returnstmt
| 11 = @breakstmt
| 12 = @continuestmt
| 13 = @gotostmt
| 14 = @fallthroughstmt
| 15 = @blockstmt
| 16 = @ifstmt
| 17 = @caseclause
| 18 = @exprswitchstmt
| 19 = @typeswitchstmt
| 20 = @commclause
| 21 = @selectstmt
| 22 = @forstmt
| 23 = @rangestmt
| 24 = @assignstmt
| 25 = @definestmt
| 26 = @addassignstmt
| 27 = @subassignstmt
| 28 = @mulassignstmt
| 29 = @quoassignstmt
| 30 = @remassignstmt
| 31 = @andassignstmt
| 32 = @orassignstmt
| 33 = @xorassignstmt
| 34 = @shlassignstmt
| 35 = @shrassignstmt
| 36 = @andnotassignstmt;
@incdecstmt = @incstmt | @decstmt;
@assignment = @simpleassignstmt | @compoundassignstmt;
@simpleassignstmt = @assignstmt | @definestmt;
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
@switchstmt = @exprswitchstmt | @typeswitchstmt;
@loopstmt = @forstmt | @rangestmt;
case @decl.kind of
0 = @baddecl
| 1 = @importdecl
| 2 = @constdecl
| 3 = @typedecl
| 4 = @vardecl
| 5 = @funcdecl;
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
case @spec.kind of
0 = @importspec
| 1 = @valuespec
| 2 = @typespec;
case @object.kind of
0 = @pkgobject
| 1 = @decltypeobject
| 2 = @builtintypeobject
| 3 = @declconstobject
| 4 = @builtinconstobject
| 5 = @declvarobject
| 6 = @declfunctionobject
| 7 = @builtinfunctionobject
| 8 = @labelobject;
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
@typeobject = @decltypeobject | @builtintypeobject;
@valueobject = @constobject | @varobject | @functionobject;
@constobject = @declconstobject | @builtinconstobject;
@varobject = @declvarobject;
@functionobject = @declfunctionobject | @builtinfunctionobject;
case @scope.kind of
0 = @universescope
| 1 = @packagescope
| 2 = @localscope;
case @type.kind of
0 = @invalidtype
| 1 = @boolexprtype
| 2 = @inttype
| 3 = @int8type
| 4 = @int16type
| 5 = @int32type
| 6 = @int64type
| 7 = @uinttype
| 8 = @uint8type
| 9 = @uint16type
| 10 = @uint32type
| 11 = @uint64type
| 12 = @uintptrtype
| 13 = @float32type
| 14 = @float64type
| 15 = @complex64type
| 16 = @complex128type
| 17 = @stringexprtype
| 18 = @unsafepointertype
| 19 = @boolliteraltype
| 20 = @intliteraltype
| 21 = @runeliteraltype
| 22 = @floatliteraltype
| 23 = @complexliteraltype
| 24 = @stringliteraltype
| 25 = @nilliteraltype
| 26 = @arraytype
| 27 = @slicetype
| 28 = @structtype
| 29 = @pointertype
| 30 = @interfacetype
| 31 = @tupletype
| 32 = @signaturetype
| 33 = @maptype
| 34 = @sendchantype
| 35 = @recvchantype
| 36 = @sendrcvchantype
| 37 = @namedtype;
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
@booltype = @boolexprtype | @boolliteraltype;
@numerictype = @integertype | @floattype | @complextype;
@integertype = @signedintegertype | @unsignedintegertype;
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
@floattype = @float32type | @float64type | @floatliteraltype;
@complextype = @complex64type | @complex128type | @complexliteraltype;
@stringtype = @stringexprtype | @stringliteraltype;
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
| @stringliteraltype | @nilliteraltype;
@compositetype = @containertype | @structtype | @pointertype | @interfacetype | @tupletype | @signaturetype | @namedtype;
@containertype = @arraytype | @slicetype | @maptype | @chantype;
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
case @modexpr.kind of
0 = @modcommentblock
| 1 = @modline
| 2 = @modlineblock
| 3 = @modlparen
| 4 = @modrparen;
case @error.kind of
0 = @unknownerror
| 1 = @listerror
| 2 = @parseerror
| 3 = @typeerror;

View File

@@ -0,0 +1,430 @@
/** Auto-generated dbscheme; do not edit. */
/** Duplicate code **/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity;
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/** External data **/
externalData(
int id : @externalDataElement,
varchar(900) path : string ref,
int column: int ref,
varchar(900) value : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
int endLine: int ref, int endColumn: int ref);
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
files(unique int id: @file, string name: string ref, string simple: string ref, string ext: string ref, int fromSource: int ref);
folders(unique int id: @folder, string name: string ref, string simple: string ref);
containerparent(int parent: @container ref, unique int child: @container ref);
has_location(unique int locatable: @locatable ref, int location: @location ref);
comment_groups(unique int id: @comment_group);
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
#keyset[parent, idx]
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
#keyset[parent, idx]
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
#keyset[parent, idx]
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
#keyset[parent, idx]
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
scopes(unique int id: @scope, int kind: int ref);
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
objects(unique int id: @object, int kind: int ref, string name: string ref);
objectscopes(unique int object: @object ref, int scope: @scope ref);
objecttypes(unique int object: @object ref, int tp: @type ref);
methodreceivers(unique int method: @object ref, int receiver: @object ref);
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
methodhosts(int method: @object ref, int host: @namedtype ref);
defs(int ident: @ident ref, int object: @object ref);
uses(int ident: @ident ref, int object: @object ref);
types(unique int id: @type, int kind: int ref);
type_of(unique int expr: @expr ref, int tp: @type ref);
typename(unique int tp: @type ref, string name: string ref);
key_type(unique int map: @maptype ref, int tp: @type ref);
element_type(unique int container: @containertype ref, int tp: @type ref);
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
underlying_type(unique int named: @namedtype ref, int tp: @type ref);
#keyset[parent, index]
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
array_length(unique int tp: @arraytype ref, string len: string ref);
type_objects(unique int tp: @type ref, int object: @object ref);
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
#keyset[parent, idx]
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
#keyset[parent, idx]
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
#keyset[package, idx]
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
@container = @file | @folder;
@locatable = @node | @localscope;
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @scopenode
| @comment_group | @comment;
@documentable = @file | @field | @spec | @gendecl | @funcdecl | @modexpr;
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @spec;
@modexprparent = @file | @modexpr;
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
@stmtparent = @funcdef | @stmt | @decl;
@declparent = @file | @declstmt;
@funcdef = @funclit | @funcdecl;
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
@location = @location_default;
@sourceline = @locatable;
case @comment.kind of
0 = @slashslashcomment
| 1 = @slashstarcomment;
case @expr.kind of
0 = @badexpr
| 1 = @ident
| 2 = @ellipsis
| 3 = @intlit
| 4 = @floatlit
| 5 = @imaglit
| 6 = @charlit
| 7 = @stringlit
| 8 = @funclit
| 9 = @compositelit
| 10 = @parenexpr
| 11 = @selectorexpr
| 12 = @indexexpr
| 13 = @sliceexpr
| 14 = @typeassertexpr
| 15 = @callorconversionexpr
| 16 = @starexpr
| 17 = @keyvalueexpr
| 18 = @arraytypeexpr
| 19 = @structtypeexpr
| 20 = @functypeexpr
| 21 = @interfacetypeexpr
| 22 = @maptypeexpr
| 23 = @plusexpr
| 24 = @minusexpr
| 25 = @notexpr
| 26 = @complementexpr
| 27 = @derefexpr
| 28 = @addressexpr
| 29 = @arrowexpr
| 30 = @lorexpr
| 31 = @landexpr
| 32 = @eqlexpr
| 33 = @neqexpr
| 34 = @lssexpr
| 35 = @leqexpr
| 36 = @gtrexpr
| 37 = @geqexpr
| 38 = @addexpr
| 39 = @subexpr
| 40 = @orexpr
| 41 = @xorexpr
| 42 = @mulexpr
| 43 = @quoexpr
| 44 = @remexpr
| 45 = @shlexpr
| 46 = @shrexpr
| 47 = @andexpr
| 48 = @andnotexpr
| 49 = @sendchantypeexpr
| 50 = @recvchantypeexpr
| 51 = @sendrcvchantypeexpr;
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
@logicalunaryexpr = @notexpr;
@bitwiseunaryexpr = @complementexpr;
@arithmeticunaryexpr = @plusexpr | @minusexpr;
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
@logicalbinaryexpr = @lorexpr | @landexpr;
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
@shiftexpr = @shlexpr | @shrexpr;
@comparison = @equalitytest | @relationalcomparison;
@equalitytest = @eqlexpr | @neqexpr;
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
case @stmt.kind of
0 = @badstmt
| 1 = @declstmt
| 2 = @emptystmt
| 3 = @labeledstmt
| 4 = @exprstmt
| 5 = @sendstmt
| 6 = @incstmt
| 7 = @decstmt
| 8 = @gostmt
| 9 = @deferstmt
| 10 = @returnstmt
| 11 = @breakstmt
| 12 = @continuestmt
| 13 = @gotostmt
| 14 = @fallthroughstmt
| 15 = @blockstmt
| 16 = @ifstmt
| 17 = @caseclause
| 18 = @exprswitchstmt
| 19 = @typeswitchstmt
| 20 = @commclause
| 21 = @selectstmt
| 22 = @forstmt
| 23 = @rangestmt
| 24 = @assignstmt
| 25 = @definestmt
| 26 = @addassignstmt
| 27 = @subassignstmt
| 28 = @mulassignstmt
| 29 = @quoassignstmt
| 30 = @remassignstmt
| 31 = @andassignstmt
| 32 = @orassignstmt
| 33 = @xorassignstmt
| 34 = @shlassignstmt
| 35 = @shrassignstmt
| 36 = @andnotassignstmt;
@incdecstmt = @incstmt | @decstmt;
@assignment = @simpleassignstmt | @compoundassignstmt;
@simpleassignstmt = @assignstmt | @definestmt;
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
@switchstmt = @exprswitchstmt | @typeswitchstmt;
@loopstmt = @forstmt | @rangestmt;
case @decl.kind of
0 = @baddecl
| 1 = @importdecl
| 2 = @constdecl
| 3 = @typedecl
| 4 = @vardecl
| 5 = @funcdecl;
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
case @spec.kind of
0 = @importspec
| 1 = @valuespec
| 2 = @typespec;
case @object.kind of
0 = @pkgobject
| 1 = @decltypeobject
| 2 = @builtintypeobject
| 3 = @declconstobject
| 4 = @builtinconstobject
| 5 = @declvarobject
| 6 = @declfunctionobject
| 7 = @builtinfunctionobject
| 8 = @labelobject;
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
@typeobject = @decltypeobject | @builtintypeobject;
@valueobject = @constobject | @varobject | @functionobject;
@constobject = @declconstobject | @builtinconstobject;
@varobject = @declvarobject;
@functionobject = @declfunctionobject | @builtinfunctionobject;
case @scope.kind of
0 = @universescope
| 1 = @packagescope
| 2 = @localscope;
case @type.kind of
0 = @invalidtype
| 1 = @boolexprtype
| 2 = @inttype
| 3 = @int8type
| 4 = @int16type
| 5 = @int32type
| 6 = @int64type
| 7 = @uinttype
| 8 = @uint8type
| 9 = @uint16type
| 10 = @uint32type
| 11 = @uint64type
| 12 = @uintptrtype
| 13 = @float32type
| 14 = @float64type
| 15 = @complex64type
| 16 = @complex128type
| 17 = @stringexprtype
| 18 = @unsafepointertype
| 19 = @boolliteraltype
| 20 = @intliteraltype
| 21 = @runeliteraltype
| 22 = @floatliteraltype
| 23 = @complexliteraltype
| 24 = @stringliteraltype
| 25 = @nilliteraltype
| 26 = @arraytype
| 27 = @slicetype
| 28 = @structtype
| 29 = @pointertype
| 30 = @interfacetype
| 31 = @tupletype
| 32 = @signaturetype
| 33 = @maptype
| 34 = @sendchantype
| 35 = @recvchantype
| 36 = @sendrcvchantype
| 37 = @namedtype;
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
@booltype = @boolexprtype | @boolliteraltype;
@numerictype = @integertype | @floattype | @complextype;
@integertype = @signedintegertype | @unsignedintegertype;
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
@floattype = @float32type | @float64type | @floatliteraltype;
@complextype = @complex64type | @complex128type | @complexliteraltype;
@stringtype = @stringexprtype | @stringliteraltype;
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
| @stringliteraltype | @nilliteraltype;
@compositetype = @containertype | @structtype | @pointertype | @interfacetype | @tupletype | @signaturetype | @namedtype;
@containertype = @arraytype | @slicetype | @maptype | @chantype;
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
case @modexpr.kind of
0 = @modcommentblock
| 1 = @modline
| 2 = @modlineblock
| 3 = @modlparen
| 4 = @modrparen;
case @error.kind of
0 = @unknownerror
| 1 = @listerror
| 2 = @parseerror
| 3 = @typeerror;

View File

@@ -0,0 +1,3 @@
description: Give comment-group AST nodes a parent file
compatibility: partial
comment_groups.rel: run upgrade_comment_groups.qlo

View File

@@ -0,0 +1,44 @@
class File extends @file {
string toString() { result = "file" }
}
class Location extends @location {
/** Gets the file for this location. */
File getFile() { locations_default(this, result, _, _, _, _) }
int getStartLine() { locations_default(this, _, result, _, _, _) }
string toString() { result = "location" }
}
class Locatable extends @locatable {
Location getLocation() { has_location(this, result) }
string toString() { result = "locatable" }
}
class CommentGroup extends @comment_group, Locatable {
Comment getComment(int i) { comments(result, _, this, i, _) }
override string toString() { result = "comment group" }
}
class Comment extends @comment, Locatable {
override string toString() { result = "comment" }
}
Location getLocation(CommentGroup cg) {
result = cg.getLocation()
or
not exists(cg.getLocation()) and result = cg.getComment(0).getLocation()
}
from CommentGroup cg, File f, int idx
where
f = getLocation(cg).getFile() and
rank[idx + 1](CommentGroup rankedcg |
getLocation(rankedcg).getFile() = f
|
rankedcg order by getLocation(rankedcg).getStartLine()
) = cg
select cg, f, idx