зеркало из https://github.com/github/codeql-go.git
Merge branch 'github:main' into main
This commit is contained in:
Коммит
252b19063e
|
@ -7,10 +7,10 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.17
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.17
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Set up CodeQL CLI
|
||||
|
@ -59,10 +59,10 @@ jobs:
|
|||
name: Test MacOS
|
||||
runs-on: macOS-latest
|
||||
steps:
|
||||
- name: Set up Go 1.17
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.17
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Set up CodeQL CLI
|
||||
|
@ -99,10 +99,10 @@ jobs:
|
|||
name: Test Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- name: Set up Go 1.17
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.17
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Set up CodeQL CLI
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
class Expr_ extends @expr {
|
||||
string toString() { result = "Expr" }
|
||||
}
|
||||
|
||||
class ExprParent_ extends @exprparent {
|
||||
string toString() { result = "ExprParent" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Two new kinds have been inserted such that `@sliceexpr` which used to have
|
||||
* index 13 now has index 15. Another new kind has been inserted such that
|
||||
* `@plusexpr` which used to have index 23 now has index 26. Entries with
|
||||
* indices lower than 13 are unchanged.
|
||||
*/
|
||||
bindingset[new_index]
|
||||
int old_index(int new_index) {
|
||||
if new_index < 13
|
||||
then result = new_index
|
||||
else
|
||||
if new_index = [13, 14]
|
||||
then result = 0 // badexpr
|
||||
else
|
||||
if new_index < 23
|
||||
then result + (15 - 13) = new_index
|
||||
else
|
||||
if new_index = 23
|
||||
then result = 0 // badexpr
|
||||
else result + (26 - 23) = new_index
|
||||
}
|
||||
|
||||
// The schema for exprs is:
|
||||
//
|
||||
// exprs(unique int id: @expr,
|
||||
// int kind: int ref,
|
||||
// int parent: @exprparent ref,
|
||||
// int idx: int ref);
|
||||
from Expr_ expr, int new_kind, ExprParent_ parent, int idx, int old_kind
|
||||
where
|
||||
exprs(expr, new_kind, parent, idx) and
|
||||
old_kind = old_index(new_kind)
|
||||
select expr, old_kind, parent, idx
|
|
@ -0,0 +1,531 @@
|
|||
/** 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);
|
||||
|
||||
|
||||
/*
|
||||
* XML Files
|
||||
*/
|
||||
|
||||
xmlEncoding(
|
||||
unique int id: @file ref,
|
||||
string encoding: string ref
|
||||
);
|
||||
|
||||
xmlDTDs(
|
||||
unique int id: @xmldtd,
|
||||
string root: string ref,
|
||||
string publicId: string ref,
|
||||
string systemId: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlElements(
|
||||
unique int id: @xmlelement,
|
||||
string name: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlAttrs(
|
||||
unique int id: @xmlattribute,
|
||||
int elementid: @xmlelement ref,
|
||||
string name: string ref,
|
||||
string value: string ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlNs(
|
||||
int id: @xmlnamespace,
|
||||
string prefixName: string ref,
|
||||
string URI: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlHasNs(
|
||||
int elementId: @xmlnamespaceable ref,
|
||||
int nsId: @xmlnamespace ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlComments(
|
||||
unique int id: @xmlcomment,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlChars(
|
||||
unique int id: @xmlcharacters,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int isCDATA: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
@xmlparent = @file | @xmlelement;
|
||||
@xmlnamespaceable = @xmlelement | @xmlattribute;
|
||||
|
||||
xmllocations(
|
||||
int xmlElement: @xmllocatable ref,
|
||||
int location: @location_default ref
|
||||
);
|
||||
|
||||
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
|
||||
|
||||
compilations(unique int id: @compilation, string cwd: string ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
|
||||
|
||||
#keyset[id, num, kind]
|
||||
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
|
||||
|
||||
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
|
||||
|
||||
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
|
||||
|
||||
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
|
||||
string full_error_message: string ref, int location: @location 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);
|
||||
|
||||
folders(unique int id: @folder, string name: 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);
|
||||
|
||||
has_ellipsis(int id: @callorconversionexpr ref);
|
||||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
@container = @file | @folder;
|
||||
|
||||
@locatable = @xmllocatable | @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
|
||||
| 52 = @errorexpr;
|
||||
|
||||
@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 = @typedefspec
|
||||
| 3 = @aliasspec;
|
||||
|
||||
@typespec = @typedefspec | @aliasspec;
|
||||
|
||||
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;
|
||||
|
|
@ -0,0 +1,547 @@
|
|||
/** 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);
|
||||
|
||||
|
||||
/*
|
||||
* XML Files
|
||||
*/
|
||||
|
||||
xmlEncoding(
|
||||
unique int id: @file ref,
|
||||
string encoding: string ref
|
||||
);
|
||||
|
||||
xmlDTDs(
|
||||
unique int id: @xmldtd,
|
||||
string root: string ref,
|
||||
string publicId: string ref,
|
||||
string systemId: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlElements(
|
||||
unique int id: @xmlelement,
|
||||
string name: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlAttrs(
|
||||
unique int id: @xmlattribute,
|
||||
int elementid: @xmlelement ref,
|
||||
string name: string ref,
|
||||
string value: string ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlNs(
|
||||
int id: @xmlnamespace,
|
||||
string prefixName: string ref,
|
||||
string URI: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlHasNs(
|
||||
int elementId: @xmlnamespaceable ref,
|
||||
int nsId: @xmlnamespace ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlComments(
|
||||
unique int id: @xmlcomment,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlChars(
|
||||
unique int id: @xmlcharacters,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int isCDATA: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
@xmlparent = @file | @xmlelement;
|
||||
@xmlnamespaceable = @xmlelement | @xmlattribute;
|
||||
|
||||
xmllocations(
|
||||
int xmlElement: @xmllocatable ref,
|
||||
int location: @location_default ref
|
||||
);
|
||||
|
||||
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
|
||||
|
||||
compilations(unique int id: @compilation, string cwd: string ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
|
||||
|
||||
#keyset[id, num, kind]
|
||||
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
|
||||
|
||||
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
|
||||
|
||||
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
|
||||
|
||||
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
|
||||
string full_error_message: string ref, int location: @location 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);
|
||||
|
||||
folders(unique int id: @folder, string name: 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);
|
||||
|
||||
typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent 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);
|
||||
|
||||
has_ellipsis(int id: @callorconversionexpr ref);
|
||||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref,
|
||||
int parent: @typeparamparentobject ref, int idx: int ref);
|
||||
|
||||
@container = @file | @folder;
|
||||
|
||||
@locatable = @xmllocatable | @node | @localscope;
|
||||
|
||||
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
|
||||
| @scopenode | @comment_group | @comment;
|
||||
|
||||
@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr;
|
||||
|
||||
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec;
|
||||
|
||||
@modexprparent = @file | @modexpr;
|
||||
|
||||
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
|
||||
|
||||
@stmtparent = @funcdef | @stmt | @decl;
|
||||
|
||||
@declparent = @file | @declstmt;
|
||||
|
||||
@typeparamdeclparent = @funcdecl | @typespec;
|
||||
|
||||
@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 = @genericfunctioninstantiationexpr
|
||||
| 14 = @generictypeinstantiationexpr
|
||||
| 15 = @sliceexpr
|
||||
| 16 = @typeassertexpr
|
||||
| 17 = @callorconversionexpr
|
||||
| 18 = @starexpr
|
||||
| 19 = @keyvalueexpr
|
||||
| 20 = @arraytypeexpr
|
||||
| 21 = @structtypeexpr
|
||||
| 22 = @functypeexpr
|
||||
| 23 = @interfacetypeexpr
|
||||
| 24 = @maptypeexpr
|
||||
| 25 = @typesetliteralexpr
|
||||
| 26 = @plusexpr
|
||||
| 27 = @minusexpr
|
||||
| 28 = @notexpr
|
||||
| 29 = @complementexpr
|
||||
| 30 = @derefexpr
|
||||
| 31 = @addressexpr
|
||||
| 32 = @arrowexpr
|
||||
| 33 = @lorexpr
|
||||
| 34 = @landexpr
|
||||
| 35 = @eqlexpr
|
||||
| 36 = @neqexpr
|
||||
| 37 = @lssexpr
|
||||
| 38 = @leqexpr
|
||||
| 39 = @gtrexpr
|
||||
| 40 = @geqexpr
|
||||
| 41 = @addexpr
|
||||
| 42 = @subexpr
|
||||
| 43 = @orexpr
|
||||
| 44 = @xorexpr
|
||||
| 45 = @mulexpr
|
||||
| 46 = @quoexpr
|
||||
| 47 = @remexpr
|
||||
| 48 = @shlexpr
|
||||
| 49 = @shrexpr
|
||||
| 50 = @andexpr
|
||||
| 51 = @andnotexpr
|
||||
| 52 = @sendchantypeexpr
|
||||
| 53 = @recvchantypeexpr
|
||||
| 54 = @sendrcvchantypeexpr
|
||||
| 55 = @errorexpr;
|
||||
|
||||
@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 = @typedefspec
|
||||
| 3 = @aliasspec;
|
||||
|
||||
@typespec = @typedefspec | @aliasspec;
|
||||
|
||||
case @object.kind of
|
||||
0 = @pkgobject
|
||||
| 1 = @decltypeobject
|
||||
| 2 = @builtintypeobject
|
||||
| 3 = @declconstobject
|
||||
| 4 = @builtinconstobject
|
||||
| 5 = @declvarobject
|
||||
| 6 = @declfunctionobject
|
||||
| 7 = @builtinfunctionobject
|
||||
| 8 = @labelobject;
|
||||
|
||||
@typeparamparentobject = @decltypeobject | @declfunctionobject;
|
||||
|
||||
@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 = @typeparamtype
|
||||
| 27 = @arraytype
|
||||
| 28 = @slicetype
|
||||
| 29 = @structtype
|
||||
| 30 = @pointertype
|
||||
| 31 = @interfacetype
|
||||
| 32 = @tupletype
|
||||
| 33 = @signaturetype
|
||||
| 34 = @maptype
|
||||
| 35 = @sendchantype
|
||||
| 36 = @recvchantype
|
||||
| 37 = @sendrcvchantype
|
||||
| 38 = @namedtype
|
||||
| 39 = @typesetliteraltype;
|
||||
|
||||
@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 = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype
|
||||
| @signaturetype | @namedtype | @typesetliteraltype;
|
||||
|
||||
@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;
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
class Type_ extends @type {
|
||||
string toString() { result = "Type" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A new kind has been inserted such that `@arraytype` which used to have index
|
||||
* 26 now has index 27. Another new kind has been inserted at 39, which is the
|
||||
* end of the list. Entries with lower indices are unchanged.
|
||||
*/
|
||||
bindingset[new_index]
|
||||
int old_index(int new_index) {
|
||||
if new_index < 26
|
||||
then result = new_index
|
||||
else
|
||||
if new_index = 26
|
||||
then result = 0 // invalidtype
|
||||
else
|
||||
if new_index < 39
|
||||
then result + (27 - 26) = new_index
|
||||
else result = 0 // invalidtype
|
||||
}
|
||||
|
||||
// The schema for types is:
|
||||
//
|
||||
// types(unique int id: @type,
|
||||
// int kind: int ref);
|
||||
from Type_ type, int new_kind, int old_kind
|
||||
where
|
||||
types(type, new_kind) and
|
||||
old_kind = old_index(new_kind)
|
||||
select type, old_kind
|
|
@ -0,0 +1,6 @@
|
|||
description: Add generic instantiation expressions and type parameter types
|
||||
compatibility: full
|
||||
exprs.rel: run exprs.qlo
|
||||
types.rel: run types.qlo
|
||||
typeparamdecls.rel: delete
|
||||
typeparam.rel: delete
|
|
@ -0,0 +1,531 @@
|
|||
/** 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);
|
||||
|
||||
|
||||
/*
|
||||
* XML Files
|
||||
*/
|
||||
|
||||
xmlEncoding(
|
||||
unique int id: @file ref,
|
||||
string encoding: string ref
|
||||
);
|
||||
|
||||
xmlDTDs(
|
||||
unique int id: @xmldtd,
|
||||
string root: string ref,
|
||||
string publicId: string ref,
|
||||
string systemId: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlElements(
|
||||
unique int id: @xmlelement,
|
||||
string name: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlAttrs(
|
||||
unique int id: @xmlattribute,
|
||||
int elementid: @xmlelement ref,
|
||||
string name: string ref,
|
||||
string value: string ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlNs(
|
||||
int id: @xmlnamespace,
|
||||
string prefixName: string ref,
|
||||
string URI: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlHasNs(
|
||||
int elementId: @xmlnamespaceable ref,
|
||||
int nsId: @xmlnamespace ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlComments(
|
||||
unique int id: @xmlcomment,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlChars(
|
||||
unique int id: @xmlcharacters,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int isCDATA: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
@xmlparent = @file | @xmlelement;
|
||||
@xmlnamespaceable = @xmlelement | @xmlattribute;
|
||||
|
||||
xmllocations(
|
||||
int xmlElement: @xmllocatable ref,
|
||||
int location: @location_default ref
|
||||
);
|
||||
|
||||
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
|
||||
|
||||
compilations(unique int id: @compilation, string cwd: string ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
|
||||
|
||||
#keyset[id, num, kind]
|
||||
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
|
||||
|
||||
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
|
||||
|
||||
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
|
||||
|
||||
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
|
||||
string full_error_message: string ref, int location: @location 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);
|
||||
|
||||
folders(unique int id: @folder, string name: 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);
|
||||
|
||||
has_ellipsis(int id: @callorconversionexpr ref);
|
||||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
@container = @file | @folder;
|
||||
|
||||
@locatable = @xmllocatable | @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
|
||||
| 52 = @errorexpr;
|
||||
|
||||
@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 = @typedefspec
|
||||
| 3 = @aliasspec;
|
||||
|
||||
@typespec = @typedefspec | @aliasspec;
|
||||
|
||||
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;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
name: codeql/go-downgrades
|
||||
groups: go
|
||||
downgrades: .
|
||||
library: true
|
|
@ -4,6 +4,7 @@ import (
|
|||
"go/ast"
|
||||
"go/token"
|
||||
gotypes "go/types"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
|
@ -274,6 +275,9 @@ var StmtParentType = NewUnionType("@stmtparent", NodeType)
|
|||
// DeclParentType is the type of AST nodes that can have declarations as children
|
||||
var DeclParentType = NewUnionType("@declparent", NodeType)
|
||||
|
||||
// TypeParamDeclParentType is the type of AST nodes that can have type parameter declarations as children
|
||||
var TypeParamDeclParentType = NewUnionType("@typeparamdeclparent", NodeType)
|
||||
|
||||
// FuncDefType is the type of AST nodes that define functions, that is, function
|
||||
// declarations and function literals
|
||||
var FuncDefType = NewUnionType("@funcdef", StmtParentType, ExprParentType)
|
||||
|
@ -308,6 +312,9 @@ var StmtType = NewPrimaryKeyType("@stmt", ExprParentType, StmtParentType)
|
|||
// DeclType is the type of declaration AST nodes
|
||||
var DeclType = NewPrimaryKeyType("@decl", ExprParentType, StmtParentType, FieldParentType)
|
||||
|
||||
// TypeParamDeclType is the type of type parameter declaration AST nodes
|
||||
var TypeParamDeclType = NewPrimaryKeyType("@typeparamdecl", DocumentableType, ExprParentType)
|
||||
|
||||
// SpecType is the type of spec AST nodes
|
||||
var SpecType = NewPrimaryKeyType("@spec", ExprParentType, DocumentableType)
|
||||
|
||||
|
@ -371,9 +378,23 @@ var ParenExpr = ExprKind.NewBranch("@parenexpr")
|
|||
// SelectorExpr is the type of selector expression AST nodes
|
||||
var SelectorExpr = ExprKind.NewBranch("@selectorexpr")
|
||||
|
||||
// IndexExpr is the type of index expression AST nodes
|
||||
// IndexExpr is the type of AST nodes for index expressions and generic type
|
||||
// instantiation expressions with one type argument. Note that syntactically
|
||||
// unambiguous generic instantiations will be extracted as
|
||||
// `GenericTypeInstantiationExpr`.
|
||||
var IndexExpr = ExprKind.NewBranch("@indexexpr")
|
||||
|
||||
// GenericFunctionInstantiationExpr is the type of AST nodes that represent an instantiation
|
||||
// of a generic type. These correspond to some index expression AST nodes and all index
|
||||
// list expression AST nodes.
|
||||
var GenericFunctionInstantiationExpr = ExprKind.NewBranch("@genericfunctioninstantiationexpr")
|
||||
|
||||
// GenericTypeInstantiationExpr is the type of AST nodes that represent an instantiation
|
||||
// of a generic type. These correspond to some index expression AST nodes and all index
|
||||
// list expression AST nodes. Note some syntactically ambiguous instantations are
|
||||
// extracted as an `IndexExpr` to be disambiguated in QL later.
|
||||
var GenericTypeInstantiationExpr = ExprKind.NewBranch("@generictypeinstantiationexpr")
|
||||
|
||||
// SliceExpr is the type of slice expression AST nodes
|
||||
var SliceExpr = ExprKind.NewBranch("@sliceexpr")
|
||||
|
||||
|
@ -453,6 +474,9 @@ var InterfaceTypeExpr = ExprKind.NewBranch("@interfacetypeexpr", FieldParentType
|
|||
// MapTypeExpr is the type of map type AST nodes
|
||||
var MapTypeExpr = ExprKind.NewBranch("@maptypeexpr")
|
||||
|
||||
// TypeSetLiteralExpr is the type of type set literal type AST nodes
|
||||
var TypeSetLiteralExpr = ExprKind.NewBranch("@typesetliteralexpr")
|
||||
|
||||
// ChanTypeExpr is the type of channel type AST nodes
|
||||
var ChanTypeExpr = NewUnionType("@chantypeexpr")
|
||||
|
||||
|
@ -635,7 +659,7 @@ var TypeDeclType = DeclKind.NewBranch("@typedecl", GenDeclType)
|
|||
var VarDeclType = DeclKind.NewBranch("@vardecl", GenDeclType)
|
||||
|
||||
// FuncDeclType is the type of function declaration AST nodes
|
||||
var FuncDeclType = DeclKind.NewBranch("@funcdecl", DocumentableType, FuncDefType)
|
||||
var FuncDeclType = DeclKind.NewBranch("@funcdecl", DocumentableType, FuncDefType, TypeParamDeclParentType)
|
||||
|
||||
// SpecKind is a case type for distinguishing different kinds of declaration specification nodes
|
||||
var SpecKind = NewCaseType(SpecType, "kind")
|
||||
|
@ -647,7 +671,7 @@ var ImportSpecType = SpecKind.NewBranch("@importspec")
|
|||
var ValueSpecType = SpecKind.NewBranch("@valuespec")
|
||||
|
||||
// TypeSpecType is the type of type declaration specification nodes
|
||||
var TypeSpecType = NewUnionType("@typespec")
|
||||
var TypeSpecType = NewUnionType("@typespec", TypeParamDeclParentType)
|
||||
|
||||
// TypeDefSpecType is the type of type declaration specification nodes corresponding to type definitions
|
||||
var TypeDefSpecType = SpecKind.NewBranch("@typedefspec", TypeSpecType)
|
||||
|
@ -661,6 +685,9 @@ var ObjectType = NewPrimaryKeyType("@object")
|
|||
// ObjectKind is a case type for distinguishing different kinds of built-in and declared objects
|
||||
var ObjectKind = NewCaseType(ObjectType, "kind")
|
||||
|
||||
// TypeParamParentObjectType is the type of objects that can have type parameters as children
|
||||
var TypeParamParentObjectType = NewUnionType("@typeparamparentobject")
|
||||
|
||||
// DeclObjectType is the type of declared objects
|
||||
var DeclObjectType = NewUnionType("@declobject")
|
||||
|
||||
|
@ -674,7 +701,7 @@ var PkgObjectType = ObjectKind.NewBranch("@pkgobject")
|
|||
var TypeObjectType = NewUnionType("@typeobject")
|
||||
|
||||
// DeclTypeObjectType is the type of declared named types
|
||||
var DeclTypeObjectType = ObjectKind.NewBranch("@decltypeobject", TypeObjectType, DeclObjectType)
|
||||
var DeclTypeObjectType = ObjectKind.NewBranch("@decltypeobject", TypeObjectType, DeclObjectType, TypeParamParentObjectType)
|
||||
|
||||
// BuiltinTypeObjectType is the type of built-in named types
|
||||
var BuiltinTypeObjectType = ObjectKind.NewBranch("@builtintypeobject", TypeObjectType, BuiltinObjectType)
|
||||
|
@ -701,7 +728,7 @@ var DeclVarObjectType = ObjectKind.NewBranch("@declvarobject", VarObjectType, De
|
|||
var FunctionObjectType = NewUnionType("@functionobject", ValueObjectType)
|
||||
|
||||
// DeclFuncObjectType is the type of declared functions, including (abstract and concrete) methods
|
||||
var DeclFuncObjectType = ObjectKind.NewBranch("@declfunctionobject", FunctionObjectType, DeclObjectType)
|
||||
var DeclFuncObjectType = ObjectKind.NewBranch("@declfunctionobject", FunctionObjectType, DeclObjectType, TypeParamParentObjectType)
|
||||
|
||||
// BuiltinFuncObjectType is the type of built-in functions
|
||||
var BuiltinFuncObjectType = ObjectKind.NewBranch("@builtinfunctionobject", FunctionObjectType, BuiltinObjectType)
|
||||
|
@ -790,6 +817,9 @@ var BasicTypes = map[gotypes.BasicKind]*BranchType{
|
|||
// CompositeType is the type of all composite (that is, non-basic) types
|
||||
var CompositeType = NewUnionType("@compositetype")
|
||||
|
||||
// TypeParamType is the type of type parameter types
|
||||
var TypeParamType = TypeKind.NewBranch("@typeparamtype", CompositeType)
|
||||
|
||||
// ElementContainerType is the type of types that have elements, such as arrays
|
||||
// and channels
|
||||
var ElementContainerType = NewUnionType("@containertype", CompositeType)
|
||||
|
@ -831,6 +861,9 @@ var ChanTypes = map[gotypes.ChanDir]*BranchType{
|
|||
// NamedType is the type of named types
|
||||
var NamedType = TypeKind.NewBranch("@namedtype", CompositeType)
|
||||
|
||||
// TypeSetLiteral is the type of type set literals
|
||||
var TypeSetLiteral = TypeKind.NewBranch("@typesetliteraltype", CompositeType)
|
||||
|
||||
// PackageType is the type of packages
|
||||
var PackageType = NewPrimaryKeyType("@package")
|
||||
|
||||
|
@ -970,6 +1003,13 @@ var FieldsTable = NewTable("fields",
|
|||
IntColumn("idx"),
|
||||
)
|
||||
|
||||
// TypeParamDeclsTable is the table defining type param declaration AST nodes
|
||||
var TypeParamDeclsTable = NewTable("typeparamdecls",
|
||||
EntityColumn(TypeParamDeclType, "id").Key(),
|
||||
EntityColumn(TypeParamDeclParentType, "parent"),
|
||||
IntColumn("idx"),
|
||||
)
|
||||
|
||||
// StmtsTable is the table defining statement AST nodes
|
||||
var StmtsTable = NewTable("stmts",
|
||||
EntityColumn(StmtType, "id").Key(),
|
||||
|
@ -1171,3 +1211,12 @@ var HasEllipsisTable = NewTable("has_ellipsis",
|
|||
var VariadicTable = NewTable("variadic",
|
||||
EntityColumn(SignatureType, "id"),
|
||||
)
|
||||
|
||||
// TypeParamTable is the table describing type parameter types
|
||||
var TypeParamTable = NewTable("typeparam",
|
||||
EntityColumn(TypeParamType, "tp").Unique(),
|
||||
StringColumn("name"),
|
||||
EntityColumn(CompositeType, "bound"),
|
||||
EntityColumn(TypeParamParentObjectType, "parent"),
|
||||
IntColumn("idx"),
|
||||
).KeySet("parent", "idx")
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
)
|
||||
|
||||
var MaxGoRoutines int
|
||||
var typeParamParent map[*types.TypeParam]types.Object = make(map[*types.TypeParam]types.Object)
|
||||
|
||||
func init() {
|
||||
// this sets the number of threads that the Go runtime will spawn; this is separate
|
||||
|
@ -109,9 +110,7 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
|||
// root directories of packages that we want to extract
|
||||
wantedRoots := make(map[string]bool)
|
||||
|
||||
// recursively visit all packages in depth-first order;
|
||||
// on the way down, associate each package scope with its corresponding package,
|
||||
// and on the way up extract the package's scope
|
||||
// Do a post-order traversal and extract the package scope of each package
|
||||
packages.Visit(pkgs, func(pkg *packages.Package) bool {
|
||||
return true
|
||||
}, func(pkg *packages.Package) {
|
||||
|
@ -138,7 +137,7 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
|||
defer tw.Close()
|
||||
|
||||
scope := extractPackageScope(tw, pkg)
|
||||
tw.ForEachObject(extractObjectType)
|
||||
extractObjectTypes(tw)
|
||||
lbl := tw.Labeler.GlobalID(util.EscapeTrapSpecialChars(pkg.PkgPath) + ";pkg")
|
||||
dbscheme.PackagesTable.Emit(tw, lbl, pkg.Name, pkg.PkgPath, scope)
|
||||
|
||||
|
@ -361,8 +360,23 @@ func extractUniverseScope() {
|
|||
func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label) {
|
||||
for _, name := range scope.Names() {
|
||||
obj := scope.Lookup(name)
|
||||
lbl, exists := tw.Labeler.ScopedObjectID(obj, extractType(tw, obj.Type()))
|
||||
lbl, exists := tw.Labeler.ScopedObjectID(obj, func() trap.Label { return extractType(tw, obj.Type()) })
|
||||
if !exists {
|
||||
// Populate type parameter parents for functions. Note that methods
|
||||
// do not appear as objects in any scope, so they have to be dealt
|
||||
// with separately in extractMethods.
|
||||
if funcObj, ok := obj.(*types.Func); ok {
|
||||
populateTypeParamParents(tw, funcObj.Type().(*types.Signature).TypeParams(), obj)
|
||||
populateTypeParamParents(tw, funcObj.Type().(*types.Signature).RecvTypeParams(), obj)
|
||||
}
|
||||
// Populate type parameter parents for named types. Note that we
|
||||
// skip type aliases as the original type should be the parent
|
||||
// of any type parameters.
|
||||
if typeNameObj, ok := obj.(*types.TypeName); ok && !typeNameObj.IsAlias() {
|
||||
if tp, ok := typeNameObj.Type().(*types.Named); ok {
|
||||
populateTypeParamParents(tw, tp.TypeParams(), obj)
|
||||
}
|
||||
}
|
||||
extractObject(tw, obj, lbl)
|
||||
}
|
||||
|
||||
|
@ -378,10 +392,16 @@ func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label)
|
|||
func extractMethod(tw *trap.Writer, meth *types.Func) trap.Label {
|
||||
// get the receiver type of the method
|
||||
recvtyp := meth.Type().(*types.Signature).Recv().Type()
|
||||
recvlbl := extractType(tw, recvtyp) // ensure receiver type has been extracted
|
||||
// ensure receiver type has been extracted
|
||||
recvtyplbl := extractType(tw, recvtyp)
|
||||
|
||||
// if the method label does not exist, extract it
|
||||
methlbl, exists := tw.Labeler.MethodID(meth, recvlbl)
|
||||
methlbl, exists := tw.Labeler.MethodID(meth, recvtyplbl)
|
||||
if !exists {
|
||||
// Populate type parameter parents for methods. They do not appear as
|
||||
// objects in any scope, so they have to be dealt with separately here.
|
||||
populateTypeParamParents(tw, meth.Type().(*types.Signature).TypeParams(), meth)
|
||||
populateTypeParamParents(tw, meth.Type().(*types.Signature).RecvTypeParams(), meth)
|
||||
extractObject(tw, meth, methlbl)
|
||||
}
|
||||
|
||||
|
@ -435,8 +455,30 @@ func extractObject(tw *trap.Writer, obj types.Object, lbl trap.Label) {
|
|||
}
|
||||
}
|
||||
|
||||
// extractObjectTypes extracts type and receiver information for all objects
|
||||
func extractObjectTypes(tw *trap.Writer) {
|
||||
// calling `extractType` on a named type will extract all methods defined
|
||||
// on it, which will add new objects. Therefore we need to do this first
|
||||
// before we loops over all objects and emit them.
|
||||
changed := true
|
||||
for changed {
|
||||
changed = tw.ForEachObject(extractObjectType)
|
||||
}
|
||||
changed = tw.ForEachObject(emitObjectType)
|
||||
if changed {
|
||||
log.Printf("Warning: more objects were labeled while emitted object types")
|
||||
}
|
||||
}
|
||||
|
||||
// extractObjectType extracts type and receiver information for a given object
|
||||
func extractObjectType(tw *trap.Writer, obj types.Object, lbl trap.Label) {
|
||||
if tp := obj.Type(); tp != nil {
|
||||
extractType(tw, tp)
|
||||
}
|
||||
}
|
||||
|
||||
// emitObjectType emits the type information for a given object
|
||||
func emitObjectType(tw *trap.Writer, obj types.Object, lbl trap.Label) {
|
||||
if tp := obj.Type(); tp != nil {
|
||||
dbscheme.ObjectTypesTable.Emit(tw, lbl, extractType(tw, tp))
|
||||
}
|
||||
|
@ -583,7 +625,7 @@ func (extraction *Extraction) extractFile(ast *ast.File, pkg *packages.Package)
|
|||
|
||||
extractFileNode(tw, ast)
|
||||
|
||||
tw.ForEachObject(extractObjectType)
|
||||
extractObjectTypes(tw)
|
||||
|
||||
extractNumLines(tw, path, ast)
|
||||
|
||||
|
@ -685,7 +727,8 @@ func extractScopeLocation(tw *trap.Writer, scope *types.Scope, lbl trap.Label) {
|
|||
}
|
||||
|
||||
// extractScopes extracts symbol table information for the package scope and all local scopes
|
||||
// of the given package
|
||||
// of the given package. Note that this will not encounter methods or struct fields as
|
||||
// they do not have a parent scope.
|
||||
func extractScopes(tw *trap.Writer, nd *ast.File, pkg *packages.Package) {
|
||||
pkgScopeLabel := extractPackageScope(tw, pkg)
|
||||
fileScope := pkg.TypesInfo.Scopes[nd]
|
||||
|
@ -801,7 +844,7 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int) {
|
|||
dbscheme.DefsTable.Emit(tw, lbl, objlbl)
|
||||
}
|
||||
}
|
||||
use := tw.Package.TypesInfo.Uses[expr]
|
||||
use := getObjectBeingUsed(tw, expr)
|
||||
if use != nil {
|
||||
useTyp := extractType(tw, use.Type())
|
||||
objlbl, exists := tw.Labeler.LookupObjectID(use, useTyp)
|
||||
|
@ -877,9 +920,43 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int) {
|
|||
if expr == nil {
|
||||
return
|
||||
}
|
||||
typeofx := typeOf(tw, expr.X)
|
||||
if typeofx == nil {
|
||||
// We are missing type information for `expr.X`, so we cannot
|
||||
// determine whether this is a generic function instantiation
|
||||
// or not.
|
||||
kind = dbscheme.IndexExpr.Index()
|
||||
} else {
|
||||
if _, ok := typeofx.Underlying().(*types.Signature); ok {
|
||||
kind = dbscheme.GenericFunctionInstantiationExpr.Index()
|
||||
} else {
|
||||
// Can't distinguish between actual index expressions (into a
|
||||
// map, array, slice, string or pointer to array) and generic
|
||||
// type specialization expression, so we do it later in QL.
|
||||
kind = dbscheme.IndexExpr.Index()
|
||||
}
|
||||
}
|
||||
extractExpr(tw, expr.X, lbl, 0)
|
||||
extractExpr(tw, expr.Index, lbl, 1)
|
||||
case *ast.IndexListExpr:
|
||||
if expr == nil {
|
||||
return
|
||||
}
|
||||
typeofx := typeOf(tw, expr.X)
|
||||
if typeofx == nil {
|
||||
// We are missing type information for `expr.X`, so we cannot
|
||||
// determine whether this is a generic function instantiation
|
||||
// or not.
|
||||
kind = dbscheme.GenericTypeInstantiationExpr.Index()
|
||||
} else {
|
||||
if _, ok := typeofx.Underlying().(*types.Signature); ok {
|
||||
kind = dbscheme.GenericFunctionInstantiationExpr.Index()
|
||||
} else {
|
||||
kind = dbscheme.GenericTypeInstantiationExpr.Index()
|
||||
}
|
||||
}
|
||||
extractExpr(tw, expr.X, lbl, 0)
|
||||
extractExprs(tw, expr.Indices, lbl, 1, 1)
|
||||
case *ast.SliceExpr:
|
||||
if expr == nil {
|
||||
return
|
||||
|
@ -923,16 +1000,25 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int) {
|
|||
if expr == nil {
|
||||
return
|
||||
}
|
||||
if expr.Op == token.TILDE {
|
||||
kind = dbscheme.TypeSetLiteralExpr.Index()
|
||||
} else {
|
||||
tp := dbscheme.UnaryExprs[expr.Op]
|
||||
if tp == nil {
|
||||
log.Fatalf("unsupported unary operator %s", expr.Op)
|
||||
}
|
||||
kind = tp.Index()
|
||||
}
|
||||
extractExpr(tw, expr.X, lbl, 0)
|
||||
case *ast.BinaryExpr:
|
||||
if expr == nil {
|
||||
return
|
||||
}
|
||||
_, isUnionType := typeOf(tw, expr).(*types.Union)
|
||||
if expr.Op == token.OR && isUnionType {
|
||||
kind = dbscheme.TypeSetLiteralExpr.Index()
|
||||
flattenBinaryExprTree(tw, expr, lbl, 0)
|
||||
} else {
|
||||
tp := dbscheme.BinaryExprs[expr.Op]
|
||||
if tp == nil {
|
||||
log.Fatalf("unsupported binary operator %s", expr.Op)
|
||||
|
@ -940,6 +1026,7 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int) {
|
|||
kind = tp.Index()
|
||||
extractExpr(tw, expr.X, lbl, 0)
|
||||
extractExpr(tw, expr.Y, lbl, 1)
|
||||
}
|
||||
case *ast.ArrayType:
|
||||
if expr == nil {
|
||||
return
|
||||
|
@ -966,6 +1053,9 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int) {
|
|||
return
|
||||
}
|
||||
kind = dbscheme.InterfaceTypeExpr.Index()
|
||||
// expr.Methods contains methods, embedded interfaces and type set
|
||||
// literals.
|
||||
makeTypeSetLiteralsUnionTyped(tw, expr.Methods)
|
||||
extractFields(tw, expr.Methods, lbl, 0, 1)
|
||||
case *ast.MapType:
|
||||
if expr == nil {
|
||||
|
@ -1009,7 +1099,7 @@ func extractExprs(tw *trap.Writer, exprs []ast.Expr, parent trap.Label, idx int,
|
|||
// extractTypeOf looks up the type of `expr`, extracts it if it hasn't previously been
|
||||
// extracted, and associates it with `expr` in the `type_of` table
|
||||
func extractTypeOf(tw *trap.Writer, expr ast.Expr, lbl trap.Label) {
|
||||
tp := tw.Package.TypesInfo.TypeOf(expr)
|
||||
tp := typeOf(tw, expr)
|
||||
if tp != nil {
|
||||
tplbl := extractType(tw, tp)
|
||||
dbscheme.TypeOfTable.Emit(tw, lbl, tplbl)
|
||||
|
@ -1304,6 +1394,12 @@ func extractDecl(tw *trap.Writer, decl ast.Decl, parent trap.Label, idx int) {
|
|||
extractExpr(tw, decl.Type, lbl, 1)
|
||||
extractStmt(tw, decl.Body, lbl, 2)
|
||||
extractDoc(tw, decl.Doc, lbl)
|
||||
extractTypeParamDecls(tw, decl.Type.TypeParams, lbl)
|
||||
|
||||
// Note that we currently don't extract any kind of declaration for
|
||||
// receiver type parameters. There isn't an explicit declaration, but
|
||||
// we could consider the index/indices of an IndexExpr/IndexListExpr
|
||||
// receiver as declarations.
|
||||
default:
|
||||
log.Fatalf("unknown declaration of type %T", decl)
|
||||
}
|
||||
|
@ -1345,6 +1441,7 @@ func extractSpec(tw *trap.Writer, spec ast.Spec, parent trap.Label, idx int) {
|
|||
kind = dbscheme.TypeDefSpecType.Index()
|
||||
}
|
||||
extractExpr(tw, spec.Name, lbl, 0)
|
||||
extractTypeParamDecls(tw, spec.TypeParams, lbl)
|
||||
extractExpr(tw, spec.Type, lbl, 1)
|
||||
extractDoc(tw, spec.Doc, lbl)
|
||||
}
|
||||
|
@ -1377,7 +1474,9 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
|||
for i := 0; i < tp.NumFields(); i++ {
|
||||
field := tp.Field(i)
|
||||
|
||||
// ensure the field is associated with a label
|
||||
// ensure the field is associated with a label - note that
|
||||
// struct fields do not have a parent scope, so they are not
|
||||
// dealt with by `extractScopes`
|
||||
fieldlbl, exists := tw.Labeler.FieldID(field, i, lbl)
|
||||
if !exists {
|
||||
extractObject(tw, field, fieldlbl)
|
||||
|
@ -1399,10 +1498,19 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
|||
for i := 0; i < tp.NumMethods(); i++ {
|
||||
meth := tp.Method(i)
|
||||
|
||||
// Note that methods do not have a parent scope, so they are
|
||||
// not dealt with by `extractScopes`
|
||||
extractMethod(tw, meth)
|
||||
|
||||
extractComponentType(tw, lbl, i, meth.Name(), meth.Type())
|
||||
}
|
||||
for i := 0; i < tp.NumEmbeddeds(); i++ {
|
||||
component := tp.EmbeddedType(i)
|
||||
if isNonUnionTypeSetLiteral(component) {
|
||||
component = createUnionFromType(component)
|
||||
}
|
||||
extractComponentType(tw, lbl, -(i + 1), "", component)
|
||||
}
|
||||
case *types.Tuple:
|
||||
kind = dbscheme.TupleType.Index()
|
||||
for i := 0; i < tp.Len(); i++ {
|
||||
|
@ -1410,11 +1518,11 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
|||
}
|
||||
case *types.Signature:
|
||||
kind = dbscheme.SignatureType.Index()
|
||||
parms, results := tp.Params(), tp.Results()
|
||||
if parms != nil {
|
||||
for i := 0; i < parms.Len(); i++ {
|
||||
parm := parms.At(i)
|
||||
extractComponentType(tw, lbl, i+1, "", parm.Type())
|
||||
params, results := tp.Params(), tp.Results()
|
||||
if params != nil {
|
||||
for i := 0; i < params.Len(); i++ {
|
||||
param := params.At(i)
|
||||
extractComponentType(tw, lbl, i+1, "", param.Type())
|
||||
}
|
||||
}
|
||||
if results != nil {
|
||||
|
@ -1434,24 +1542,27 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
|||
kind = dbscheme.ChanTypes[tp.Dir()].Index()
|
||||
extractElementType(tw, lbl, tp.Elem())
|
||||
case *types.Named:
|
||||
origintp := tp.Origin()
|
||||
kind = dbscheme.NamedType.Index()
|
||||
dbscheme.TypeNameTable.Emit(tw, lbl, tp.Obj().Name())
|
||||
underlying := tp.Underlying()
|
||||
dbscheme.TypeNameTable.Emit(tw, lbl, origintp.Obj().Name())
|
||||
underlying := origintp.Underlying()
|
||||
extractUnderlyingType(tw, lbl, underlying)
|
||||
trackInstantiatedStructFields(tw, tp, origintp)
|
||||
|
||||
entitylbl, exists := tw.Labeler.LookupObjectID(tp.Obj(), lbl)
|
||||
entitylbl, exists := tw.Labeler.LookupObjectID(origintp.Obj(), lbl)
|
||||
if entitylbl == trap.InvalidLabel {
|
||||
log.Printf("Omitting type-object binding for unknown object %v.\n", tp.Obj())
|
||||
log.Printf("Omitting type-object binding for unknown object %v.\n", origintp.Obj())
|
||||
} else {
|
||||
if !exists {
|
||||
extractObject(tw, tp.Obj(), entitylbl)
|
||||
extractObject(tw, origintp.Obj(), entitylbl)
|
||||
}
|
||||
dbscheme.TypeObjectTable.Emit(tw, lbl, entitylbl)
|
||||
}
|
||||
|
||||
// ensure all methods have labels
|
||||
for i := 0; i < tp.NumMethods(); i++ {
|
||||
meth := tp.Method(i)
|
||||
// ensure all methods have labels - note that methods do not have a
|
||||
// parent scope, so they are not dealt with by `extractScopes`
|
||||
for i := 0; i < origintp.NumMethods(); i++ {
|
||||
meth := origintp.Method(i)
|
||||
|
||||
extractMethod(tw, meth)
|
||||
}
|
||||
|
@ -1463,6 +1574,21 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
|||
dbscheme.MethodHostsTable.Emit(tw, methlbl, lbl)
|
||||
}
|
||||
}
|
||||
case *types.TypeParam:
|
||||
kind = dbscheme.TypeParamType.Index()
|
||||
parentlbl := getTypeParamParentLabel(tw, tp)
|
||||
constraintLabel := extractType(tw, tp.Constraint())
|
||||
dbscheme.TypeParamTable.Emit(tw, lbl, tp.Obj().Name(), constraintLabel, parentlbl, tp.Index())
|
||||
case *types.Union:
|
||||
kind = dbscheme.TypeSetLiteral.Index()
|
||||
for i := 0; i < tp.Len(); i++ {
|
||||
term := tp.Term(i)
|
||||
tildeStr := ""
|
||||
if term.Tilde() {
|
||||
tildeStr = "~"
|
||||
}
|
||||
extractComponentType(tw, lbl, i, tildeStr, term.Type())
|
||||
}
|
||||
default:
|
||||
log.Fatalf("unexpected type %T", tp)
|
||||
}
|
||||
|
@ -1522,6 +1648,19 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
|
|||
}
|
||||
fmt.Fprintf(&b, "%s,{%s}", meth.Id(), methLbl)
|
||||
}
|
||||
b.WriteString(";")
|
||||
for i := 0; i < tp.NumEmbeddeds(); i++ {
|
||||
if i > 0 {
|
||||
b.WriteString(",")
|
||||
}
|
||||
fmt.Fprintf(&b, "{%s}", extractType(tw, tp.EmbeddedType(i)))
|
||||
}
|
||||
// We note whether the interface is comparable so that we can
|
||||
// distinguish the underlying type of `comparable` from an
|
||||
// empty interface.
|
||||
if tp.IsComparable() {
|
||||
b.WriteString(";comparable")
|
||||
}
|
||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%s;interfacetype", b.String()))
|
||||
case *types.Tuple:
|
||||
var b strings.Builder
|
||||
|
@ -1535,14 +1674,14 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
|
|||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%s;tupletype", b.String()))
|
||||
case *types.Signature:
|
||||
var b strings.Builder
|
||||
parms, results := tp.Params(), tp.Results()
|
||||
if parms != nil {
|
||||
for i := 0; i < parms.Len(); i++ {
|
||||
parmLbl := extractType(tw, parms.At(i).Type())
|
||||
params, results := tp.Params(), tp.Results()
|
||||
if params != nil {
|
||||
for i := 0; i < params.Len(); i++ {
|
||||
paramLbl := extractType(tw, params.At(i).Type())
|
||||
if i > 0 {
|
||||
b.WriteString(",")
|
||||
}
|
||||
fmt.Fprintf(&b, "{%s}", parmLbl)
|
||||
fmt.Fprintf(&b, "{%s}", paramLbl)
|
||||
}
|
||||
}
|
||||
b.WriteString(";")
|
||||
|
@ -1568,14 +1707,33 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
|
|||
elem := extractType(tw, tp.Elem())
|
||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%v,{%s};chantype", dir, elem))
|
||||
case *types.Named:
|
||||
entitylbl, exists := tw.Labeler.LookupObjectID(tp.Obj(), lbl)
|
||||
origintp := tp.Origin()
|
||||
entitylbl, exists := tw.Labeler.LookupObjectID(origintp.Obj(), lbl)
|
||||
if entitylbl == trap.InvalidLabel {
|
||||
panic(fmt.Sprintf("Cannot construct label for named type %v (underlying object is %v).\n", tp, tp.Obj()))
|
||||
panic(fmt.Sprintf("Cannot construct label for named type %v (underlying object is %v).\n", origintp, origintp.Obj()))
|
||||
}
|
||||
if !exists {
|
||||
extractObject(tw, tp.Obj(), entitylbl)
|
||||
extractObject(tw, origintp.Obj(), entitylbl)
|
||||
}
|
||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%s};namedtype", entitylbl))
|
||||
case *types.TypeParam:
|
||||
parentlbl := getTypeParamParentLabel(tw, tp)
|
||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%v},%s;typeparamtype", parentlbl, tp.Obj().Name()))
|
||||
case *types.Union:
|
||||
var b strings.Builder
|
||||
for i := 0; i < tp.Len(); i++ {
|
||||
compLbl := extractType(tw, tp.Term(i).Type())
|
||||
if i > 0 {
|
||||
b.WriteString("|")
|
||||
}
|
||||
if tp.Term(i).Tilde() {
|
||||
b.WriteString("~")
|
||||
}
|
||||
fmt.Fprintf(&b, "{%s}", compLbl)
|
||||
}
|
||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%s;typesetliteraltype", b.String()))
|
||||
default:
|
||||
log.Fatalf("(getTypeLabel) unexpected type %T", tp)
|
||||
}
|
||||
tw.Labeler.TypeLabels[tp] = lbl
|
||||
}
|
||||
|
@ -1658,3 +1816,206 @@ func extractNumLines(tw *trap.Writer, fileName string, ast *ast.File) {
|
|||
|
||||
dbscheme.NumlinesTable.Emit(tw, tw.Labeler.FileLabel(), lineCount, linesOfCode, linesOfComments)
|
||||
}
|
||||
|
||||
// For a type `t` which is the type of a field of an interface type, return
|
||||
// whether `t` a type set literal which is not a union type. Note that a field
|
||||
// of an interface must be a method signature, an embedded interface type or a
|
||||
// type set literal.
|
||||
func isNonUnionTypeSetLiteral(t types.Type) bool {
|
||||
if t == nil {
|
||||
return false
|
||||
}
|
||||
switch t.Underlying().(type) {
|
||||
case *types.Interface, *types.Union, *types.Signature:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Given a type `t`, return a union with a single term that is `t` without a
|
||||
// tilde.
|
||||
func createUnionFromType(t types.Type) *types.Union {
|
||||
return types.NewUnion([]*types.Term{types.NewTerm(false, t)})
|
||||
}
|
||||
|
||||
// Go through a `FieldList` and update the types of all type set literals which
|
||||
// are not already union types to be union types. We do this by changing the
|
||||
// types stored in `tw.Package.TypesInfo.Types`. Type set literals can only
|
||||
// occur in two places: a type parameter declaration or a type in an interface.
|
||||
func makeTypeSetLiteralsUnionTyped(tw *trap.Writer, fields *ast.FieldList) {
|
||||
if fields == nil || fields.List == nil {
|
||||
return
|
||||
}
|
||||
for i := 0; i < len(fields.List); i++ {
|
||||
x := fields.List[i].Type
|
||||
if _, alreadyOverridden := tw.TypesOverride[x]; !alreadyOverridden {
|
||||
xtp := typeOf(tw, x)
|
||||
if isNonUnionTypeSetLiteral(xtp) {
|
||||
tw.TypesOverride[x] = createUnionFromType(xtp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func typeOf(tw *trap.Writer, e ast.Expr) types.Type {
|
||||
if val, ok := tw.TypesOverride[e]; ok {
|
||||
return val
|
||||
}
|
||||
return tw.Package.TypesInfo.TypeOf(e)
|
||||
}
|
||||
|
||||
func flattenBinaryExprTree(tw *trap.Writer, e ast.Expr, parent trap.Label, idx int) int {
|
||||
binaryexpr, ok := e.(*ast.BinaryExpr)
|
||||
if ok {
|
||||
idx = flattenBinaryExprTree(tw, binaryexpr.X, parent, idx)
|
||||
idx = flattenBinaryExprTree(tw, binaryexpr.Y, parent, idx)
|
||||
} else {
|
||||
extractExpr(tw, e, parent, idx)
|
||||
idx = idx + 1
|
||||
}
|
||||
return idx
|
||||
}
|
||||
|
||||
func extractTypeParamDecls(tw *trap.Writer, fields *ast.FieldList, parent trap.Label) {
|
||||
if fields == nil || fields.List == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Type set literals can occur as the type in a type parameter declaration,
|
||||
// so we ensure that they are union typed.
|
||||
makeTypeSetLiteralsUnionTyped(tw, fields)
|
||||
|
||||
idx := 0
|
||||
for _, field := range fields.List {
|
||||
lbl := tw.Labeler.LocalID(field)
|
||||
dbscheme.TypeParamDeclsTable.Emit(tw, lbl, parent, idx)
|
||||
extractNodeLocation(tw, field, lbl)
|
||||
if field.Names != nil {
|
||||
for i, name := range field.Names {
|
||||
extractExpr(tw, name, lbl, i+1)
|
||||
}
|
||||
}
|
||||
extractExpr(tw, field.Type, lbl, 0)
|
||||
extractDoc(tw, field.Doc, lbl)
|
||||
idx += 1
|
||||
}
|
||||
}
|
||||
|
||||
// populateTypeParamParents sets `parent` as the parent of the elements of `typeparams`
|
||||
func populateTypeParamParents(tw *trap.Writer, typeparams *types.TypeParamList, parent types.Object) {
|
||||
if typeparams != nil {
|
||||
for idx := 0; idx < typeparams.Len(); idx++ {
|
||||
setTypeParamParent(typeparams.At(idx), parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getobjectBeingUsed looks up `ident` in `tw.Package.TypesInfo.Uses` and makes
|
||||
// some changes to the object to avoid returning objects relating to instantiated
|
||||
// types.
|
||||
func getObjectBeingUsed(tw *trap.Writer, ident *ast.Ident) types.Object {
|
||||
obj := tw.Package.TypesInfo.Uses[ident]
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
if override, ok := tw.ObjectsOverride[obj]; ok {
|
||||
return override
|
||||
}
|
||||
if funcObj, ok := obj.(*types.Func); ok {
|
||||
sig := funcObj.Type().(*types.Signature)
|
||||
if recv := sig.Recv(); recv != nil {
|
||||
recvType := recv.Type()
|
||||
originType, isSame := tryGetGenericType(recvType)
|
||||
|
||||
if originType == nil {
|
||||
if pointerType, ok := recvType.(*types.Pointer); ok {
|
||||
originType, isSame = tryGetGenericType(pointerType.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
if originType == nil || isSame {
|
||||
return obj
|
||||
}
|
||||
|
||||
for i := 0; i < originType.NumMethods(); i++ {
|
||||
meth := originType.Method(i)
|
||||
if meth.Name() == funcObj.Name() {
|
||||
return meth
|
||||
}
|
||||
}
|
||||
if interfaceType, ok := originType.Underlying().(*types.Interface); ok {
|
||||
for i := 0; i < interfaceType.NumMethods(); i++ {
|
||||
meth := interfaceType.Method(i)
|
||||
if meth.Name() == funcObj.Name() {
|
||||
return meth
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Fatalf("Could not find method %s on type %s", funcObj.Name(), originType)
|
||||
}
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
// tryGetGenericType returns the generic type of `tp`, and a boolean indicating
|
||||
// whether it is the same as `tp`.
|
||||
func tryGetGenericType(tp types.Type) (*types.Named, bool) {
|
||||
if namedType, ok := tp.(*types.Named); ok {
|
||||
originType := namedType.Origin()
|
||||
return originType, namedType == originType
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// trackInstantiatedStructFields tries to give the fields of an instantiated
|
||||
// struct type underlying `tp` the same labels as the corresponding fields of
|
||||
// the generic struct type. This is so that when we come across the
|
||||
// instantiated field in `tw.Package.TypesInfo.Uses` we will get the label for
|
||||
// the generic field instead.
|
||||
func trackInstantiatedStructFields(tw *trap.Writer, tp, origintp *types.Named) {
|
||||
if tp == origintp {
|
||||
return
|
||||
}
|
||||
|
||||
if instantiatedStruct, ok := tp.Underlying().(*types.Struct); ok {
|
||||
genericStruct, ok2 := origintp.Underlying().(*types.Struct)
|
||||
if !ok2 {
|
||||
log.Fatalf(
|
||||
"Error: underlying type of instantiated type is a struct but underlying type of generic type is %s",
|
||||
origintp.Underlying())
|
||||
}
|
||||
|
||||
if instantiatedStruct.NumFields() != genericStruct.NumFields() {
|
||||
log.Fatalf(
|
||||
"Error: instantiated struct %s has different number of fields than the generic version %s (%d != %d)",
|
||||
instantiatedStruct, genericStruct, instantiatedStruct.NumFields(), genericStruct.NumFields())
|
||||
}
|
||||
|
||||
for i := 0; i < instantiatedStruct.NumFields(); i++ {
|
||||
tw.ObjectsOverride[instantiatedStruct.Field(i)] = genericStruct.Field(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getTypeParamParentLabel(tw *trap.Writer, tp *types.TypeParam) trap.Label {
|
||||
parent, exists := typeParamParent[tp]
|
||||
if !exists {
|
||||
log.Fatalf("Parent of type parameter does not exist: %s %s", tp.String(), tp.Constraint().String())
|
||||
}
|
||||
parentlbl, _ := tw.Labeler.ScopedObjectID(parent, func() trap.Label {
|
||||
log.Fatalf("getTypeLabel() called for parent of type parameter %s", tp.String())
|
||||
return trap.InvalidLabel
|
||||
})
|
||||
return parentlbl
|
||||
}
|
||||
|
||||
func setTypeParamParent(tp *types.TypeParam, newobj types.Object) {
|
||||
obj, exists := typeParamParent[tp]
|
||||
if !exists {
|
||||
typeParamParent[tp] = newobj
|
||||
} else if newobj != obj {
|
||||
log.Fatalf("Parent of type parameter '%s %s' being set to a different value: '%s' vs '%s'", tp.String(), tp.Constraint().String(), obj, newobj)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ func (l *Labeler) LookupObjectID(object types.Object, typelbl Label) (Label, boo
|
|||
}
|
||||
label = InvalidLabel
|
||||
} else {
|
||||
label, exists = l.ScopedObjectID(object, typelbl)
|
||||
label, exists = l.ScopedObjectID(object, func() Label { return typelbl })
|
||||
}
|
||||
}
|
||||
return label, exists
|
||||
|
@ -144,7 +144,7 @@ func (l *Labeler) LookupObjectID(object types.Object, typelbl Label) (Label, boo
|
|||
// detected, we must construct a special label, as the variable can be reached
|
||||
// from several files via the method. As the type label is required to construct
|
||||
// the receiver object id, it is also required here.
|
||||
func (l *Labeler) ScopedObjectID(object types.Object, typelbl Label) (Label, bool) {
|
||||
func (l *Labeler) ScopedObjectID(object types.Object, getTypeLabel func() Label) (Label, bool) {
|
||||
label, exists := l.objectLabels[object]
|
||||
if !exists {
|
||||
scope := object.Parent()
|
||||
|
@ -154,19 +154,17 @@ func (l *Labeler) ScopedObjectID(object types.Object, typelbl Label) (Label, boo
|
|||
} else {
|
||||
// associate method receiver objects to special keys, because those can be
|
||||
// referenced from other files via their method
|
||||
isRecv := false
|
||||
if namedType, ok := object.Type().(*types.Named); ok {
|
||||
for i := 0; i < namedType.NumMethods(); i++ {
|
||||
meth := namedType.Method(i)
|
||||
if object == meth.Type().(*types.Signature).Recv() {
|
||||
isRecv = true
|
||||
methlbl, _ := l.MethodID(meth, typelbl)
|
||||
label, _ = l.ReceiverObjectID(object, methlbl)
|
||||
}
|
||||
meth := findMethodWithGivenReceiver(object.Type(), object)
|
||||
if meth == nil {
|
||||
if pointerType, ok := object.Type().(*types.Pointer); ok {
|
||||
meth = findMethodWithGivenReceiver(pointerType.Elem(), object)
|
||||
}
|
||||
}
|
||||
|
||||
if !isRecv {
|
||||
if meth != nil {
|
||||
methlbl, _ := l.MethodID(meth, getTypeLabel())
|
||||
label, _ = l.ReceiverObjectID(object, methlbl)
|
||||
} else {
|
||||
scopeLbl := l.ScopeID(scope, object.Pkg())
|
||||
label = l.GlobalID(fmt.Sprintf("{%v},%s;object", scopeLbl, object.Name()))
|
||||
}
|
||||
|
@ -176,6 +174,18 @@ func (l *Labeler) ScopedObjectID(object types.Object, typelbl Label) (Label, boo
|
|||
return label, exists
|
||||
}
|
||||
|
||||
func findMethodWithGivenReceiver(tp types.Type, object types.Object) *types.Func {
|
||||
if namedType, ok := tp.(*types.Named); ok {
|
||||
for i := 0; i < namedType.NumMethods(); i++ {
|
||||
meth := namedType.Method(i)
|
||||
if object == meth.Type().(*types.Signature).Recv() {
|
||||
return meth
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReceiverObjectID associates a label with the given object and returns it, together with a flag indicating whether
|
||||
// the object already had a label associated with it; the object must be the receiver of `methlbl`, since that label
|
||||
// is used to construct the label of the object
|
||||
|
@ -210,12 +220,12 @@ func (l *Labeler) FieldID(field *types.Var, idx int, structlbl Label) (Label, bo
|
|||
}
|
||||
|
||||
// MethodID associates a label with the given method and returns it, together with a flag indicating whether
|
||||
// the method already had a label associated with it; the method must belong to `recvlbl`, since that label
|
||||
// the method already had a label associated with it; the method must belong to `recvtyplbl`, since that label
|
||||
// is used to construct the label of the method
|
||||
func (l *Labeler) MethodID(method types.Object, recvlbl Label) (Label, bool) {
|
||||
func (l *Labeler) MethodID(method types.Object, recvtyplbl Label) (Label, bool) {
|
||||
label, exists := l.objectLabels[method]
|
||||
if !exists {
|
||||
label = l.GlobalID(fmt.Sprintf("{%v},%s;method", recvlbl, method.Name()))
|
||||
label = l.GlobalID(fmt.Sprintf("{%v},%s;method", recvtyplbl, method.Name()))
|
||||
l.objectLabels[method] = label
|
||||
}
|
||||
return label, exists
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/types"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -24,6 +25,8 @@ type Writer struct {
|
|||
path string
|
||||
trapFilePath string
|
||||
Package *packages.Package
|
||||
TypesOverride map[ast.Expr]types.Type
|
||||
ObjectsOverride map[types.Object]types.Object
|
||||
}
|
||||
|
||||
func FileFor(path string) (string, error) {
|
||||
|
@ -61,6 +64,8 @@ func NewWriter(path string, pkg *packages.Package) (*Writer, error) {
|
|||
path,
|
||||
trapFilePath,
|
||||
pkg,
|
||||
make(map[ast.Expr]types.Type),
|
||||
make(map[types.Object]types.Object),
|
||||
}
|
||||
tw.Labeler = newLabeler(tw)
|
||||
return tw, nil
|
||||
|
@ -104,11 +109,22 @@ func (tw *Writer) Close() error {
|
|||
|
||||
// ForEachObject iterates over all objects labeled by this labeler, and invokes
|
||||
// the provided callback with a writer for the trap file, the object, and its
|
||||
// label.
|
||||
func (tw *Writer) ForEachObject(cb func(*Writer, types.Object, Label)) {
|
||||
for object, lbl := range tw.Labeler.objectLabels {
|
||||
cb(tw, object, lbl)
|
||||
// label. It returns true if any extra objects were labeled and false otherwise.
|
||||
func (tw *Writer) ForEachObject(cb func(*Writer, types.Object, Label)) bool {
|
||||
// copy the objects into an array so that our behaviour is deterministic even
|
||||
// if `cb` adds any new objects
|
||||
i := 0
|
||||
objects := make([]types.Object, len(tw.Labeler.objectLabels))
|
||||
for k := range tw.Labeler.objectLabels {
|
||||
objects[i] = k
|
||||
i++
|
||||
}
|
||||
|
||||
for _, object := range objects {
|
||||
cb(tw, object, tw.Labeler.objectLabels[object])
|
||||
}
|
||||
|
||||
return len(tw.Labeler.objectLabels) != len(objects)
|
||||
}
|
||||
|
||||
const max_strlen = 1024 * 1024
|
||||
|
|
2
go.mod
2
go.mod
|
@ -1,6 +1,6 @@
|
|||
module github.com/github/codeql-go
|
||||
|
||||
go 1.17
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
golang.org/x/mod v0.5.0
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category: feature
|
||||
---
|
||||
* Go 1.18 generics are now extracted and can be explored using the new CodeQL classes `TypeParamDecl`, `GenericFunctionInstantiationExpr`, `GenericTypeInstantiationExpr`, `TypeSetTerm`, and `TypeSetLiteralType`, as well as using new predicates defined on the existing `InterfaceType`. Class- and predicate-level documentation can be found in the [Go CodeQL library reference](https://codeql.github.com/codeql-standard-libraries/go/).
|
|
@ -157,6 +157,8 @@ constvalues(unique int expr: @expr ref, string value: string ref, string exact:
|
|||
|
||||
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
|
||||
|
||||
typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent 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);
|
||||
|
||||
|
@ -225,16 +227,20 @@ has_ellipsis(int id: @callorconversionexpr ref);
|
|||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref,
|
||||
int parent: @typeparamparentobject ref, int idx: int ref);
|
||||
|
||||
@container = @file | @folder;
|
||||
|
||||
@locatable = @xmllocatable | @node | @localscope;
|
||||
|
||||
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @scopenode
|
||||
| @comment_group | @comment;
|
||||
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
|
||||
| @scopenode | @comment_group | @comment;
|
||||
|
||||
@documentable = @file | @field | @spec | @gendecl | @funcdecl | @modexpr;
|
||||
@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr;
|
||||
|
||||
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @spec;
|
||||
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec;
|
||||
|
||||
@modexprparent = @file | @modexpr;
|
||||
|
||||
|
@ -244,6 +250,8 @@ variadic(int id: @signaturetype ref);
|
|||
|
||||
@declparent = @file | @declstmt;
|
||||
|
||||
@typeparamdeclparent = @funcdecl | @typespec;
|
||||
|
||||
@funcdef = @funclit | @funcdecl;
|
||||
|
||||
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
|
||||
|
@ -270,46 +278,49 @@ case @expr.kind of
|
|||
| 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
|
||||
| 52 = @errorexpr;
|
||||
| 13 = @genericfunctioninstantiationexpr
|
||||
| 14 = @generictypeinstantiationexpr
|
||||
| 15 = @sliceexpr
|
||||
| 16 = @typeassertexpr
|
||||
| 17 = @callorconversionexpr
|
||||
| 18 = @starexpr
|
||||
| 19 = @keyvalueexpr
|
||||
| 20 = @arraytypeexpr
|
||||
| 21 = @structtypeexpr
|
||||
| 22 = @functypeexpr
|
||||
| 23 = @interfacetypeexpr
|
||||
| 24 = @maptypeexpr
|
||||
| 25 = @typesetliteralexpr
|
||||
| 26 = @plusexpr
|
||||
| 27 = @minusexpr
|
||||
| 28 = @notexpr
|
||||
| 29 = @complementexpr
|
||||
| 30 = @derefexpr
|
||||
| 31 = @addressexpr
|
||||
| 32 = @arrowexpr
|
||||
| 33 = @lorexpr
|
||||
| 34 = @landexpr
|
||||
| 35 = @eqlexpr
|
||||
| 36 = @neqexpr
|
||||
| 37 = @lssexpr
|
||||
| 38 = @leqexpr
|
||||
| 39 = @gtrexpr
|
||||
| 40 = @geqexpr
|
||||
| 41 = @addexpr
|
||||
| 42 = @subexpr
|
||||
| 43 = @orexpr
|
||||
| 44 = @xorexpr
|
||||
| 45 = @mulexpr
|
||||
| 46 = @quoexpr
|
||||
| 47 = @remexpr
|
||||
| 48 = @shlexpr
|
||||
| 49 = @shrexpr
|
||||
| 50 = @andexpr
|
||||
| 51 = @andnotexpr
|
||||
| 52 = @sendchantypeexpr
|
||||
| 53 = @recvchantypeexpr
|
||||
| 54 = @sendrcvchantypeexpr
|
||||
| 55 = @errorexpr;
|
||||
|
||||
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
|
||||
|
||||
|
@ -430,6 +441,8 @@ case @object.kind of
|
|||
| 7 = @builtinfunctionobject
|
||||
| 8 = @labelobject;
|
||||
|
||||
@typeparamparentobject = @decltypeobject | @declfunctionobject;
|
||||
|
||||
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
|
||||
|
||||
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
|
||||
|
@ -476,18 +489,20 @@ case @type.kind of
|
|||
| 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;
|
||||
| 26 = @typeparamtype
|
||||
| 27 = @arraytype
|
||||
| 28 = @slicetype
|
||||
| 29 = @structtype
|
||||
| 30 = @pointertype
|
||||
| 31 = @interfacetype
|
||||
| 32 = @tupletype
|
||||
| 33 = @signaturetype
|
||||
| 34 = @maptype
|
||||
| 35 = @sendchantype
|
||||
| 36 = @recvchantype
|
||||
| 37 = @sendrcvchantype
|
||||
| 38 = @namedtype
|
||||
| 39 = @typesetliteraltype;
|
||||
|
||||
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
|
||||
|
||||
|
@ -510,7 +525,8 @@ case @type.kind of
|
|||
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
|
||||
| @stringliteraltype | @nilliteraltype;
|
||||
|
||||
@compositetype = @containertype | @structtype | @pointertype | @interfacetype | @tupletype | @signaturetype | @namedtype;
|
||||
@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype
|
||||
| @signaturetype | @namedtype | @typesetliteraltype;
|
||||
|
||||
@containertype = @arraytype | @slicetype | @maptype | @chantype;
|
||||
|
||||
|
|
|
@ -216,6 +216,24 @@ class FieldParent extends @fieldparent, AstNode {
|
|||
int getNumFields() { result = count(getAField()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An AST node whose children include type parameter declarations.
|
||||
*/
|
||||
class TypeParamDeclParent extends @typeparamdeclparent, AstNode {
|
||||
/**
|
||||
* Gets the `i`th type parameter declaration of this node.
|
||||
*
|
||||
* Note that the precise indices of type parameters are considered an implementation detail
|
||||
* and are subject to change without notice.
|
||||
*/
|
||||
TypeParamDecl getTypeParameterDecl(int i) { typeparamdecls(result, this, i) }
|
||||
|
||||
/**
|
||||
* Gets a child field of this node in the AST.
|
||||
*/
|
||||
TypeParamDecl getATypeParameterDecl() { result = this.getTypeParameterDecl(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An AST node which may induce a scope.
|
||||
*
|
||||
|
|
|
@ -146,7 +146,7 @@ class FuncDef extends @funcdef, StmtParent, ExprParent {
|
|||
/**
|
||||
* A function declaration.
|
||||
*/
|
||||
class FuncDecl extends @funcdecl, Decl, Documentable, FuncDef {
|
||||
class FuncDecl extends @funcdecl, Decl, Documentable, FuncDef, TypeParamDeclParent {
|
||||
/** Gets the identifier denoting the name of this function. */
|
||||
Ident getNameExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
|
@ -376,7 +376,7 @@ class ValueSpec extends @valuespec, Spec {
|
|||
* )
|
||||
* ```
|
||||
*/
|
||||
class TypeSpec extends @typespec, Spec {
|
||||
class TypeSpec extends @typespec, Spec, TypeParamDeclParent {
|
||||
/** Gets the identifier denoting the name of the declared type. */
|
||||
Ident getNameExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
|
@ -562,6 +562,57 @@ class ResultVariableDecl extends ParameterOrResultDecl {
|
|||
override string getAPrimaryQlClass() { result = "ResultVariableDecl" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A type parameter declaration in a type specification.
|
||||
*/
|
||||
class TypeParamDecl extends @typeparamdecl, Documentable, ExprParent {
|
||||
TypeParamDecl() { typeparamdecls(this, _, _) }
|
||||
|
||||
/**
|
||||
* Gets the expression representing the type constraint of the type
|
||||
* parameters in this declaration.
|
||||
*
|
||||
* If you want the type constraint type itself then use `getTypeConstraint`,
|
||||
* as that wraps type set literals with implicit interface types.
|
||||
*/
|
||||
Expr getTypeConstraintExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/**
|
||||
* Gets the type constraint of the type parameters in this declaration.
|
||||
*
|
||||
* If the type constraint is a type set literal then it will be wrapped
|
||||
* with an implicit interface type.
|
||||
*/
|
||||
Type getTypeConstraint() {
|
||||
exists(Type t | t = this.getTypeConstraintExpr().getType() |
|
||||
if t instanceof TypeSetLiteralType
|
||||
then result = t.(TypeSetLiteralType).getInterfaceType()
|
||||
else result = t
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expression representing the name of the `i`th type parameter
|
||||
* in this declaration (0-based).
|
||||
*/
|
||||
Expr getNameExpr(int i) {
|
||||
i >= 0 and
|
||||
result = this.getChildExpr(i + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `i`th type parameter type in this declaration (0-based).
|
||||
*/
|
||||
TypeParamType getTypeParamType(int i) {
|
||||
i >= 0 and
|
||||
result = this.getNameExpr(i).getType()
|
||||
}
|
||||
|
||||
override string toString() { result = "type parameter declaration" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeParamDecl" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A method or embedding specification in an interface type expression.
|
||||
*/
|
||||
|
|
|
@ -626,14 +626,21 @@ class PromotedSelector extends SelectorExpr {
|
|||
|
||||
/**
|
||||
* An index expression, that is, a base expression followed by an index.
|
||||
* Expressions which represent generic type instantiations have been
|
||||
* excluded.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```go
|
||||
* a[i]
|
||||
* array[i]
|
||||
* arrayptr[i]
|
||||
* slice[i]
|
||||
* map[key]
|
||||
* ```
|
||||
*/
|
||||
class IndexExpr extends @indexexpr, Expr {
|
||||
IndexExpr() { not isTypeExprBottomUp(this.getChildExpr(0)) }
|
||||
|
||||
/** Gets the base of this index expression. */
|
||||
Expr getBase() { result = this.getChildExpr(0) }
|
||||
|
||||
|
@ -647,6 +654,68 @@ class IndexExpr extends @indexexpr, Expr {
|
|||
override string getAPrimaryQlClass() { result = "IndexExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic function instantiation, that is, a base expression that represents
|
||||
* a generic function, followed by a list of type arguments.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```go
|
||||
* genericfunction[type]
|
||||
* genericfunction[type1, type2]
|
||||
* ```
|
||||
*/
|
||||
class GenericFunctionInstantiationExpr extends @genericfunctioninstantiationexpr, Expr {
|
||||
/** Gets the generic function expression. */
|
||||
Expr getBase() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the `i`th type argument. */
|
||||
Expr getTypeArgument(int i) {
|
||||
i >= 0 and
|
||||
result = this.getChildExpr(i + 1)
|
||||
}
|
||||
|
||||
override predicate mayHaveOwnSideEffects() { any() }
|
||||
|
||||
override string toString() { result = "generic function instantiation expression" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "GenericFunctionInstantiationExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic type instantiation, that is, a base expression that is a generic
|
||||
* type followed by a list of type arguments.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```go
|
||||
* generictype[type]
|
||||
* generictype[type1, type2]
|
||||
* ```
|
||||
*/
|
||||
class GenericTypeInstantiationExpr extends Expr {
|
||||
GenericTypeInstantiationExpr() {
|
||||
this instanceof @generictypeinstantiationexpr
|
||||
or
|
||||
this instanceof @indexexpr and isTypeExprBottomUp(this.getChildExpr(0))
|
||||
}
|
||||
|
||||
/** Gets the generic type expression. */
|
||||
Expr getBase() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the `i`th type argument. */
|
||||
Expr getTypeArgument(int i) {
|
||||
i >= 0 and
|
||||
result = this.getChildExpr(i + 1)
|
||||
}
|
||||
|
||||
override predicate mayHaveOwnSideEffects() { any() }
|
||||
|
||||
override string toString() { result = "generic type instantiation expression" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "GenericTypeInstantiationExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A slice expression, that is, a base expression followed by slice indices.
|
||||
*
|
||||
|
@ -770,7 +839,11 @@ class CallExpr extends CallOrConversionExpr {
|
|||
}
|
||||
|
||||
/** Gets the expression representing the function being called. */
|
||||
Expr getCalleeExpr() { result = this.getChildExpr(0) }
|
||||
Expr getCalleeExpr() {
|
||||
if this.getChildExpr(0) instanceof GenericFunctionInstantiationExpr
|
||||
then result = this.getChildExpr(0).(GenericFunctionInstantiationExpr).getBase()
|
||||
else result = this.getChildExpr(0)
|
||||
}
|
||||
|
||||
/** Gets the `i`th argument expression of this call (0-based). */
|
||||
Expr getArgument(int i) {
|
||||
|
@ -995,6 +1068,22 @@ class MapTypeExpr extends @maptypeexpr, TypeExpr {
|
|||
override string getAPrimaryQlClass() { result = "MapTypeExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression representing a type set literal.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```go
|
||||
* ~string
|
||||
* int64 | float64
|
||||
* ```
|
||||
*/
|
||||
class TypeSetLiteralExpr extends @typesetliteralexpr, TypeExpr {
|
||||
override string toString() { result = "type set literal" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeSetLiteralExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression with a (unary or binary) operator.
|
||||
*
|
||||
|
@ -1956,15 +2045,30 @@ class LabelName extends Name {
|
|||
* a bottom-up analysis. In such cases, `isTypeExprTopDown` below is useful.
|
||||
*/
|
||||
private predicate isTypeExprBottomUp(Expr e) {
|
||||
e instanceof TypeName or
|
||||
e instanceof @arraytypeexpr or
|
||||
e instanceof @structtypeexpr or
|
||||
e instanceof @functypeexpr or
|
||||
e instanceof @interfacetypeexpr or
|
||||
e instanceof @maptypeexpr or
|
||||
e instanceof @chantypeexpr or
|
||||
isTypeExprBottomUp(e.(ParenExpr).getExpr()) or
|
||||
isTypeExprBottomUp(e.(StarExpr).getBase()) or
|
||||
e instanceof TypeName
|
||||
or
|
||||
e instanceof @arraytypeexpr
|
||||
or
|
||||
e instanceof @structtypeexpr
|
||||
or
|
||||
e instanceof @functypeexpr
|
||||
or
|
||||
e instanceof @interfacetypeexpr
|
||||
or
|
||||
e instanceof @maptypeexpr
|
||||
or
|
||||
e instanceof @chantypeexpr
|
||||
or
|
||||
e instanceof @typesetliteralexpr
|
||||
or
|
||||
e instanceof @generictypeinstantiationexpr
|
||||
or
|
||||
e instanceof @indexexpr and isTypeExprBottomUp(e.getChildExpr(0))
|
||||
or
|
||||
isTypeExprBottomUp(e.(ParenExpr).getExpr())
|
||||
or
|
||||
isTypeExprBottomUp(e.(StarExpr).getBase())
|
||||
or
|
||||
isTypeExprBottomUp(e.(Ellipsis).getOperand())
|
||||
}
|
||||
|
||||
|
@ -1989,6 +2093,10 @@ private predicate isTypeExprTopDown(Expr e) {
|
|||
or
|
||||
e = any(ParameterDecl pd).getTypeExpr()
|
||||
or
|
||||
e = any(TypeParamDecl tpd).getTypeConstraintExpr()
|
||||
or
|
||||
e = any(TypeParamDecl tpd).getNameExpr(_)
|
||||
or
|
||||
e = any(ReceiverDecl rd).getTypeExpr()
|
||||
or
|
||||
e = any(ResultVariableDecl rvd).getTypeExpr()
|
||||
|
@ -2005,6 +2113,10 @@ private predicate isTypeExprTopDown(Expr e) {
|
|||
or
|
||||
e = any(TypeSpec s).getTypeExpr()
|
||||
or
|
||||
e = any(GenericTypeInstantiationExpr gtie).getBase()
|
||||
or
|
||||
e = any(GenericTypeInstantiationExpr gtie).getTypeArgument(_)
|
||||
or
|
||||
e = any(TypeSwitchStmt s).getACase().getExpr(_) and
|
||||
// special case: `nil` is allowed in a type case but isn't a type
|
||||
not e = Builtin::nil().getAReference()
|
||||
|
|
|
@ -66,18 +66,75 @@ class Type extends @type {
|
|||
|
||||
/**
|
||||
* Holds if this type implements interface `i`, that is, the method set of `i`
|
||||
* is contained in the method set of this type.
|
||||
* is contained in the method set of this type and any type restrictions are
|
||||
* satisfied.
|
||||
*/
|
||||
predicate implements(InterfaceType i) {
|
||||
isEmptyInterface(i)
|
||||
if i = any(ComparableType comparable).getUnderlyingType()
|
||||
then this.implementsComparable()
|
||||
else this.implementsNotComparable(i)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type implements interface `i`, which is not the underlying
|
||||
* type of `comparable`. This predicate is needed to avoid non-monotonic
|
||||
* recursion.
|
||||
*/
|
||||
private predicate implementsNotComparable(InterfaceType i) {
|
||||
(
|
||||
forall(TypeSetLiteralType tslit | tslit = i.getAnEmbeddedTypeSetLiteral() |
|
||||
tslit.includesType(this)
|
||||
) and
|
||||
(
|
||||
hasNoMethods(i)
|
||||
or
|
||||
this.hasMethod(getExampleMethodName(i), _) and
|
||||
forall(string m, SignatureType t | i.hasMethod(m, t) | this.hasMethod(m, t))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type implements `comparable`. This includes being
|
||||
* `comparable` itself, or the underlying type of `comparable`.
|
||||
*/
|
||||
predicate implementsComparable() {
|
||||
exists(Type u | u = this.getUnderlyingType() |
|
||||
// Note that BasicType includes Invalidtype
|
||||
u instanceof BasicType
|
||||
or
|
||||
u instanceof PointerType
|
||||
or
|
||||
u instanceof ChanType
|
||||
or
|
||||
u instanceof StructType and
|
||||
forall(Type fieldtp | u.(StructType).hasField(_, fieldtp) | fieldtp.implementsComparable())
|
||||
or
|
||||
u instanceof ArrayType and u.(ArrayType).getElementType().implementsComparable()
|
||||
or
|
||||
exists(InterfaceType uif | uif = u |
|
||||
not uif instanceof BasicInterfaceType and
|
||||
if exists(uif.getAnEmbeddedTypeSetLiteral())
|
||||
then
|
||||
// All types in the intersection of all the embedded type set
|
||||
// literals must implement comparable.
|
||||
forall(Type intersectionType |
|
||||
intersectionType = uif.getAnEmbeddedTypeSetLiteral().getATerm().getType() and
|
||||
forall(TypeSetLiteralType tslit | tslit = uif.getAnEmbeddedTypeSetLiteral() |
|
||||
intersectionType = tslit.getATerm().getType()
|
||||
)
|
||||
|
|
||||
intersectionType.implementsComparable()
|
||||
)
|
||||
else uif.isOrEmbedsComparable()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type implements an interface that has the qualified name `pkg.name`,
|
||||
* that is, the method set of `pkg.name` is contained in the method set of this type.
|
||||
* that is, the method set of `pkg.name` is contained in the method set of this type
|
||||
* and any type restrictions are satisfied.
|
||||
*/
|
||||
predicate implements(string pkg, string name) {
|
||||
exists(Type t | t.hasQualifiedName(pkg, name) | this.implements(t.getUnderlyingType()))
|
||||
|
@ -306,6 +363,26 @@ class NilLiteralType extends @nilliteraltype, LiteralType {
|
|||
/** A composite type, that is, not a basic type. */
|
||||
class CompositeType extends @compositetype, Type { }
|
||||
|
||||
/** A type that comes from a type parameter. */
|
||||
class TypeParamType extends @typeparamtype, CompositeType {
|
||||
/** Gets the name of this type parameter type. */
|
||||
string getParamName() { typeparam(this, result, _, _, _) }
|
||||
|
||||
/** Gets the constraint of this type parameter type. */
|
||||
Type getConstraint() { typeparam(this, _, result, _, _) }
|
||||
|
||||
override InterfaceType getUnderlyingType() { result = this.getConstraint().getUnderlyingType() }
|
||||
|
||||
override string pp() { result = this.getParamName() }
|
||||
|
||||
/**
|
||||
* Gets a pretty-printed representation of this type including its constraint.
|
||||
*/
|
||||
string ppWithConstraint() { result = this.getParamName() + " " + this.getConstraint().pp() }
|
||||
|
||||
override string toString() { result = "type parameter type" }
|
||||
}
|
||||
|
||||
/** An array type. */
|
||||
class ArrayType extends @arraytype, CompositeType {
|
||||
/** Gets the element type of this array type. */
|
||||
|
@ -532,33 +609,269 @@ class PointerType extends @pointertype, CompositeType {
|
|||
override string toString() { result = "pointer type" }
|
||||
}
|
||||
|
||||
/** An interface type. */
|
||||
class InterfaceType extends @interfacetype, CompositeType {
|
||||
/** Gets the type of method `name` of this interface type. */
|
||||
Type getMethodType(string name) { component_types(this, _, name, result) }
|
||||
private newtype TTypeSetTerm =
|
||||
MkTypeSetTerm(TypeSetLiteralType tslit, int index) { component_types(tslit, index, _, _) }
|
||||
|
||||
override predicate hasMethod(string m, SignatureType t) { t = this.getMethodType(m) }
|
||||
/**
|
||||
* A term in a type set literal.
|
||||
*
|
||||
* Examples:
|
||||
* ```go
|
||||
* int
|
||||
* ~string
|
||||
* ```
|
||||
*/
|
||||
class TypeSetTerm extends TTypeSetTerm {
|
||||
boolean tilde;
|
||||
Type tp;
|
||||
|
||||
TypeSetTerm() {
|
||||
exists(TypeSetLiteralType tslit, int index |
|
||||
this = MkTypeSetTerm(tslit, index) and
|
||||
(
|
||||
component_types(tslit, index, "", tp) and
|
||||
tilde = false
|
||||
or
|
||||
component_types(tslit, index, "~", tp) and
|
||||
tilde = true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this term has a tilde in front of it.
|
||||
*
|
||||
* A tilde is used to indicate that the term refers to all types with a given
|
||||
* underlying type.
|
||||
*/
|
||||
predicate hasTilde() { tilde = true }
|
||||
|
||||
/** Gets the type of this term. */
|
||||
Type getType() { result = tp }
|
||||
|
||||
/** Holds if `t` is in the type set of this term. */
|
||||
predicate includesType(Type t) { if tilde = false then t = tp else t.getUnderlyingType() = tp }
|
||||
|
||||
/** Gets a pretty-printed representation of this term. */
|
||||
string pp() {
|
||||
exists(string tildeStr | if tilde = true then tildeStr = "~" else tildeStr = "" |
|
||||
result = tildeStr + tp.pp()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = "type set term" }
|
||||
}
|
||||
|
||||
private TypeSetTerm getIntersection(TypeSetTerm term1, TypeSetTerm term2) {
|
||||
term1.getType() = term2.getType() and
|
||||
if term1.hasTilde() then result = term2 else result = term1
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a term in the intersection of type-set literals `a` and `b`.
|
||||
*/
|
||||
TypeSetTerm getTermInIntersection(TypeSetLiteralType a, TypeSetLiteralType b) {
|
||||
result = getIntersection(a.getATerm(), b.getATerm())
|
||||
}
|
||||
|
||||
/**
|
||||
* A type set literal type, used when declaring a non-basic interface. May be a
|
||||
* single term, consisting of either a type or a tilde followed by a type, or a
|
||||
* union of terms.
|
||||
*
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```go
|
||||
* int
|
||||
* ~string
|
||||
* int | ~string
|
||||
* ```
|
||||
*/
|
||||
class TypeSetLiteralType extends @typesetliteraltype, CompositeType {
|
||||
/** Gets the `i`th term in this type set literal. */
|
||||
TypeSetTerm getTerm(int i) { result = MkTypeSetTerm(this, i) }
|
||||
|
||||
/** Gets a term in this type set literal. */
|
||||
TypeSetTerm getATerm() { result = this.getTerm(_) }
|
||||
|
||||
/** Holds if `t` is in the type set of this type set literal. */
|
||||
predicate includesType(Type t) { this.getATerm().includesType(t) }
|
||||
|
||||
/**
|
||||
* Gets the interface type of which this type-set literal is the only
|
||||
* element, if it exists.
|
||||
*
|
||||
* It exists if it has been explicitly defined, as in
|
||||
* `interface { int64 | uint64 }`, or if it has been implicitly created by
|
||||
* using the type set literal directly as the bound in a type parameter
|
||||
* declaration, as in `[T int64 | uint64]`.
|
||||
*/
|
||||
InterfaceType getInterfaceType() {
|
||||
this = result.getDirectlyEmbeddedTypeSetLiteral(0) and
|
||||
not exists(result.getDirectlyEmbeddedTypeSetLiteral(1)) and
|
||||
hasNoMethods(result) and
|
||||
not exists(result.getADirectlyEmbeddedInterface())
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
override string pp() {
|
||||
exists(string meth |
|
||||
result = concat(TypeSetTerm t, int i | t = this.getTerm(i) | t.pp(), " | " order by i)
|
||||
}
|
||||
|
||||
override string toString() { result = "type set literal type" }
|
||||
}
|
||||
|
||||
/** An interface type. */
|
||||
class InterfaceType extends @interfacetype, CompositeType {
|
||||
/** Gets the type of method `name` of this interface type. */
|
||||
Type getMethodType(string name) {
|
||||
// Note that negative indices correspond to embedded interfaces and type
|
||||
// set literals.
|
||||
exists(int i | i >= 0 | component_types(this, i, name, result))
|
||||
}
|
||||
|
||||
override predicate hasMethod(string m, SignatureType t) { t = this.getMethodType(m) }
|
||||
|
||||
/**
|
||||
* Holds if `tp` is a directly embedded type with index `index`.
|
||||
*
|
||||
* `tp` (or its underlying type) is either a type set literal type or an
|
||||
* interface type.
|
||||
*/
|
||||
private predicate hasDirectlyEmbeddedType(int index, Type tp) {
|
||||
index >= 0 and component_types(this, -(index + 1), _, tp)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a type whose underlying type is an interface that is directly
|
||||
* embedded into this interface.
|
||||
*
|
||||
* Note that the methods of the embedded interface are already considered
|
||||
* as part of the method set of this interface.
|
||||
*/
|
||||
Type getADirectlyEmbeddedInterface() {
|
||||
this.hasDirectlyEmbeddedType(_, result) and result.getUnderlyingType() instanceof InterfaceType
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a type whose underlying type is an interface that is embedded into
|
||||
* this interface.
|
||||
*
|
||||
* Note that the methods of the embedded interface are already considered
|
||||
* as part of the method set of this interface.
|
||||
*/
|
||||
Type getAnEmbeddedInterface() {
|
||||
result = this.getADirectlyEmbeddedInterface() or
|
||||
result =
|
||||
this.getADirectlyEmbeddedInterface()
|
||||
.getUnderlyingType()
|
||||
.(InterfaceType)
|
||||
.getAnEmbeddedInterface()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this interface type is (the underlying type of) `comparable`, or
|
||||
* it embeds `comparable`.
|
||||
*/
|
||||
predicate isOrEmbedsComparable() {
|
||||
this.getAnEmbeddedInterface() instanceof ComparableType or
|
||||
this = any(ComparableType comparable).getUnderlyingType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type set literal with index `index` from the definition of this
|
||||
* interface type.
|
||||
*
|
||||
* Note that the indexes are not contiguous.
|
||||
*/
|
||||
TypeSetLiteralType getDirectlyEmbeddedTypeSetLiteral(int index) {
|
||||
hasDirectlyEmbeddedType(index, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a type set literal of this interface type.
|
||||
*
|
||||
* This includes type set literals of embedded interfaces.
|
||||
*/
|
||||
TypeSetLiteralType getAnEmbeddedTypeSetLiteral() {
|
||||
result = this.getDirectlyEmbeddedTypeSetLiteral(_) or
|
||||
result =
|
||||
getADirectlyEmbeddedInterface()
|
||||
.getUnderlyingType()
|
||||
.(InterfaceType)
|
||||
.getAnEmbeddedTypeSetLiteral()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
override string pp() {
|
||||
exists(string comp, string sep1, string ts, string sep2, string meth |
|
||||
// Note that the interface type underlying `comparable` will be printed
|
||||
// as `interface { comparable }`, which is not entirely accurate, but
|
||||
// also better than anything else I can think of.
|
||||
(if this.isOrEmbedsComparable() then comp = " comparable" else comp = "") and
|
||||
ts =
|
||||
concat(TypeSetLiteralType tslit |
|
||||
tslit = this.getAnEmbeddedTypeSetLiteral()
|
||||
|
|
||||
" " + tslit.pp(), ";"
|
||||
) and
|
||||
meth =
|
||||
concat(string name, Type tp |
|
||||
tp = this.getMethodType(name)
|
||||
|
|
||||
" " + name + " " + tp.pp(), ";" order by name
|
||||
)
|
||||
) and
|
||||
(if comp != "" and ts != "" then sep1 = ";" else sep1 = "") and
|
||||
if
|
||||
(comp != "" or ts != "") and
|
||||
meth != ""
|
||||
then sep2 = ";"
|
||||
else sep2 = ""
|
||||
|
|
||||
result = "interface {" + meth + " }"
|
||||
result = "interface {" + comp + sep1 + ts + sep2 + meth + " }"
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() { result = "interface type" }
|
||||
}
|
||||
|
||||
/** An empty interface type. */
|
||||
class EmptyInterfaceType extends InterfaceType {
|
||||
EmptyInterfaceType() { not this.hasMethod(_, _) }
|
||||
// This predicate is needed for performance reasons.
|
||||
pragma[noinline]
|
||||
private predicate hasNoMethods(InterfaceType i) { not i.hasMethod(_, _) }
|
||||
|
||||
/**
|
||||
* A basic interface type.
|
||||
*
|
||||
* A basic interface is an interface that does not specify any type set
|
||||
* literals, and which does not embed any non-basic interfaces. The special
|
||||
* interface `comparable` is not a basic interface.
|
||||
*/
|
||||
class BasicInterfaceType extends InterfaceType {
|
||||
BasicInterfaceType() {
|
||||
not exists(this.getAnEmbeddedTypeSetLiteral()) and
|
||||
not this.isOrEmbedsComparable()
|
||||
}
|
||||
|
||||
override string toString() { result = "basic interface type" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An empty interface type.
|
||||
*
|
||||
* Note that by we have to be careful to exclude the underlying type of
|
||||
* `comparable`. This is done by extending `BasicInterfaceType`.
|
||||
*/
|
||||
class EmptyInterfaceType extends BasicInterfaceType {
|
||||
EmptyInterfaceType() { hasNoMethods(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The predeclared `comparable` type.
|
||||
*/
|
||||
class ComparableType extends NamedType {
|
||||
ComparableType() { this.getName() = "comparable" }
|
||||
}
|
||||
|
||||
/** A tuple type. */
|
||||
|
@ -693,12 +1006,6 @@ class ErrorType extends Type {
|
|||
ErrorType() { this.implements(Builtin::error().getType().getUnderlyingType()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `i` is the empty interface type, which is implemented by every type with a method set.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate isEmptyInterface(InterfaceType i) { not i.hasMethod(_, _) }
|
||||
|
||||
/**
|
||||
* Gets the name of a method in the method set of `i`.
|
||||
*
|
||||
|
|
|
@ -698,6 +698,10 @@ module CFG {
|
|||
not this.(SelectorExpr).getBase() instanceof ValueExpr and
|
||||
nd = mkExprOrSkipNode(this) and
|
||||
cmpl = Done()
|
||||
or
|
||||
this instanceof GenericFunctionInstantiationExpr and
|
||||
nd = MkExprNode(this) and
|
||||
cmpl = Done()
|
||||
}
|
||||
|
||||
override predicate firstNode(ControlFlow::Node first) { first = nd }
|
||||
|
|
|
@ -443,7 +443,8 @@ module Public {
|
|||
*/
|
||||
private DataFlow::Node getACalleeSource(DataFlow::CallNode cn) {
|
||||
result = cn.getCalleeNode() or
|
||||
basicLocalFlowStep(result, getACalleeSource(cn))
|
||||
basicLocalFlowStep(result, getACalleeSource(cn)) or
|
||||
result.asExpr() = getACalleeSource(cn).asExpr().(GenericFunctionInstantiationExpr).getBase()
|
||||
}
|
||||
|
||||
/** A data flow node that represents a call. */
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
class Expr_ extends @expr {
|
||||
string toString() { result = "Expr" }
|
||||
}
|
||||
|
||||
class ExprParent_ extends @exprparent {
|
||||
string toString() { result = "ExprParent" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Two new kinds have been inserted such that `@sliceexpr` which used to have
|
||||
* index 13 now has index 15. Another new kind has been inserted such that
|
||||
* `@plusexpr` which used to have index 23 now has index 26. Entries with
|
||||
* indices lower than 13 are unchanged.
|
||||
*/
|
||||
bindingset[old_index]
|
||||
int new_index(int old_index) {
|
||||
if old_index < 13
|
||||
then result = old_index
|
||||
else
|
||||
if old_index < 23
|
||||
then result = (15 - 13) + old_index
|
||||
else result = (26 - 23) + old_index
|
||||
}
|
||||
|
||||
// The schema for exprs is:
|
||||
//
|
||||
// exprs(unique int id: @expr,
|
||||
// int kind: int ref,
|
||||
// int parent: @exprparent ref,
|
||||
// int idx: int ref);
|
||||
from Expr_ expr, int new_kind, ExprParent_ parent, int idx, int old_kind
|
||||
where exprs(expr, old_kind, parent, idx) and new_kind = new_index(old_kind)
|
||||
select expr, new_kind, parent, idx
|
|
@ -0,0 +1,547 @@
|
|||
/** 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);
|
||||
|
||||
|
||||
/*
|
||||
* XML Files
|
||||
*/
|
||||
|
||||
xmlEncoding(
|
||||
unique int id: @file ref,
|
||||
string encoding: string ref
|
||||
);
|
||||
|
||||
xmlDTDs(
|
||||
unique int id: @xmldtd,
|
||||
string root: string ref,
|
||||
string publicId: string ref,
|
||||
string systemId: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlElements(
|
||||
unique int id: @xmlelement,
|
||||
string name: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlAttrs(
|
||||
unique int id: @xmlattribute,
|
||||
int elementid: @xmlelement ref,
|
||||
string name: string ref,
|
||||
string value: string ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlNs(
|
||||
int id: @xmlnamespace,
|
||||
string prefixName: string ref,
|
||||
string URI: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlHasNs(
|
||||
int elementId: @xmlnamespaceable ref,
|
||||
int nsId: @xmlnamespace ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlComments(
|
||||
unique int id: @xmlcomment,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlChars(
|
||||
unique int id: @xmlcharacters,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int isCDATA: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
@xmlparent = @file | @xmlelement;
|
||||
@xmlnamespaceable = @xmlelement | @xmlattribute;
|
||||
|
||||
xmllocations(
|
||||
int xmlElement: @xmllocatable ref,
|
||||
int location: @location_default ref
|
||||
);
|
||||
|
||||
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
|
||||
|
||||
compilations(unique int id: @compilation, string cwd: string ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
|
||||
|
||||
#keyset[id, num, kind]
|
||||
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
|
||||
|
||||
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
|
||||
|
||||
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
|
||||
|
||||
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
|
||||
string full_error_message: string ref, int location: @location 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);
|
||||
|
||||
folders(unique int id: @folder, string name: 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);
|
||||
|
||||
typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent 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);
|
||||
|
||||
has_ellipsis(int id: @callorconversionexpr ref);
|
||||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref,
|
||||
int parent: @typeparamparentobject ref, int idx: int ref);
|
||||
|
||||
@container = @file | @folder;
|
||||
|
||||
@locatable = @xmllocatable | @node | @localscope;
|
||||
|
||||
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
|
||||
| @scopenode | @comment_group | @comment;
|
||||
|
||||
@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr;
|
||||
|
||||
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec;
|
||||
|
||||
@modexprparent = @file | @modexpr;
|
||||
|
||||
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
|
||||
|
||||
@stmtparent = @funcdef | @stmt | @decl;
|
||||
|
||||
@declparent = @file | @declstmt;
|
||||
|
||||
@typeparamdeclparent = @funcdecl | @typespec;
|
||||
|
||||
@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 = @genericfunctioninstantiationexpr
|
||||
| 14 = @generictypeinstantiationexpr
|
||||
| 15 = @sliceexpr
|
||||
| 16 = @typeassertexpr
|
||||
| 17 = @callorconversionexpr
|
||||
| 18 = @starexpr
|
||||
| 19 = @keyvalueexpr
|
||||
| 20 = @arraytypeexpr
|
||||
| 21 = @structtypeexpr
|
||||
| 22 = @functypeexpr
|
||||
| 23 = @interfacetypeexpr
|
||||
| 24 = @maptypeexpr
|
||||
| 25 = @typesetliteralexpr
|
||||
| 26 = @plusexpr
|
||||
| 27 = @minusexpr
|
||||
| 28 = @notexpr
|
||||
| 29 = @complementexpr
|
||||
| 30 = @derefexpr
|
||||
| 31 = @addressexpr
|
||||
| 32 = @arrowexpr
|
||||
| 33 = @lorexpr
|
||||
| 34 = @landexpr
|
||||
| 35 = @eqlexpr
|
||||
| 36 = @neqexpr
|
||||
| 37 = @lssexpr
|
||||
| 38 = @leqexpr
|
||||
| 39 = @gtrexpr
|
||||
| 40 = @geqexpr
|
||||
| 41 = @addexpr
|
||||
| 42 = @subexpr
|
||||
| 43 = @orexpr
|
||||
| 44 = @xorexpr
|
||||
| 45 = @mulexpr
|
||||
| 46 = @quoexpr
|
||||
| 47 = @remexpr
|
||||
| 48 = @shlexpr
|
||||
| 49 = @shrexpr
|
||||
| 50 = @andexpr
|
||||
| 51 = @andnotexpr
|
||||
| 52 = @sendchantypeexpr
|
||||
| 53 = @recvchantypeexpr
|
||||
| 54 = @sendrcvchantypeexpr
|
||||
| 55 = @errorexpr;
|
||||
|
||||
@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 = @typedefspec
|
||||
| 3 = @aliasspec;
|
||||
|
||||
@typespec = @typedefspec | @aliasspec;
|
||||
|
||||
case @object.kind of
|
||||
0 = @pkgobject
|
||||
| 1 = @decltypeobject
|
||||
| 2 = @builtintypeobject
|
||||
| 3 = @declconstobject
|
||||
| 4 = @builtinconstobject
|
||||
| 5 = @declvarobject
|
||||
| 6 = @declfunctionobject
|
||||
| 7 = @builtinfunctionobject
|
||||
| 8 = @labelobject;
|
||||
|
||||
@typeparamparentobject = @decltypeobject | @declfunctionobject;
|
||||
|
||||
@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 = @typeparamtype
|
||||
| 27 = @arraytype
|
||||
| 28 = @slicetype
|
||||
| 29 = @structtype
|
||||
| 30 = @pointertype
|
||||
| 31 = @interfacetype
|
||||
| 32 = @tupletype
|
||||
| 33 = @signaturetype
|
||||
| 34 = @maptype
|
||||
| 35 = @sendchantype
|
||||
| 36 = @recvchantype
|
||||
| 37 = @sendrcvchantype
|
||||
| 38 = @namedtype
|
||||
| 39 = @typesetliteraltype;
|
||||
|
||||
@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 = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype
|
||||
| @signaturetype | @namedtype | @typesetliteraltype;
|
||||
|
||||
@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;
|
||||
|
|
@ -0,0 +1,531 @@
|
|||
/** 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);
|
||||
|
||||
|
||||
/*
|
||||
* XML Files
|
||||
*/
|
||||
|
||||
xmlEncoding(
|
||||
unique int id: @file ref,
|
||||
string encoding: string ref
|
||||
);
|
||||
|
||||
xmlDTDs(
|
||||
unique int id: @xmldtd,
|
||||
string root: string ref,
|
||||
string publicId: string ref,
|
||||
string systemId: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlElements(
|
||||
unique int id: @xmlelement,
|
||||
string name: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlAttrs(
|
||||
unique int id: @xmlattribute,
|
||||
int elementid: @xmlelement ref,
|
||||
string name: string ref,
|
||||
string value: string ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlNs(
|
||||
int id: @xmlnamespace,
|
||||
string prefixName: string ref,
|
||||
string URI: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlHasNs(
|
||||
int elementId: @xmlnamespaceable ref,
|
||||
int nsId: @xmlnamespace ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlComments(
|
||||
unique int id: @xmlcomment,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlChars(
|
||||
unique int id: @xmlcharacters,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int isCDATA: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
@xmlparent = @file | @xmlelement;
|
||||
@xmlnamespaceable = @xmlelement | @xmlattribute;
|
||||
|
||||
xmllocations(
|
||||
int xmlElement: @xmllocatable ref,
|
||||
int location: @location_default ref
|
||||
);
|
||||
|
||||
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
|
||||
|
||||
compilations(unique int id: @compilation, string cwd: string ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
|
||||
|
||||
#keyset[id, num, kind]
|
||||
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
|
||||
|
||||
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
|
||||
|
||||
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
|
||||
|
||||
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
|
||||
string full_error_message: string ref, int location: @location 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);
|
||||
|
||||
folders(unique int id: @folder, string name: 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);
|
||||
|
||||
has_ellipsis(int id: @callorconversionexpr ref);
|
||||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
@container = @file | @folder;
|
||||
|
||||
@locatable = @xmllocatable | @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
|
||||
| 52 = @errorexpr;
|
||||
|
||||
@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 = @typedefspec
|
||||
| 3 = @aliasspec;
|
||||
|
||||
@typespec = @typedefspec | @aliasspec;
|
||||
|
||||
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;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
class Type_ extends @type {
|
||||
string toString() { result = "Type" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A new kind has been inserted such that `@arraytype` which used to have index
|
||||
* 26 now has index 27. Another new kind has been inserted at 39, which is the
|
||||
* end of the list. Entries with lower indices are unchanged.
|
||||
*/
|
||||
bindingset[old_index]
|
||||
int new_index(int old_index) {
|
||||
if old_index < 26 then result = old_index else result = (27 - 26) + old_index
|
||||
}
|
||||
|
||||
// The schema for types is:
|
||||
//
|
||||
// types(unique int id: @type,
|
||||
// int kind: int ref);
|
||||
from Type_ type, int new_kind, int old_kind
|
||||
where types(type, old_kind) and new_kind = new_index(old_kind)
|
||||
select type, new_kind
|
|
@ -0,0 +1,4 @@
|
|||
description: Add generic instantiation expressions and type parameter types
|
||||
compatibility: backwards
|
||||
exprs.rel: run exprs.qlo
|
||||
types.rel: run types.qlo
|
|
@ -51,16 +51,12 @@ numlines(
|
|||
|
||||
files(
|
||||
unique int id: @file,
|
||||
string name: string ref,
|
||||
string simple: string ref,
|
||||
string ext: string ref,
|
||||
int fromSource: int ref // deprecated
|
||||
string name: string ref
|
||||
);
|
||||
|
||||
folders(
|
||||
unique int id: @folder,
|
||||
string name: string ref,
|
||||
string simple: string ref
|
||||
string name: string ref
|
||||
);
|
||||
|
||||
@container = @folder | @file
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
| genericFunctions.go:25:2:25:33 | generic function instantiation expression | genericFunctions.go:25:2:25:28 | GenericFunctionOneTypeParam | 0 | genericFunctions.go:25:30:25:32 | int |
|
||||
| genericFunctions.go:26:2:26:36 | generic function instantiation expression | genericFunctions.go:26:2:26:28 | GenericFunctionOneTypeParam | 0 | genericFunctions.go:26:30:26:35 | string |
|
||||
| genericFunctions.go:44:6:44:48 | generic function instantiation expression | genericFunctions.go:44:6:44:33 | GenericFunctionTwoTypeParams | 0 | genericFunctions.go:44:35:44:40 | string |
|
||||
| genericFunctions.go:44:6:44:48 | generic function instantiation expression | genericFunctions.go:44:6:44:33 | GenericFunctionTwoTypeParams | 1 | genericFunctions.go:44:43:44:47 | int64 |
|
||||
| genericFunctions.go:45:6:45:50 | generic function instantiation expression | genericFunctions.go:45:6:45:33 | GenericFunctionTwoTypeParams | 0 | genericFunctions.go:45:35:45:40 | string |
|
||||
| genericFunctions.go:45:6:45:50 | generic function instantiation expression | genericFunctions.go:45:6:45:33 | GenericFunctionTwoTypeParams | 1 | genericFunctions.go:45:43:45:49 | float64 |
|
||||
| genericFunctions.go:141:6:141:41 | generic function instantiation expression | genericFunctions.go:141:6:141:33 | GenericFunctionInAnotherFile | 0 | genericFunctions.go:141:35:141:40 | string |
|
||||
| genericFunctions.go:146:6:146:55 | generic function instantiation expression | genericFunctions.go:146:6:146:47 | selection of GenericFunctionInAnotherPackage | 0 | genericFunctions.go:146:49:146:54 | string |
|
|
@ -0,0 +1,4 @@
|
|||
import go
|
||||
|
||||
from GenericFunctionInstantiationExpr e, int i
|
||||
select e, e.getBase(), i, e.getTypeArgument(i)
|
|
@ -0,0 +1,15 @@
|
|||
| Edge | EdgeConstraint |
|
||||
| Edge | interface { } |
|
||||
| K | comparable |
|
||||
| Node | NodeConstraint |
|
||||
| Node | interface { } |
|
||||
| S | interface { } |
|
||||
| SF2 | interface { } |
|
||||
| SG2 | interface { } |
|
||||
| T | interface { } |
|
||||
| TF1 | interface { } |
|
||||
| TF2 | interface { } |
|
||||
| TG1 | interface { } |
|
||||
| TG2 | interface { } |
|
||||
| U | interface { } |
|
||||
| V | interface { int64 \| float64 } |
|
|
@ -0,0 +1,4 @@
|
|||
import go
|
||||
|
||||
from TypeParamType tpt
|
||||
select tpt.getParamName(), tpt.getConstraint().pp()
|
|
@ -0,0 +1,148 @@
|
|||
package main
|
||||
|
||||
import "github.com/anotherpkg"
|
||||
|
||||
type T1 map[string][]string
|
||||
type T2 T1
|
||||
|
||||
// A generic function with one type parameter
|
||||
func GenericFunctionOneTypeParam[T any](t T) T {
|
||||
var r T
|
||||
return r
|
||||
}
|
||||
|
||||
// A generic function with two type parameter
|
||||
func GenericFunctionTwoTypeParams[K comparable, V int64 | float64](m map[K]V) V {
|
||||
var s V
|
||||
for _, v := range m {
|
||||
s += v
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func generic_functions() {
|
||||
// Call the generic function with one type parameter, specifying the type
|
||||
GenericFunctionOneTypeParam[int](1)
|
||||
GenericFunctionOneTypeParam[string]("hello")
|
||||
|
||||
// Call the generic function with one type parameter, without specifying the type
|
||||
GenericFunctionOneTypeParam(1)
|
||||
GenericFunctionOneTypeParam("hello")
|
||||
|
||||
// Initialize a map for the integer values
|
||||
ints := map[string]int64{
|
||||
"first": 34,
|
||||
"second": 12,
|
||||
}
|
||||
|
||||
// Initialize a map for the float values
|
||||
floats := map[string]float64{
|
||||
"first": 35.98,
|
||||
"second": 26.99,
|
||||
}
|
||||
|
||||
_ = GenericFunctionTwoTypeParams[string, int64](ints)
|
||||
_ = GenericFunctionTwoTypeParams[string, float64](floats)
|
||||
|
||||
_ = GenericFunctionTwoTypeParams(ints)
|
||||
_ = GenericFunctionTwoTypeParams(floats)
|
||||
|
||||
// Map read
|
||||
_ = floats["first"]
|
||||
// Map write
|
||||
floats["first"] = -1.0
|
||||
|
||||
arrayVar := [5]int{1, 2, 3, 4, 5}
|
||||
// Array read
|
||||
_ = arrayVar[0]
|
||||
// Array write
|
||||
arrayVar[0] = -1
|
||||
|
||||
arrayPtr := &arrayVar
|
||||
// Array read through pointer
|
||||
_ = arrayPtr[0]
|
||||
// Array write through pointer
|
||||
arrayPtr[0] = -1
|
||||
|
||||
sliceVar := make([]int, 0, 5) // $ isVariadic
|
||||
// Slice read
|
||||
_ = sliceVar[0]
|
||||
// Slice write
|
||||
sliceVar[0] = -1
|
||||
|
||||
// Access a map through two type aliases
|
||||
aliasedMap := T2{"key": []string{"value"}}
|
||||
// Map read
|
||||
_ = aliasedMap["key"]
|
||||
// Map write
|
||||
aliasedMap["key"][0] = "new value"
|
||||
}
|
||||
|
||||
type GenericStruct1[T any] struct {
|
||||
}
|
||||
|
||||
type GenericStruct2[S, T any] struct {
|
||||
}
|
||||
|
||||
func (x GenericStruct1[TF1]) f1() TF1 {
|
||||
var r TF1
|
||||
return r
|
||||
}
|
||||
|
||||
func (x *GenericStruct1[TG1]) g1() {
|
||||
}
|
||||
|
||||
func (x GenericStruct2[SF2, TF2]) f2() {
|
||||
}
|
||||
|
||||
func (x *GenericStruct2[SG2, TG2]) g2() {
|
||||
}
|
||||
|
||||
func call_methods_with_generic_receiver() {
|
||||
x1 := GenericStruct1[int]{}
|
||||
x1.f1()
|
||||
x1.g1()
|
||||
|
||||
x2 := GenericStruct2[string, int]{}
|
||||
x2.f2()
|
||||
x2.g2()
|
||||
}
|
||||
|
||||
type Element[S any] struct {
|
||||
list *List[S]
|
||||
}
|
||||
|
||||
type List[T any] struct {
|
||||
root Element[T]
|
||||
}
|
||||
|
||||
// Len is the number of elements in the list.
|
||||
func (l *List[U]) MyLen() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
type NodeConstraint[Edge any] interface {
|
||||
Edges() []Edge
|
||||
}
|
||||
|
||||
type EdgeConstraint[Node any] interface {
|
||||
Nodes() (from, to Node)
|
||||
}
|
||||
|
||||
type Graph[Node NodeConstraint[Edge], Edge EdgeConstraint[Node]] struct{}
|
||||
|
||||
func New[Node NodeConstraint[Edge], Edge EdgeConstraint[Node]](nodes []Node) *Graph[Node, Edge] {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graph[Node, Edge]) ShortestPath(from, to Node) []Edge { return []Edge{} }
|
||||
|
||||
func callFunctionsInAnotherFile() {
|
||||
_ = GenericFunctionInAnotherFile[string]("world")
|
||||
_ = GenericFunctionInAnotherFile("world")
|
||||
}
|
||||
|
||||
func callFunctionsInAnotherPackage() {
|
||||
_ = anotherpkg.GenericFunctionInAnotherPackage[string]("world")
|
||||
_ = anotherpkg.GenericFunctionInAnotherPackage("world")
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package main
|
||||
|
||||
func GenericFunctionInAnotherFile[T any](t T) T {
|
||||
var r T
|
||||
return r
|
||||
}
|
|
@ -1,3 +1,15 @@
|
|||
| genericFunctions2.go:3:6:3:33 | GenericFunctionInAnotherFile | 0 | genericFunctions2.go:3:42:3:42 | t |
|
||||
| genericFunctions.go:9:6:9:32 | GenericFunctionOneTypeParam | 0 | genericFunctions.go:9:41:9:41 | t |
|
||||
| genericFunctions.go:15:6:15:33 | GenericFunctionTwoTypeParams | 0 | genericFunctions.go:15:68:15:68 | m |
|
||||
| genericFunctions.go:87:30:87:31 | f1 | -1 | genericFunctions.go:87:7:87:7 | x |
|
||||
| genericFunctions.go:92:31:92:32 | g1 | -1 | genericFunctions.go:92:7:92:7 | x |
|
||||
| genericFunctions.go:95:35:95:36 | f2 | -1 | genericFunctions.go:95:7:95:7 | x |
|
||||
| genericFunctions.go:98:36:98:37 | g2 | -1 | genericFunctions.go:98:7:98:7 | x |
|
||||
| genericFunctions.go:120:19:120:23 | MyLen | -1 | genericFunctions.go:120:7:120:7 | l |
|
||||
| genericFunctions.go:134:6:134:8 | New | 0 | genericFunctions.go:134:64:134:68 | nodes |
|
||||
| genericFunctions.go:138:29:138:40 | ShortestPath | 0 | genericFunctions.go:138:42:138:45 | from |
|
||||
| genericFunctions.go:138:29:138:40 | ShortestPath | 1 | genericFunctions.go:138:48:138:49 | to |
|
||||
| genericFunctions.go:138:29:138:40 | ShortestPath | -1 | genericFunctions.go:138:7:138:7 | g |
|
||||
| main.go:7:6:7:7 | f1 | 0 | main.go:7:9:7:9 | x |
|
||||
| main.go:9:12:9:13 | f2 | 0 | main.go:9:15:9:15 | x |
|
||||
| main.go:9:12:9:13 | f2 | 1 | main.go:9:18:9:18 | y |
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
| genericFunctions2.go:3:1:6:1 | function declaration | FuncDecl | 0 | genericFunctions2.go:3:35:3:39 | type parameter declaration | 0 | genericFunctions2.go:3:35:3:35 | T | genericFunctions2.go:3:37:3:39 | any | interface { } |
|
||||
| genericFunctions.go:9:1:12:1 | function declaration | FuncDecl | 0 | genericFunctions.go:9:34:9:38 | type parameter declaration | 0 | genericFunctions.go:9:34:9:34 | T | genericFunctions.go:9:36:9:38 | any | interface { } |
|
||||
| genericFunctions.go:15:1:21:1 | function declaration | FuncDecl | 0 | genericFunctions.go:15:35:15:46 | type parameter declaration | 0 | genericFunctions.go:15:35:15:35 | K | genericFunctions.go:15:37:15:46 | comparable | comparable |
|
||||
| genericFunctions.go:15:1:21:1 | function declaration | FuncDecl | 1 | genericFunctions.go:15:49:15:65 | type parameter declaration | 0 | genericFunctions.go:15:49:15:49 | V | genericFunctions.go:15:51:15:65 | type set literal | interface { int64 \| float64 } |
|
||||
| genericFunctions.go:81:6:82:1 | type declaration specifier | TypeSpec | 0 | genericFunctions.go:81:21:81:25 | type parameter declaration | 0 | genericFunctions.go:81:21:81:21 | T | genericFunctions.go:81:23:81:25 | any | interface { } |
|
||||
| genericFunctions.go:84:6:85:1 | type declaration specifier | TypeSpec | 0 | genericFunctions.go:84:21:84:28 | type parameter declaration | 0 | genericFunctions.go:84:21:84:21 | S | genericFunctions.go:84:26:84:28 | any | interface { } |
|
||||
| genericFunctions.go:84:6:85:1 | type declaration specifier | TypeSpec | 0 | genericFunctions.go:84:21:84:28 | type parameter declaration | 1 | genericFunctions.go:84:24:84:24 | T | genericFunctions.go:84:26:84:28 | any | interface { } |
|
||||
| genericFunctions.go:111:6:113:1 | type declaration specifier | TypeSpec | 0 | genericFunctions.go:111:14:111:18 | type parameter declaration | 0 | genericFunctions.go:111:14:111:14 | S | genericFunctions.go:111:16:111:18 | any | interface { } |
|
||||
| genericFunctions.go:115:6:117:1 | type declaration specifier | TypeSpec | 0 | genericFunctions.go:115:11:115:15 | type parameter declaration | 0 | genericFunctions.go:115:11:115:11 | T | genericFunctions.go:115:13:115:15 | any | interface { } |
|
||||
| genericFunctions.go:124:6:126:1 | type declaration specifier | TypeSpec | 0 | genericFunctions.go:124:21:124:28 | type parameter declaration | 0 | genericFunctions.go:124:21:124:24 | Edge | genericFunctions.go:124:26:124:28 | any | interface { } |
|
||||
| genericFunctions.go:128:6:130:1 | type declaration specifier | TypeSpec | 0 | genericFunctions.go:128:21:128:28 | type parameter declaration | 0 | genericFunctions.go:128:21:128:24 | Node | genericFunctions.go:128:26:128:28 | any | interface { } |
|
||||
| genericFunctions.go:132:6:132:73 | type declaration specifier | TypeSpec | 0 | genericFunctions.go:132:12:132:36 | type parameter declaration | 0 | genericFunctions.go:132:12:132:15 | Node | genericFunctions.go:132:17:132:36 | generic type instantiation expression | NodeConstraint |
|
||||
| genericFunctions.go:132:6:132:73 | type declaration specifier | TypeSpec | 1 | genericFunctions.go:132:39:132:63 | type parameter declaration | 0 | genericFunctions.go:132:39:132:42 | Edge | genericFunctions.go:132:44:132:63 | generic type instantiation expression | EdgeConstraint |
|
||||
| genericFunctions.go:134:1:136:1 | function declaration | FuncDecl | 0 | genericFunctions.go:134:10:134:34 | type parameter declaration | 0 | genericFunctions.go:134:10:134:13 | Node | genericFunctions.go:134:15:134:34 | generic type instantiation expression | NodeConstraint |
|
||||
| genericFunctions.go:134:1:136:1 | function declaration | FuncDecl | 1 | genericFunctions.go:134:37:134:61 | type parameter declaration | 0 | genericFunctions.go:134:37:134:40 | Edge | genericFunctions.go:134:42:134:61 | generic type instantiation expression | EdgeConstraint |
|
|
@ -0,0 +1,6 @@
|
|||
import go
|
||||
|
||||
from TypeParamDeclParent x, int i, TypeParamDecl tpd, int j
|
||||
where tpd = x.getTypeParameterDecl(i)
|
||||
select x, x.getPrimaryQlClasses(), i, tpd, j, tpd.getNameExpr(j), tpd.getTypeConstraintExpr(),
|
||||
tpd.getTypeConstraint().pp()
|
|
@ -0,0 +1,6 @@
|
|||
module codeql-go-tests/function
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/anotherpkg v0.0.0-20200203000000-0000000000000
|
||||
|
1
ql/test/library-tests/semmle/go/Function/vendor/github.com/anotherpkg/README.md
сгенерированный
поставляемый
Normal file
1
ql/test/library-tests/semmle/go/Function/vendor/github.com/anotherpkg/README.md
сгенерированный
поставляемый
Normal file
|
@ -0,0 +1 @@
|
|||
This is a simple stub package, strictly for use in query testing.
|
6
ql/test/library-tests/semmle/go/Function/vendor/github.com/anotherpkg/anotherpkg.go
сгенерированный
поставляемый
Normal file
6
ql/test/library-tests/semmle/go/Function/vendor/github.com/anotherpkg/anotherpkg.go
сгенерированный
поставляемый
Normal file
|
@ -0,0 +1,6 @@
|
|||
package anotherpkg
|
||||
|
||||
func GenericFunctionInAnotherPackage[T any](t T) T {
|
||||
var r T
|
||||
return r
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# github.com/anotherpkg v0.0.0-20200203000000-0000000000000
|
||||
## explicit; go 1.18
|
||||
github.com/anotherpkg
|
|
@ -12,6 +12,17 @@
|
|||
| embedded.go:8:3:8:5 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| embedded.go:13:2:13:4 | Qux | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| embedded.go:14:2:14:4 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:4:2:4:11 | valueField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:5:2:5:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:6:2:6:11 | arrayField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:7:2:7:11 | sliceField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:8:2:8:9 | mapField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:12:2:12:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:16:2:16:5 | root | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:20:2:20:12 | structField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:21:2:21:9 | mapField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:25:2:25:12 | structField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| generic.go:29:2:29:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/embedding.go:22:27:22:30 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/embedding.go:25:24:25:31 | embedder | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
|
|
|
@ -19,6 +19,17 @@
|
|||
| embedded.go:8:3:8:5 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | Baz |
|
||||
| embedded.go:13:2:13:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Qux |
|
||||
| embedded.go:14:2:14:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Baz |
|
||||
| generic.go:4:2:4:11 | valueField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | valueField |
|
||||
| generic.go:5:2:5:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | pointerField |
|
||||
| generic.go:6:2:6:11 | arrayField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | arrayField |
|
||||
| generic.go:7:2:7:11 | sliceField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | sliceField |
|
||||
| generic.go:8:2:8:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | mapField |
|
||||
| generic.go:12:2:12:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct1 | pointerField |
|
||||
| generic.go:16:2:16:5 | root | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.UsesCircularGenericStruct1 | root |
|
||||
| generic.go:20:2:20:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2 | structField |
|
||||
| generic.go:21:2:21:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2 | mapField |
|
||||
| generic.go:25:2:25:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2b | structField |
|
||||
| generic.go:29:2:29:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct2 | pointerField |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | base |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | base |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | base |
|
||||
|
|
|
@ -19,6 +19,17 @@
|
|||
| embedded.go:8:3:8:5 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Qux | Baz |
|
||||
| embedded.go:13:2:13:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Qux |
|
||||
| embedded.go:14:2:14:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Baz |
|
||||
| generic.go:4:2:4:11 | valueField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | valueField |
|
||||
| generic.go:5:2:5:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | pointerField |
|
||||
| generic.go:6:2:6:11 | arrayField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | arrayField |
|
||||
| generic.go:7:2:7:11 | sliceField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | sliceField |
|
||||
| generic.go:8:2:8:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | mapField |
|
||||
| generic.go:12:2:12:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | CircularGenericStruct1 | pointerField |
|
||||
| generic.go:16:2:16:5 | root | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | UsesCircularGenericStruct1 | root |
|
||||
| generic.go:20:2:20:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2 | structField |
|
||||
| generic.go:21:2:21:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2 | mapField |
|
||||
| generic.go:25:2:25:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2b | structField |
|
||||
| generic.go:29:2:29:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | CircularGenericStruct2 | pointerField |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | base |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | base |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | base |
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
| generic.go:12:16:12:40 | generic type instantiation expression | generic.go:12:16:12:37 | CircularGenericStruct1 | 0 | generic.go:12:39:12:39 | T |
|
||||
| generic.go:16:7:16:31 | generic type instantiation expression | generic.go:16:7:16:28 | CircularGenericStruct1 | 0 | generic.go:16:30:16:30 | T |
|
||||
| generic.go:20:14:20:30 | generic type instantiation expression | generic.go:20:14:20:27 | GenericStruct1 | 0 | generic.go:20:29:20:29 | S |
|
||||
| generic.go:25:14:25:33 | generic type instantiation expression | generic.go:25:14:25:27 | GenericStruct2 | 0 | generic.go:25:29:25:29 | S |
|
||||
| generic.go:25:14:25:33 | generic type instantiation expression | generic.go:25:14:25:27 | GenericStruct2 | 1 | generic.go:25:32:25:32 | T |
|
||||
| generic.go:29:16:29:43 | generic type instantiation expression | generic.go:29:16:29:37 | CircularGenericStruct2 | 0 | generic.go:29:39:29:39 | S |
|
||||
| generic.go:29:16:29:43 | generic type instantiation expression | generic.go:29:16:29:37 | CircularGenericStruct2 | 1 | generic.go:29:42:29:42 | T |
|
||||
| generic.go:48:10:48:23 | generic type instantiation expression | generic.go:48:10:48:20 | MyInterface | 0 | generic.go:48:22:48:22 | U |
|
||||
| generic.go:56:12:56:26 | generic type instantiation expression | generic.go:56:12:56:23 | GenericArray | 0 | generic.go:56:25:56:25 | U |
|
||||
| generic.go:57:12:57:28 | generic type instantiation expression | generic.go:57:12:57:25 | GenericPointer | 0 | generic.go:57:27:57:27 | U |
|
||||
| generic.go:58:12:58:26 | generic type instantiation expression | generic.go:58:12:58:23 | GenericSlice | 0 | generic.go:58:25:58:25 | U |
|
||||
| generic.go:59:12:59:25 | generic type instantiation expression | generic.go:59:12:59:22 | GenericMap1 | 0 | generic.go:59:24:59:24 | U |
|
||||
| generic.go:60:12:60:28 | generic type instantiation expression | generic.go:60:12:60:22 | GenericMap2 | 0 | generic.go:60:24:60:24 | U |
|
||||
| generic.go:60:12:60:28 | generic type instantiation expression | generic.go:60:12:60:22 | GenericMap2 | 1 | generic.go:60:27:60:27 | U |
|
||||
| generic.go:61:12:61:28 | generic type instantiation expression | generic.go:61:12:61:25 | GenericChannel | 0 | generic.go:61:27:61:27 | U |
|
||||
| generic.go:62:12:62:26 | generic type instantiation expression | generic.go:62:12:62:23 | GenericNamed | 0 | generic.go:62:25:62:25 | U |
|
||||
| generic.go:70:42:70:64 | generic type instantiation expression | generic.go:70:42:70:57 | GenericInterface | 0 | generic.go:70:59:70:63 | int32 |
|
||||
| generic.go:74:41:74:62 | generic type instantiation expression | generic.go:74:41:74:54 | GenericStruct1 | 0 | generic.go:74:56:74:61 | string |
|
||||
| generic.go:82:18:82:34 | generic type instantiation expression | generic.go:82:18:82:29 | GenericArray | 0 | generic.go:82:31:82:33 | int |
|
|
@ -0,0 +1,4 @@
|
|||
import go
|
||||
|
||||
from GenericTypeInstantiationExpr e, int i
|
||||
select e, e.getBase(), i, e.getTypeArgument(i)
|
|
@ -0,0 +1,21 @@
|
|||
import go
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class ImplementsComparableTest extends InlineExpectationsTest {
|
||||
ImplementsComparableTest() { this = "ImplementsComparableTest" }
|
||||
|
||||
override string getARelevantTag() { result = "implementsComparable" }
|
||||
|
||||
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
|
||||
// file = "interface.go" and
|
||||
tag = "implementsComparable" and
|
||||
exists(TypeSpec ts |
|
||||
ts.getName().matches("testComparable%") and
|
||||
ts.getATypeParameterDecl().getTypeConstraint().implementsComparable()
|
||||
|
|
||||
ts.hasLocationInfo(file, line, _, _, _) and
|
||||
element = ts.getName() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
|
@ -13,6 +13,8 @@
|
|||
| B | 2 |
|
||||
| C | 2 |
|
||||
| Foo | 1 |
|
||||
| GenericInterface | 1 |
|
||||
| MyInterface | 17 |
|
||||
| T | 1 |
|
||||
| T3 | 1 |
|
||||
| T4 | 1 |
|
||||
|
@ -20,4 +22,14 @@
|
|||
| embedder | 1 |
|
||||
| embedder2 | 1 |
|
||||
| embedder3 | 1 |
|
||||
| i6 | 1 |
|
||||
| i7 | 1 |
|
||||
| i8 | 2 |
|
||||
| i9 | 2 |
|
||||
| i14 | 2 |
|
||||
| i15 | 2 |
|
||||
| i17 | 1 |
|
||||
| i18 | 1 |
|
||||
| i19 | 1 |
|
||||
| i20 | 1 |
|
||||
| ptrembedder | 2 |
|
||||
|
|
|
@ -10,6 +10,24 @@
|
|||
| B | n | func() |
|
||||
| C | n | func() |
|
||||
| C | o | func() |
|
||||
| GenericInterface | GetT | func() T |
|
||||
| MyInterface | clone | func() MyInterface |
|
||||
| MyInterface | dummy1 | func() [10]U |
|
||||
| MyInterface | dummy2 | func() * U |
|
||||
| MyInterface | dummy3 | func() []U |
|
||||
| MyInterface | dummy4 | func() [U]U |
|
||||
| MyInterface | dummy5 | func() chan<- U |
|
||||
| MyInterface | dummy6 | func() MyMapType |
|
||||
| MyInterface | dummy7 | func() MyFuncType2 |
|
||||
| MyInterface | dummy11 | func() GenericArray |
|
||||
| MyInterface | dummy12 | func() GenericPointer |
|
||||
| MyInterface | dummy13 | func() GenericSlice |
|
||||
| MyInterface | dummy14 | func() GenericMap1 |
|
||||
| MyInterface | dummy15 | func() GenericMap2 |
|
||||
| MyInterface | dummy17 | func() GenericChannel |
|
||||
| MyInterface | dummy18 | func() GenericNamed |
|
||||
| MyInterface | dummy19 | func() MyFuncType1 |
|
||||
| MyInterface | dummy20 | func() MyFuncType2 |
|
||||
| T | half | func() Foo |
|
||||
| T3 | half | func() Foo |
|
||||
| T4 | half | func() Foo |
|
||||
|
@ -17,5 +35,19 @@
|
|||
| embedder2 | f | func() int |
|
||||
| embedder3 | f | func() int |
|
||||
| embedder4 | f | func() int |
|
||||
| i6 | String | func() string |
|
||||
| i7 | String | func() string |
|
||||
| i8 | String | func() string |
|
||||
| i8 | StringA | func() string |
|
||||
| i9 | String | func() string |
|
||||
| i9 | StringB | func() string |
|
||||
| i14 | String | func() string |
|
||||
| i14 | StringA | func() string |
|
||||
| i15 | String | func() string |
|
||||
| i15 | StringB | func() string |
|
||||
| i17 | StringA | func() string |
|
||||
| i18 | StringA | func() string |
|
||||
| i19 | StringB | func() string |
|
||||
| i20 | StringB | func() string |
|
||||
| ptrembedder | f | func() int |
|
||||
| ptrembedder | g | func() int |
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
| generic.go:33:2:33:5 | GetT | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericInterface | GetT |
|
||||
| generic.go:48:2:48:6 | clone | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | clone |
|
||||
| generic.go:49:2:49:7 | dummy1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy1 |
|
||||
| generic.go:50:2:50:7 | dummy2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy2 |
|
||||
| generic.go:51:2:51:7 | dummy3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy3 |
|
||||
| generic.go:52:2:52:7 | dummy4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy4 |
|
||||
| generic.go:53:2:53:7 | dummy5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy5 |
|
||||
| generic.go:54:2:54:7 | dummy6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy6 |
|
||||
| generic.go:55:2:55:7 | dummy7 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy7 |
|
||||
| generic.go:56:2:56:8 | dummy11 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy11 |
|
||||
| generic.go:57:2:57:8 | dummy12 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy12 |
|
||||
| generic.go:58:2:58:8 | dummy13 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy13 |
|
||||
| generic.go:59:2:59:8 | dummy14 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy14 |
|
||||
| generic.go:60:2:60:8 | dummy15 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy15 |
|
||||
| generic.go:61:2:61:8 | dummy17 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy17 |
|
||||
| generic.go:62:2:62:8 | dummy18 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy18 |
|
||||
| generic.go:63:2:63:8 | dummy19 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy19 |
|
||||
| generic.go:64:2:64:8 | dummy20 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy20 |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i6 | String |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i8 | String |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i9 | String |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i14 | String |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i15 | String |
|
||||
| interface.go:37:2:37:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i7 | String |
|
||||
| interface.go:43:2:43:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i8 | StringA |
|
||||
| interface.go:43:2:43:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i14 | StringA |
|
||||
| interface.go:49:2:49:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i9 | StringB |
|
||||
| interface.go:49:2:49:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i15 | StringB |
|
||||
| interface.go:92:2:92:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i17 | StringA |
|
||||
| interface.go:97:2:97:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i18 | StringA |
|
||||
| interface.go:102:2:102:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i19 | StringB |
|
||||
| interface.go:107:2:107:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i20 | StringB |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | base | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | f |
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
| generic.go:33:2:33:5 | GetT | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericInterface | GetT |
|
||||
| generic.go:48:2:48:6 | clone | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | clone |
|
||||
| generic.go:49:2:49:7 | dummy1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy1 |
|
||||
| generic.go:50:2:50:7 | dummy2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy2 |
|
||||
| generic.go:51:2:51:7 | dummy3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy3 |
|
||||
| generic.go:52:2:52:7 | dummy4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy4 |
|
||||
| generic.go:53:2:53:7 | dummy5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy5 |
|
||||
| generic.go:54:2:54:7 | dummy6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy6 |
|
||||
| generic.go:55:2:55:7 | dummy7 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy7 |
|
||||
| generic.go:56:2:56:8 | dummy11 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy11 |
|
||||
| generic.go:57:2:57:8 | dummy12 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy12 |
|
||||
| generic.go:58:2:58:8 | dummy13 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy13 |
|
||||
| generic.go:59:2:59:8 | dummy14 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy14 |
|
||||
| generic.go:60:2:60:8 | dummy15 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy15 |
|
||||
| generic.go:61:2:61:8 | dummy17 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy17 |
|
||||
| generic.go:62:2:62:8 | dummy18 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy18 |
|
||||
| generic.go:63:2:63:8 | dummy19 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy19 |
|
||||
| generic.go:64:2:64:8 | dummy20 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | MyInterface | dummy20 |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i6 | String |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i8 | String |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i9 | String |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i14 | String |
|
||||
| interface.go:30:2:30:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i15 | String |
|
||||
| interface.go:37:2:37:7 | String | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i7 | String |
|
||||
| interface.go:43:2:43:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i8 | StringA |
|
||||
| interface.go:43:2:43:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i14 | StringA |
|
||||
| interface.go:49:2:49:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i9 | StringB |
|
||||
| interface.go:49:2:49:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i15 | StringB |
|
||||
| interface.go:92:2:92:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i17 | StringA |
|
||||
| interface.go:97:2:97:8 | StringA | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i18 | StringA |
|
||||
| interface.go:102:2:102:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i19 | StringB |
|
||||
| interface.go:107:2:107:8 | StringB | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | i20 | StringB |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | base | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | f |
|
||||
|
|
|
@ -23,6 +23,24 @@
|
|||
| C | n | pkg1/interfaces.go:13:2:13:2 | n |
|
||||
| C | o | pkg1/interfaces.go:14:2:14:2 | o |
|
||||
| Foo | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
| GenericInterface | GetT | generic.go:33:2:33:5 | GetT |
|
||||
| MyInterface | clone | generic.go:48:2:48:6 | clone |
|
||||
| MyInterface | dummy1 | generic.go:49:2:49:7 | dummy1 |
|
||||
| MyInterface | dummy2 | generic.go:50:2:50:7 | dummy2 |
|
||||
| MyInterface | dummy3 | generic.go:51:2:51:7 | dummy3 |
|
||||
| MyInterface | dummy4 | generic.go:52:2:52:7 | dummy4 |
|
||||
| MyInterface | dummy5 | generic.go:53:2:53:7 | dummy5 |
|
||||
| MyInterface | dummy6 | generic.go:54:2:54:7 | dummy6 |
|
||||
| MyInterface | dummy7 | generic.go:55:2:55:7 | dummy7 |
|
||||
| MyInterface | dummy11 | generic.go:56:2:56:8 | dummy11 |
|
||||
| MyInterface | dummy12 | generic.go:57:2:57:8 | dummy12 |
|
||||
| MyInterface | dummy13 | generic.go:58:2:58:8 | dummy13 |
|
||||
| MyInterface | dummy14 | generic.go:59:2:59:8 | dummy14 |
|
||||
| MyInterface | dummy15 | generic.go:60:2:60:8 | dummy15 |
|
||||
| MyInterface | dummy17 | generic.go:61:2:61:8 | dummy17 |
|
||||
| MyInterface | dummy18 | generic.go:62:2:62:8 | dummy18 |
|
||||
| MyInterface | dummy19 | generic.go:63:2:63:8 | dummy19 |
|
||||
| MyInterface | dummy20 | generic.go:64:2:64:8 | dummy20 |
|
||||
| T | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
| T3 | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
| T4 | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
|
@ -30,5 +48,19 @@
|
|||
| embedder | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| embedder2 | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| embedder3 | f | pkg1/embedding.go:30:18:30:18 | f |
|
||||
| i6 | String | interface.go:30:2:30:7 | String |
|
||||
| i7 | String | interface.go:37:2:37:7 | String |
|
||||
| i8 | String | interface.go:30:2:30:7 | String |
|
||||
| i8 | StringA | interface.go:43:2:43:8 | StringA |
|
||||
| i9 | String | interface.go:30:2:30:7 | String |
|
||||
| i9 | StringB | interface.go:49:2:49:8 | StringB |
|
||||
| i14 | String | interface.go:30:2:30:7 | String |
|
||||
| i14 | StringA | interface.go:43:2:43:8 | StringA |
|
||||
| i15 | String | interface.go:30:2:30:7 | String |
|
||||
| i15 | StringB | interface.go:49:2:49:8 | StringB |
|
||||
| i17 | StringA | interface.go:92:2:92:8 | StringA |
|
||||
| i18 | StringA | interface.go:97:2:97:8 | StringA |
|
||||
| i19 | StringB | interface.go:102:2:102:8 | StringB |
|
||||
| i20 | StringB | interface.go:107:2:107:8 | StringB |
|
||||
| ptrembedder | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| ptrembedder | g | pkg1/embedding.go:14:14:14:14 | g |
|
||||
|
|
|
@ -7,15 +7,36 @@
|
|||
| Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar |
|
||||
| Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Baz |
|
||||
| C | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.C |
|
||||
| CircularGenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct1 |
|
||||
| CircularGenericStruct2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct2 |
|
||||
| EmbedsBaz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz |
|
||||
| Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo |
|
||||
| G | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G |
|
||||
| GenericArray | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericArray |
|
||||
| GenericChannel | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericChannel |
|
||||
| GenericInterface | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericInterface |
|
||||
| GenericMap1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericMap1 |
|
||||
| GenericMap2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericMap2 |
|
||||
| GenericNamed | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericNamed |
|
||||
| GenericPointer | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericPointer |
|
||||
| GenericSignature | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericSignature |
|
||||
| GenericSlice | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericSlice |
|
||||
| GenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 |
|
||||
| GenericStruct2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2 |
|
||||
| GenericStruct2b | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2b |
|
||||
| HasBlankTypeParam | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.HasBlankTypeParam |
|
||||
| HasBlankTypeParams | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.HasBlankTypeParams |
|
||||
| MyFuncType1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyFuncType1 |
|
||||
| MyFuncType2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyFuncType2 |
|
||||
| MyInterface | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyInterface |
|
||||
| MyMapType | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.MyMapType |
|
||||
| Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux |
|
||||
| T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T |
|
||||
| T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T |
|
||||
| T2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 |
|
||||
| T3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 |
|
||||
| T4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 |
|
||||
| UsesCircularGenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.UsesCircularGenericStruct1 |
|
||||
| a | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.a |
|
||||
| b | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.b |
|
||||
| base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.base |
|
||||
|
@ -25,8 +46,54 @@
|
|||
| embedder2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 |
|
||||
| embedder3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 |
|
||||
| embedder4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder4 |
|
||||
| i0 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i0 |
|
||||
| i1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i1 |
|
||||
| i2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i2 |
|
||||
| i3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i3 |
|
||||
| i4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i4 |
|
||||
| i5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i5 |
|
||||
| i6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i6 |
|
||||
| i7 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i7 |
|
||||
| i8 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i8 |
|
||||
| i9 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i9 |
|
||||
| i10 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i10 |
|
||||
| i11 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i11 |
|
||||
| i12 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i12 |
|
||||
| i13 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i13 |
|
||||
| i14 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i14 |
|
||||
| i15 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i15 |
|
||||
| i16 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i16 |
|
||||
| i17 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i17 |
|
||||
| i18 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i18 |
|
||||
| i19 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i19 |
|
||||
| i20 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.i20 |
|
||||
| ptrembedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.ptrembedder |
|
||||
| s | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.s |
|
||||
| t | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.t |
|
||||
| testComparable | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable |
|
||||
| testComparable0 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable0 |
|
||||
| testComparable1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable1 |
|
||||
| testComparable2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable2 |
|
||||
| testComparable3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable3 |
|
||||
| testComparable4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable4 |
|
||||
| testComparable5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable5 |
|
||||
| testComparable6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable6 |
|
||||
| testComparable7 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable7 |
|
||||
| testComparable8 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable8 |
|
||||
| testComparable9 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable9 |
|
||||
| testComparable10 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable10 |
|
||||
| testComparable11 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable11 |
|
||||
| testComparable12 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable12 |
|
||||
| testComparable13 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable13 |
|
||||
| testComparable14 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable14 |
|
||||
| testComparable15 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable15 |
|
||||
| testComparable16 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable16 |
|
||||
| testComparable17 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable17 |
|
||||
| testComparable18 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable18 |
|
||||
| testComparable19 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable19 |
|
||||
| testComparable20 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable20 |
|
||||
| testComparable21 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable21 |
|
||||
| testComparable22 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable22 |
|
||||
| testComparable23 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable23 |
|
||||
| u | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.u |
|
||||
| v | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.v |
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
| depth.go:22:1:25:1 | function declaration | 0 |
|
||||
| generic.go:70:1:72:1 | function declaration | 1 |
|
||||
| generic.go:74:1:80:1 | function declaration | 1 |
|
||||
| main.go:5:1:5:30 | function declaration | 1 |
|
||||
| main.go:7:1:9:1 | function declaration | 2 |
|
||||
| main.go:11:1:11:14 | function declaration | 0 |
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
| depth.go:22:1:25:1 | function declaration | 0 |
|
||||
| generic.go:70:1:72:1 | function declaration | 1 |
|
||||
| generic.go:74:1:80:1 | function declaration | 0 |
|
||||
| main.go:5:1:5:30 | function declaration | 0 |
|
||||
| main.go:7:1:9:1 | function declaration | 2 |
|
||||
| main.go:11:1:11:14 | function declaration | 0 |
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
| Bar | pkg1/tst.go:29:10:31:1 | struct type | flag | bool |
|
||||
| Baz | embedded.go:3:10:5:1 | struct type | A | string |
|
||||
| CircularGenericStruct1 | generic.go:11:38:13:1 | struct type | pointerField | * CircularGenericStruct1 |
|
||||
| CircularGenericStruct2 | generic.go:28:39:30:1 | struct type | pointerField | * CircularGenericStruct2 |
|
||||
| EmbedsBaz | embedded.go:12:16:15:1 | struct type | Baz | string |
|
||||
| EmbedsBaz | embedded.go:12:16:15:1 | struct type | Qux | Qux |
|
||||
| Foo | pkg1/tst.go:24:10:27:1 | struct type | flag | bool |
|
||||
| Foo | pkg1/tst.go:24:10:27:1 | struct type | val | int |
|
||||
| G | pkg2/tst.go:3:8:5:1 | struct type | g | int |
|
||||
| G | pkg2/tst.go:7:8:9:1 | struct type | g | int |
|
||||
| GenericStruct1 | generic.go:3:28:9:1 | struct type | arrayField | [10]T |
|
||||
| GenericStruct1 | generic.go:3:28:9:1 | struct type | mapField | [string]T |
|
||||
| GenericStruct1 | generic.go:3:28:9:1 | struct type | pointerField | * T |
|
||||
| GenericStruct1 | generic.go:3:28:9:1 | struct type | sliceField | []T |
|
||||
| GenericStruct1 | generic.go:3:28:9:1 | struct type | valueField | T |
|
||||
| GenericStruct2 | generic.go:19:42:22:1 | struct type | mapField | [S]T |
|
||||
| GenericStruct2 | generic.go:19:42:22:1 | struct type | structField | GenericStruct1 |
|
||||
| GenericStruct2b | generic.go:24:39:26:1 | struct type | structField | GenericStruct2 |
|
||||
| Qux | embedded.go:7:10:9:1 | struct type | A | string |
|
||||
| Qux | embedded.go:7:10:9:1 | struct type | Baz | * Baz |
|
||||
| T | pkg1/tst.go:3:8:7:1 | struct type | Bar | Bar |
|
||||
|
@ -24,6 +34,7 @@
|
|||
| T4 | pkg1/tst.go:19:9:22:1 | struct type | Foo | * Foo |
|
||||
| T4 | pkg1/tst.go:19:9:22:1 | struct type | flag | bool |
|
||||
| T4 | pkg1/tst.go:19:9:22:1 | struct type | val | int |
|
||||
| UsesCircularGenericStruct1 | generic.go:15:42:17:1 | struct type | root | CircularGenericStruct1 |
|
||||
| a | depth.go:5:8:8:1 | struct type | b | b |
|
||||
| a | depth.go:5:8:8:1 | struct type | c | c |
|
||||
| a | depth.go:5:8:8:1 | struct type | d | d |
|
||||
|
|
|
@ -7,15 +7,36 @@
|
|||
| Bar | Bar |
|
||||
| Baz | Baz |
|
||||
| C | C |
|
||||
| CircularGenericStruct1 | CircularGenericStruct1 |
|
||||
| CircularGenericStruct2 | CircularGenericStruct2 |
|
||||
| EmbedsBaz | EmbedsBaz |
|
||||
| Foo | Foo |
|
||||
| G | G |
|
||||
| GenericArray | GenericArray |
|
||||
| GenericChannel | GenericChannel |
|
||||
| GenericInterface | GenericInterface |
|
||||
| GenericMap1 | GenericMap1 |
|
||||
| GenericMap2 | GenericMap2 |
|
||||
| GenericNamed | GenericNamed |
|
||||
| GenericPointer | GenericPointer |
|
||||
| GenericSignature | GenericSignature |
|
||||
| GenericSlice | GenericSlice |
|
||||
| GenericStruct1 | GenericStruct1 |
|
||||
| GenericStruct2 | GenericStruct2 |
|
||||
| GenericStruct2b | GenericStruct2b |
|
||||
| HasBlankTypeParam | HasBlankTypeParam |
|
||||
| HasBlankTypeParams | HasBlankTypeParams |
|
||||
| MyFuncType1 | MyFuncType1 |
|
||||
| MyFuncType2 | MyFuncType2 |
|
||||
| MyInterface | MyInterface |
|
||||
| MyMapType | MyMapType |
|
||||
| Qux | Qux |
|
||||
| T | T |
|
||||
| T | T |
|
||||
| T2 | T2 |
|
||||
| T3 | T3 |
|
||||
| T4 | T4 |
|
||||
| UsesCircularGenericStruct1 | UsesCircularGenericStruct1 |
|
||||
| a | a |
|
||||
| b | b |
|
||||
| base | base |
|
||||
|
@ -25,8 +46,54 @@
|
|||
| embedder2 | embedder2 |
|
||||
| embedder3 | embedder3 |
|
||||
| embedder4 | embedder4 |
|
||||
| i0 | i0 |
|
||||
| i1 | i1 |
|
||||
| i2 | i2 |
|
||||
| i3 | i3 |
|
||||
| i4 | i4 |
|
||||
| i5 | i5 |
|
||||
| i6 | i6 |
|
||||
| i7 | i7 |
|
||||
| i8 | i8 |
|
||||
| i9 | i9 |
|
||||
| i10 | i10 |
|
||||
| i11 | i11 |
|
||||
| i12 | i12 |
|
||||
| i13 | i13 |
|
||||
| i14 | i14 |
|
||||
| i15 | i15 |
|
||||
| i16 | i16 |
|
||||
| i17 | i17 |
|
||||
| i18 | i18 |
|
||||
| i19 | i19 |
|
||||
| i20 | i20 |
|
||||
| ptrembedder | ptrembedder |
|
||||
| s | s |
|
||||
| t | t |
|
||||
| testComparable | testComparable |
|
||||
| testComparable0 | testComparable0 |
|
||||
| testComparable1 | testComparable1 |
|
||||
| testComparable2 | testComparable2 |
|
||||
| testComparable3 | testComparable3 |
|
||||
| testComparable4 | testComparable4 |
|
||||
| testComparable5 | testComparable5 |
|
||||
| testComparable6 | testComparable6 |
|
||||
| testComparable7 | testComparable7 |
|
||||
| testComparable8 | testComparable8 |
|
||||
| testComparable9 | testComparable9 |
|
||||
| testComparable10 | testComparable10 |
|
||||
| testComparable11 | testComparable11 |
|
||||
| testComparable12 | testComparable12 |
|
||||
| testComparable13 | testComparable13 |
|
||||
| testComparable14 | testComparable14 |
|
||||
| testComparable15 | testComparable15 |
|
||||
| testComparable16 | testComparable16 |
|
||||
| testComparable17 | testComparable17 |
|
||||
| testComparable18 | testComparable18 |
|
||||
| testComparable19 | testComparable19 |
|
||||
| testComparable20 | testComparable20 |
|
||||
| testComparable21 | testComparable21 |
|
||||
| testComparable22 | testComparable22 |
|
||||
| testComparable23 | testComparable23 |
|
||||
| u | u |
|
||||
| v | v |
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package main
|
||||
|
||||
type GenericStruct1[T any] struct {
|
||||
valueField T
|
||||
pointerField *T
|
||||
arrayField [10]T
|
||||
sliceField []T
|
||||
mapField map[string]T
|
||||
}
|
||||
|
||||
type CircularGenericStruct1[T error] struct {
|
||||
pointerField *CircularGenericStruct1[T]
|
||||
}
|
||||
|
||||
type UsesCircularGenericStruct1[T error] struct {
|
||||
root CircularGenericStruct1[T]
|
||||
}
|
||||
|
||||
type GenericStruct2[S comparable, T int] struct {
|
||||
structField GenericStruct1[S]
|
||||
mapField map[S]T
|
||||
}
|
||||
|
||||
type GenericStruct2b[S string, T int] struct {
|
||||
structField GenericStruct2[S, T]
|
||||
}
|
||||
|
||||
type CircularGenericStruct2[S, T any] struct {
|
||||
pointerField *CircularGenericStruct2[S, T]
|
||||
}
|
||||
|
||||
type GenericInterface[T ~int32 | ~int64] interface {
|
||||
GetT() T
|
||||
}
|
||||
|
||||
type GenericArray[T comparable] [10]T
|
||||
type GenericPointer[T any] *T
|
||||
type GenericSlice[T any] []T
|
||||
type GenericMap1[V any] map[string]V
|
||||
type GenericMap2[K comparable, V any] map[K]V
|
||||
type GenericChannel[T comparable] chan<- T
|
||||
type MyMapType map[string]int
|
||||
type GenericNamed[T comparable] MyMapType
|
||||
type MyFuncType1[T any] func(T)
|
||||
type MyFuncType2[T1 any, T2 any] func(T1) T2
|
||||
|
||||
type MyInterface[U comparable] interface {
|
||||
clone() MyInterface[U]
|
||||
dummy1() [10]U
|
||||
dummy2() *U
|
||||
dummy3() []U
|
||||
dummy4() map[U]U
|
||||
dummy5() chan<- U
|
||||
dummy6() MyMapType
|
||||
dummy7() MyFuncType2[int, bool]
|
||||
dummy11() GenericArray[U]
|
||||
dummy12() GenericPointer[U]
|
||||
dummy13() GenericSlice[U]
|
||||
dummy14() GenericMap1[U]
|
||||
dummy15() GenericMap2[U, U]
|
||||
dummy17() GenericChannel[U]
|
||||
dummy18() GenericNamed[U]
|
||||
dummy19() MyFuncType1[U]
|
||||
dummy20() MyFuncType2[U, U]
|
||||
}
|
||||
|
||||
type HasBlankTypeParam[_ any] struct{}
|
||||
type HasBlankTypeParams[_ any, _ comparable, T ~string] struct{}
|
||||
|
||||
func callMethodOnInstantiatedInterface(x GenericInterface[int32]) int32 {
|
||||
return x.GetT()
|
||||
}
|
||||
|
||||
func accessFieldsOfInstantiatedStruct(x GenericStruct1[string]) {
|
||||
_ = x.valueField
|
||||
_ = x.pointerField
|
||||
_ = x.arrayField
|
||||
_ = x.sliceField
|
||||
_ = x.mapField
|
||||
}
|
||||
|
||||
type TypeAlias = GenericArray[int]
|
||||
|
||||
type GenericSignature[T any] func(t T) T
|
||||
type GenericSignatureAlias = GenericSignature[string]
|
|
@ -0,0 +1,134 @@
|
|||
package main
|
||||
|
||||
type i0 comparable
|
||||
|
||||
type i1 interface {
|
||||
int
|
||||
}
|
||||
|
||||
type i2 interface {
|
||||
~string
|
||||
}
|
||||
|
||||
type i3 interface {
|
||||
[5]int | ~string
|
||||
}
|
||||
|
||||
// typeset: int | ~string | float32
|
||||
type i4 interface {
|
||||
i1 | i2 | float32
|
||||
}
|
||||
|
||||
// typeset: []byte
|
||||
type i5 interface {
|
||||
int | ~[]byte
|
||||
[]byte
|
||||
}
|
||||
|
||||
type i6 interface {
|
||||
~[]int | ~string
|
||||
String() string
|
||||
}
|
||||
|
||||
// typeset: ~string
|
||||
type i7 interface {
|
||||
i3
|
||||
~string
|
||||
String() string
|
||||
}
|
||||
|
||||
// typeset: ~[]int | ~string
|
||||
type i8 interface {
|
||||
i6
|
||||
StringA() string
|
||||
}
|
||||
|
||||
// typeset: ~[]int | ~string
|
||||
type i9 interface {
|
||||
i6
|
||||
StringB() string
|
||||
}
|
||||
|
||||
type i10 interface {
|
||||
comparable
|
||||
}
|
||||
|
||||
// typeset: the empty set
|
||||
type i11 interface {
|
||||
[5]byte | string
|
||||
int
|
||||
}
|
||||
|
||||
// typeset: []byte | string
|
||||
type i12 interface {
|
||||
[]byte | string
|
||||
comparable
|
||||
}
|
||||
|
||||
// typeset: []byte | string
|
||||
type i13 interface {
|
||||
[]byte | string
|
||||
i10
|
||||
}
|
||||
|
||||
// typeset: string
|
||||
type i14 interface {
|
||||
[]byte | string
|
||||
i8
|
||||
}
|
||||
|
||||
// typeset: string
|
||||
type i15 interface {
|
||||
[]byte | string
|
||||
i9
|
||||
}
|
||||
|
||||
// The empty interface does not implement comparable
|
||||
type i16 interface {
|
||||
}
|
||||
|
||||
// A basic interface, so not comparable
|
||||
type i17 interface {
|
||||
StringA() string
|
||||
}
|
||||
|
||||
type i18 interface {
|
||||
comparable
|
||||
StringA() string
|
||||
}
|
||||
|
||||
// A basic interface, so not comparable
|
||||
type i19 interface {
|
||||
StringB() string
|
||||
}
|
||||
|
||||
type i20 interface {
|
||||
comparable
|
||||
StringB() string
|
||||
}
|
||||
|
||||
type testComparable[T comparable] struct{} // $ implementsComparable
|
||||
type testComparable0[T0 i0] struct{} // $ implementsComparable
|
||||
type testComparable1[T1 i1] struct{} // $ implementsComparable
|
||||
type testComparable2[T2 i2] struct{} // $ implementsComparable
|
||||
type testComparable3[T3 i3] struct{} // $ implementsComparable
|
||||
type testComparable4[T4 i4] struct{} // $ implementsComparable
|
||||
type testComparable5[T5 i5] struct{} // does not implement comparable
|
||||
type testComparable6[T6 i6] struct{} // does not implement comparable
|
||||
type testComparable7[T7 i7] struct{} // $ implementsComparable
|
||||
type testComparable8[T8 i8] struct{} // does not implement comparable
|
||||
type testComparable9[T9 i9] struct{} // does not implement comparable
|
||||
type testComparable10[T10 i10] struct{} // $ implementsComparable
|
||||
type testComparable11[T11 i11] struct{} // $ implementsComparable
|
||||
type testComparable12[T12 i12] struct{} // does not implement comparable
|
||||
type testComparable13[T13 i13] struct{} // does not implement comparable
|
||||
type testComparable14[T14 i14] struct{} // $ implementsComparable
|
||||
type testComparable15[T15 i15] struct{} // $ implementsComparable
|
||||
type testComparable16[T16 i16] struct{} // does not implement comparable
|
||||
type testComparable17[T17 i17] struct{} // does not implement comparable
|
||||
type testComparable18[T18 i18] struct{} // $ implementsComparable
|
||||
type testComparable19[T19 i19] struct{} // does not implement comparable
|
||||
type testComparable20[T20 i20] struct{} // $ implementsComparable
|
||||
type testComparable21[T21 ~[]byte | string] struct{} // does not implement comparable
|
||||
type testComparable22[T22 any] struct{} // does not implement comparable
|
||||
type testComparable23[T23 ~[5]byte | string] struct{} // $ implementsComparable
|
|
@ -496,6 +496,111 @@ edges
|
|||
| exprs.go:94:16:94:16 | (...) is false | exprs.go:94:21:94:21 | z |
|
||||
| exprs.go:94:16:94:16 | (...) is true | exprs.go:94:9:94:21 | ...\|\|... |
|
||||
| exprs.go:94:21:94:21 | z | exprs.go:94:9:94:21 | ...\|\|... |
|
||||
| generic.go:0:0:0:0 | entry | generic.go:3:1:5:1 | skip |
|
||||
| generic.go:3:1:5:1 | skip | generic.go:7:28:7:35 | skip |
|
||||
| generic.go:7:1:7:1 | entry | generic.go:7:7:7:7 | argument corresponding to g |
|
||||
| generic.go:7:1:7:55 | function declaration | generic.go:9:1:12:1 | skip |
|
||||
| generic.go:7:7:7:7 | argument corresponding to g | generic.go:7:7:7:7 | initialization of g |
|
||||
| generic.go:7:7:7:7 | initialization of g | generic.go:7:37:7:37 | argument corresponding to u |
|
||||
| generic.go:7:28:7:35 | skip | generic.go:7:1:7:55 | function declaration |
|
||||
| generic.go:7:37:7:37 | argument corresponding to u | generic.go:7:37:7:37 | initialization of u |
|
||||
| generic.go:7:37:7:37 | initialization of u | generic.go:7:53:7:53 | u |
|
||||
| generic.go:7:46:7:53 | return statement | generic.go:7:55:7:55 | exit |
|
||||
| generic.go:7:53:7:53 | u | generic.go:7:46:7:53 | return statement |
|
||||
| generic.go:9:1:12:1 | skip | generic.go:14:31:14:39 | skip |
|
||||
| generic.go:14:1:14:1 | entry | generic.go:14:7:14:7 | argument corresponding to g |
|
||||
| generic.go:14:1:14:59 | function declaration | generic.go:16:6:16:21 | skip |
|
||||
| generic.go:14:7:14:7 | argument corresponding to g | generic.go:14:7:14:7 | initialization of g |
|
||||
| generic.go:14:7:14:7 | initialization of g | generic.go:14:41:14:41 | argument corresponding to u |
|
||||
| generic.go:14:31:14:39 | skip | generic.go:14:1:14:59 | function declaration |
|
||||
| generic.go:14:41:14:41 | argument corresponding to u | generic.go:14:41:14:41 | initialization of u |
|
||||
| generic.go:14:41:14:41 | initialization of u | generic.go:14:57:14:57 | u |
|
||||
| generic.go:14:50:14:57 | return statement | generic.go:14:59:14:59 | exit |
|
||||
| generic.go:14:57:14:57 | u | generic.go:14:50:14:57 | return statement |
|
||||
| generic.go:16:1:16:1 | entry | generic.go:16:30:16:30 | argument corresponding to t |
|
||||
| generic.go:16:1:18:1 | function declaration | generic.go:20:6:20:21 | skip |
|
||||
| generic.go:16:6:16:21 | skip | generic.go:16:1:18:1 | function declaration |
|
||||
| generic.go:16:30:16:30 | argument corresponding to t | generic.go:16:30:16:30 | initialization of t |
|
||||
| generic.go:16:30:16:30 | initialization of t | generic.go:17:9:17:9 | t |
|
||||
| generic.go:17:2:17:9 | return statement | generic.go:18:1:18:1 | exit |
|
||||
| generic.go:17:9:17:9 | t | generic.go:17:2:17:9 | return statement |
|
||||
| generic.go:20:1:20:1 | entry | generic.go:20:33:20:33 | argument corresponding to s |
|
||||
| generic.go:20:1:22:1 | function declaration | generic.go:24:6:24:12 | skip |
|
||||
| generic.go:20:6:20:21 | skip | generic.go:20:1:22:1 | function declaration |
|
||||
| generic.go:20:33:20:33 | argument corresponding to s | generic.go:20:33:20:33 | initialization of s |
|
||||
| generic.go:20:33:20:33 | initialization of s | generic.go:20:38:20:38 | argument corresponding to t |
|
||||
| generic.go:20:38:20:38 | argument corresponding to t | generic.go:20:38:20:38 | initialization of t |
|
||||
| generic.go:20:38:20:38 | initialization of t | generic.go:21:9:21:9 | s |
|
||||
| generic.go:21:2:21:12 | return statement | generic.go:22:1:22:1 | exit |
|
||||
| generic.go:21:9:21:9 | s | generic.go:21:12:21:12 | t |
|
||||
| generic.go:21:12:21:12 | t | generic.go:21:2:21:12 | return statement |
|
||||
| generic.go:24:1:24:1 | entry | generic.go:25:2:25:4 | skip |
|
||||
| generic.go:24:1:35:1 | function declaration | generic.go:0:0:0:0 | exit |
|
||||
| generic.go:24:6:24:12 | skip | generic.go:24:1:35:1 | function declaration |
|
||||
| generic.go:25:2:25:4 | assignment to gs1 | generic.go:26:2:26:2 | skip |
|
||||
| generic.go:25:2:25:4 | skip | generic.go:25:9:25:35 | struct literal |
|
||||
| generic.go:25:9:25:35 | struct literal | generic.go:25:32:25:34 | "x" |
|
||||
| generic.go:25:32:25:34 | "x" | generic.go:25:32:25:34 | init of "x" |
|
||||
| generic.go:25:32:25:34 | init of "x" | generic.go:25:2:25:4 | assignment to gs1 |
|
||||
| generic.go:26:2:26:2 | assignment to a | generic.go:27:2:27:4 | skip |
|
||||
| generic.go:26:2:26:2 | skip | generic.go:26:7:26:9 | gs1 |
|
||||
| generic.go:26:7:26:9 | gs1 | generic.go:26:7:26:18 | selection of Identity |
|
||||
| generic.go:26:7:26:18 | selection of Identity | generic.go:26:20:26:26 | "hello" |
|
||||
| generic.go:26:7:26:27 | call to Identity | generic.go:26:2:26:2 | assignment to a |
|
||||
| generic.go:26:7:26:27 | call to Identity | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:26:20:26:26 | "hello" | generic.go:26:7:26:27 | call to Identity |
|
||||
| generic.go:27:2:27:4 | assignment to gs2 | generic.go:28:2:28:2 | skip |
|
||||
| generic.go:27:2:27:4 | skip | generic.go:27:9:27:48 | struct literal |
|
||||
| generic.go:27:9:27:48 | struct literal | generic.go:27:40:27:42 | "y" |
|
||||
| generic.go:27:40:27:42 | "y" | generic.go:27:40:27:42 | init of "y" |
|
||||
| generic.go:27:40:27:42 | init of "y" | generic.go:27:45:27:47 | "z" |
|
||||
| generic.go:27:45:27:47 | "z" | generic.go:27:45:27:47 | init of "z" |
|
||||
| generic.go:27:45:27:47 | init of "z" | generic.go:27:2:27:4 | assignment to gs2 |
|
||||
| generic.go:28:2:28:2 | assignment to b | generic.go:29:2:29:2 | skip |
|
||||
| generic.go:28:2:28:2 | skip | generic.go:28:7:28:9 | gs2 |
|
||||
| generic.go:28:7:28:9 | gs2 | generic.go:28:7:28:19 | selection of Identity1 |
|
||||
| generic.go:28:7:28:19 | selection of Identity1 | generic.go:28:21:28:21 | a |
|
||||
| generic.go:28:7:28:22 | call to Identity1 | generic.go:28:2:28:2 | assignment to b |
|
||||
| generic.go:28:7:28:22 | call to Identity1 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:28:21:28:21 | a | generic.go:28:7:28:22 | call to Identity1 |
|
||||
| generic.go:29:2:29:2 | assignment to c | generic.go:30:2:30:2 | skip |
|
||||
| generic.go:29:2:29:2 | skip | generic.go:29:7:29:22 | genericIdentity1 |
|
||||
| generic.go:29:7:29:22 | genericIdentity1 | generic.go:29:32:29:32 | b |
|
||||
| generic.go:29:7:29:33 | call to genericIdentity1 | generic.go:29:2:29:2 | assignment to c |
|
||||
| generic.go:29:7:29:33 | call to genericIdentity1 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:29:32:29:32 | b | generic.go:29:7:29:33 | call to genericIdentity1 |
|
||||
| generic.go:30:2:30:2 | assignment to d | generic.go:31:2:31:2 | skip |
|
||||
| generic.go:30:2:30:2 | skip | generic.go:30:7:30:22 | genericIdentity1 |
|
||||
| generic.go:30:7:30:22 | genericIdentity1 | generic.go:30:24:30:24 | c |
|
||||
| generic.go:30:7:30:25 | call to genericIdentity1 | generic.go:30:2:30:2 | assignment to d |
|
||||
| generic.go:30:7:30:25 | call to genericIdentity1 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:30:24:30:24 | c | generic.go:30:7:30:25 | call to genericIdentity1 |
|
||||
| generic.go:31:2:31:2 | assignment to e | generic.go:31:2:31:53 | ... := ...[1] |
|
||||
| generic.go:31:2:31:2 | skip | generic.go:31:5:31:5 | skip |
|
||||
| generic.go:31:2:31:53 | ... := ...[0] | generic.go:31:2:31:2 | assignment to e |
|
||||
| generic.go:31:2:31:53 | ... := ...[1] | generic.go:31:5:31:5 | assignment to f |
|
||||
| generic.go:31:5:31:5 | assignment to f | generic.go:32:2:32:2 | skip |
|
||||
| generic.go:31:5:31:5 | skip | generic.go:31:10:31:25 | genericIdentity2 |
|
||||
| generic.go:31:10:31:25 | genericIdentity2 | generic.go:31:43:31:43 | d |
|
||||
| generic.go:31:10:31:53 | call to genericIdentity2 | generic.go:31:2:31:53 | ... := ...[0] |
|
||||
| generic.go:31:10:31:53 | call to genericIdentity2 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:31:43:31:43 | d | generic.go:31:46:31:52 | "hello" |
|
||||
| generic.go:31:46:31:52 | "hello" | generic.go:31:10:31:53 | call to genericIdentity2 |
|
||||
| generic.go:32:2:32:2 | assignment to g | generic.go:32:2:32:31 | ... := ...[1] |
|
||||
| generic.go:32:2:32:2 | skip | generic.go:32:5:32:5 | skip |
|
||||
| generic.go:32:2:32:31 | ... := ...[0] | generic.go:32:2:32:2 | assignment to g |
|
||||
| generic.go:32:2:32:31 | ... := ...[1] | generic.go:32:5:32:5 | assignment to h |
|
||||
| generic.go:32:5:32:5 | assignment to h | generic.go:33:2:33:2 | skip |
|
||||
| generic.go:32:5:32:5 | skip | generic.go:32:10:32:25 | genericIdentity2 |
|
||||
| generic.go:32:10:32:25 | genericIdentity2 | generic.go:32:27:32:27 | e |
|
||||
| generic.go:32:10:32:31 | call to genericIdentity2 | generic.go:32:2:32:31 | ... := ...[0] |
|
||||
| generic.go:32:10:32:31 | call to genericIdentity2 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:32:27:32:27 | e | generic.go:32:30:32:30 | f |
|
||||
| generic.go:32:30:32:30 | f | generic.go:32:10:32:31 | call to genericIdentity2 |
|
||||
| generic.go:33:2:33:2 | skip | generic.go:33:6:33:6 | g |
|
||||
| generic.go:33:6:33:6 | g | generic.go:34:2:34:2 | skip |
|
||||
| generic.go:34:2:34:2 | skip | generic.go:34:6:34:6 | h |
|
||||
| generic.go:34:6:34:6 | h | generic.go:35:1:35:1 | exit |
|
||||
| hello.go:0:0:0:0 | entry | hello.go:3:1:3:12 | skip |
|
||||
| hello.go:3:1:3:12 | skip | hello.go:5:7:5:13 | skip |
|
||||
| hello.go:5:7:5:13 | assignment to message | hello.go:7:6:7:13 | skip |
|
||||
|
|
|
@ -495,6 +495,111 @@
|
|||
| exprs.go:94:16:94:16 | (...) is false | exprs.go:94:21:94:21 | z |
|
||||
| exprs.go:94:16:94:16 | (...) is true | exprs.go:94:9:94:21 | ...\|\|... |
|
||||
| exprs.go:94:21:94:21 | z | exprs.go:94:9:94:21 | ...\|\|... |
|
||||
| generic.go:0:0:0:0 | entry | generic.go:3:1:5:1 | skip |
|
||||
| generic.go:3:1:5:1 | skip | generic.go:7:28:7:35 | skip |
|
||||
| generic.go:7:1:7:1 | entry | generic.go:7:7:7:7 | argument corresponding to g |
|
||||
| generic.go:7:1:7:55 | function declaration | generic.go:9:1:12:1 | skip |
|
||||
| generic.go:7:7:7:7 | argument corresponding to g | generic.go:7:7:7:7 | initialization of g |
|
||||
| generic.go:7:7:7:7 | initialization of g | generic.go:7:37:7:37 | argument corresponding to u |
|
||||
| generic.go:7:28:7:35 | skip | generic.go:7:1:7:55 | function declaration |
|
||||
| generic.go:7:37:7:37 | argument corresponding to u | generic.go:7:37:7:37 | initialization of u |
|
||||
| generic.go:7:37:7:37 | initialization of u | generic.go:7:53:7:53 | u |
|
||||
| generic.go:7:46:7:53 | return statement | generic.go:7:55:7:55 | exit |
|
||||
| generic.go:7:53:7:53 | u | generic.go:7:46:7:53 | return statement |
|
||||
| generic.go:9:1:12:1 | skip | generic.go:14:31:14:39 | skip |
|
||||
| generic.go:14:1:14:1 | entry | generic.go:14:7:14:7 | argument corresponding to g |
|
||||
| generic.go:14:1:14:59 | function declaration | generic.go:16:6:16:21 | skip |
|
||||
| generic.go:14:7:14:7 | argument corresponding to g | generic.go:14:7:14:7 | initialization of g |
|
||||
| generic.go:14:7:14:7 | initialization of g | generic.go:14:41:14:41 | argument corresponding to u |
|
||||
| generic.go:14:31:14:39 | skip | generic.go:14:1:14:59 | function declaration |
|
||||
| generic.go:14:41:14:41 | argument corresponding to u | generic.go:14:41:14:41 | initialization of u |
|
||||
| generic.go:14:41:14:41 | initialization of u | generic.go:14:57:14:57 | u |
|
||||
| generic.go:14:50:14:57 | return statement | generic.go:14:59:14:59 | exit |
|
||||
| generic.go:14:57:14:57 | u | generic.go:14:50:14:57 | return statement |
|
||||
| generic.go:16:1:16:1 | entry | generic.go:16:30:16:30 | argument corresponding to t |
|
||||
| generic.go:16:1:18:1 | function declaration | generic.go:20:6:20:21 | skip |
|
||||
| generic.go:16:6:16:21 | skip | generic.go:16:1:18:1 | function declaration |
|
||||
| generic.go:16:30:16:30 | argument corresponding to t | generic.go:16:30:16:30 | initialization of t |
|
||||
| generic.go:16:30:16:30 | initialization of t | generic.go:17:9:17:9 | t |
|
||||
| generic.go:17:2:17:9 | return statement | generic.go:18:1:18:1 | exit |
|
||||
| generic.go:17:9:17:9 | t | generic.go:17:2:17:9 | return statement |
|
||||
| generic.go:20:1:20:1 | entry | generic.go:20:33:20:33 | argument corresponding to s |
|
||||
| generic.go:20:1:22:1 | function declaration | generic.go:24:6:24:12 | skip |
|
||||
| generic.go:20:6:20:21 | skip | generic.go:20:1:22:1 | function declaration |
|
||||
| generic.go:20:33:20:33 | argument corresponding to s | generic.go:20:33:20:33 | initialization of s |
|
||||
| generic.go:20:33:20:33 | initialization of s | generic.go:20:38:20:38 | argument corresponding to t |
|
||||
| generic.go:20:38:20:38 | argument corresponding to t | generic.go:20:38:20:38 | initialization of t |
|
||||
| generic.go:20:38:20:38 | initialization of t | generic.go:21:9:21:9 | s |
|
||||
| generic.go:21:2:21:12 | return statement | generic.go:22:1:22:1 | exit |
|
||||
| generic.go:21:9:21:9 | s | generic.go:21:12:21:12 | t |
|
||||
| generic.go:21:12:21:12 | t | generic.go:21:2:21:12 | return statement |
|
||||
| generic.go:24:1:24:1 | entry | generic.go:25:2:25:4 | skip |
|
||||
| generic.go:24:1:35:1 | function declaration | generic.go:0:0:0:0 | exit |
|
||||
| generic.go:24:6:24:12 | skip | generic.go:24:1:35:1 | function declaration |
|
||||
| generic.go:25:2:25:4 | assignment to gs1 | generic.go:26:2:26:2 | skip |
|
||||
| generic.go:25:2:25:4 | skip | generic.go:25:9:25:35 | struct literal |
|
||||
| generic.go:25:9:25:35 | struct literal | generic.go:25:32:25:34 | "x" |
|
||||
| generic.go:25:32:25:34 | "x" | generic.go:25:32:25:34 | init of "x" |
|
||||
| generic.go:25:32:25:34 | init of "x" | generic.go:25:2:25:4 | assignment to gs1 |
|
||||
| generic.go:26:2:26:2 | assignment to a | generic.go:27:2:27:4 | skip |
|
||||
| generic.go:26:2:26:2 | skip | generic.go:26:7:26:9 | gs1 |
|
||||
| generic.go:26:7:26:9 | gs1 | generic.go:26:7:26:18 | selection of Identity |
|
||||
| generic.go:26:7:26:18 | selection of Identity | generic.go:26:20:26:26 | "hello" |
|
||||
| generic.go:26:7:26:27 | call to Identity | generic.go:26:2:26:2 | assignment to a |
|
||||
| generic.go:26:7:26:27 | call to Identity | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:26:20:26:26 | "hello" | generic.go:26:7:26:27 | call to Identity |
|
||||
| generic.go:27:2:27:4 | assignment to gs2 | generic.go:28:2:28:2 | skip |
|
||||
| generic.go:27:2:27:4 | skip | generic.go:27:9:27:48 | struct literal |
|
||||
| generic.go:27:9:27:48 | struct literal | generic.go:27:40:27:42 | "y" |
|
||||
| generic.go:27:40:27:42 | "y" | generic.go:27:40:27:42 | init of "y" |
|
||||
| generic.go:27:40:27:42 | init of "y" | generic.go:27:45:27:47 | "z" |
|
||||
| generic.go:27:45:27:47 | "z" | generic.go:27:45:27:47 | init of "z" |
|
||||
| generic.go:27:45:27:47 | init of "z" | generic.go:27:2:27:4 | assignment to gs2 |
|
||||
| generic.go:28:2:28:2 | assignment to b | generic.go:29:2:29:2 | skip |
|
||||
| generic.go:28:2:28:2 | skip | generic.go:28:7:28:9 | gs2 |
|
||||
| generic.go:28:7:28:9 | gs2 | generic.go:28:7:28:19 | selection of Identity1 |
|
||||
| generic.go:28:7:28:19 | selection of Identity1 | generic.go:28:21:28:21 | a |
|
||||
| generic.go:28:7:28:22 | call to Identity1 | generic.go:28:2:28:2 | assignment to b |
|
||||
| generic.go:28:7:28:22 | call to Identity1 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:28:21:28:21 | a | generic.go:28:7:28:22 | call to Identity1 |
|
||||
| generic.go:29:2:29:2 | assignment to c | generic.go:30:2:30:2 | skip |
|
||||
| generic.go:29:2:29:2 | skip | generic.go:29:7:29:22 | genericIdentity1 |
|
||||
| generic.go:29:7:29:22 | genericIdentity1 | generic.go:29:32:29:32 | b |
|
||||
| generic.go:29:7:29:33 | call to genericIdentity1 | generic.go:29:2:29:2 | assignment to c |
|
||||
| generic.go:29:7:29:33 | call to genericIdentity1 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:29:32:29:32 | b | generic.go:29:7:29:33 | call to genericIdentity1 |
|
||||
| generic.go:30:2:30:2 | assignment to d | generic.go:31:2:31:2 | skip |
|
||||
| generic.go:30:2:30:2 | skip | generic.go:30:7:30:22 | genericIdentity1 |
|
||||
| generic.go:30:7:30:22 | genericIdentity1 | generic.go:30:24:30:24 | c |
|
||||
| generic.go:30:7:30:25 | call to genericIdentity1 | generic.go:30:2:30:2 | assignment to d |
|
||||
| generic.go:30:7:30:25 | call to genericIdentity1 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:30:24:30:24 | c | generic.go:30:7:30:25 | call to genericIdentity1 |
|
||||
| generic.go:31:2:31:2 | assignment to e | generic.go:31:2:31:53 | ... := ...[1] |
|
||||
| generic.go:31:2:31:2 | skip | generic.go:31:5:31:5 | skip |
|
||||
| generic.go:31:2:31:53 | ... := ...[0] | generic.go:31:2:31:2 | assignment to e |
|
||||
| generic.go:31:2:31:53 | ... := ...[1] | generic.go:31:5:31:5 | assignment to f |
|
||||
| generic.go:31:5:31:5 | assignment to f | generic.go:32:2:32:2 | skip |
|
||||
| generic.go:31:5:31:5 | skip | generic.go:31:10:31:25 | genericIdentity2 |
|
||||
| generic.go:31:10:31:25 | genericIdentity2 | generic.go:31:43:31:43 | d |
|
||||
| generic.go:31:10:31:53 | call to genericIdentity2 | generic.go:31:2:31:53 | ... := ...[0] |
|
||||
| generic.go:31:10:31:53 | call to genericIdentity2 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:31:43:31:43 | d | generic.go:31:46:31:52 | "hello" |
|
||||
| generic.go:31:46:31:52 | "hello" | generic.go:31:10:31:53 | call to genericIdentity2 |
|
||||
| generic.go:32:2:32:2 | assignment to g | generic.go:32:2:32:31 | ... := ...[1] |
|
||||
| generic.go:32:2:32:2 | skip | generic.go:32:5:32:5 | skip |
|
||||
| generic.go:32:2:32:31 | ... := ...[0] | generic.go:32:2:32:2 | assignment to g |
|
||||
| generic.go:32:2:32:31 | ... := ...[1] | generic.go:32:5:32:5 | assignment to h |
|
||||
| generic.go:32:5:32:5 | assignment to h | generic.go:33:2:33:2 | skip |
|
||||
| generic.go:32:5:32:5 | skip | generic.go:32:10:32:25 | genericIdentity2 |
|
||||
| generic.go:32:10:32:25 | genericIdentity2 | generic.go:32:27:32:27 | e |
|
||||
| generic.go:32:10:32:31 | call to genericIdentity2 | generic.go:32:2:32:31 | ... := ...[0] |
|
||||
| generic.go:32:10:32:31 | call to genericIdentity2 | generic.go:35:1:35:1 | exit |
|
||||
| generic.go:32:27:32:27 | e | generic.go:32:30:32:30 | f |
|
||||
| generic.go:32:30:32:30 | f | generic.go:32:10:32:31 | call to genericIdentity2 |
|
||||
| generic.go:33:2:33:2 | skip | generic.go:33:6:33:6 | g |
|
||||
| generic.go:33:6:33:6 | g | generic.go:34:2:34:2 | skip |
|
||||
| generic.go:34:2:34:2 | skip | generic.go:34:6:34:6 | h |
|
||||
| generic.go:34:6:34:6 | h | generic.go:35:1:35:1 | exit |
|
||||
| hello.go:0:0:0:0 | entry | hello.go:3:1:3:12 | skip |
|
||||
| hello.go:3:1:3:12 | skip | hello.go:5:7:5:13 | skip |
|
||||
| hello.go:5:7:5:13 | assignment to message | hello.go:7:6:7:13 | skip |
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package main
|
||||
|
||||
type GenericStruct1[T any] struct {
|
||||
Field T
|
||||
}
|
||||
|
||||
func (g GenericStruct1[U]) Identity(u U) U { return u }
|
||||
|
||||
type GenericStruct2[S, T any] struct {
|
||||
Field1 S
|
||||
Field2 T
|
||||
}
|
||||
|
||||
func (g GenericStruct2[U, _]) Identity1(u U) U { return u }
|
||||
|
||||
func genericIdentity1[T any](t T) T {
|
||||
return t
|
||||
}
|
||||
|
||||
func genericIdentity2[S, T any](s S, t T) (S, T) {
|
||||
return s, t
|
||||
}
|
||||
|
||||
func generic() {
|
||||
gs1 := GenericStruct1[string]{"x"}
|
||||
a := gs1.Identity("hello")
|
||||
gs2 := GenericStruct2[string, string]{"y", "z"}
|
||||
b := gs2.Identity1(a)
|
||||
c := genericIdentity1[string](b)
|
||||
d := genericIdentity1(c)
|
||||
e, f := genericIdentity2[string, string](d, "hello")
|
||||
g, h := genericIdentity2(e, f)
|
||||
_ = g
|
||||
_ = h
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
import go
|
||||
import TestUtilities.InlineFlowTest
|
|
@ -0,0 +1,68 @@
|
|||
package main
|
||||
|
||||
func genericSource[T any](t T) string {
|
||||
x := source()
|
||||
return x
|
||||
}
|
||||
|
||||
func genericIdentity[T any](t T) T {
|
||||
return t
|
||||
}
|
||||
|
||||
func genericSink1[T any](t T, u string) {
|
||||
sink(u) // $ hasValueFlow="u"
|
||||
}
|
||||
|
||||
func genericSink2[T any](t T, u string) {
|
||||
sink(u) // $ hasValueFlow="u"
|
||||
}
|
||||
|
||||
func genericSink3[T any](t T, u string) {
|
||||
sink(u) // $ hasValueFlow="u"
|
||||
}
|
||||
|
||||
func test() {
|
||||
var x struct {
|
||||
x1 int
|
||||
x2 string
|
||||
}
|
||||
{
|
||||
s := genericSource(x)
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
s := genericSource[int8](2)
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
f := genericSource[int8]
|
||||
s := f(2)
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
s := genericIdentity(source())
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
s := genericIdentity[string](source())
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
f := genericIdentity[string]
|
||||
s := f(source())
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
s := source()
|
||||
genericSink1(x, s)
|
||||
}
|
||||
{
|
||||
s := source()
|
||||
genericSink2[uint16](3, s)
|
||||
}
|
||||
{
|
||||
s := source()
|
||||
f := genericSink3[uint16]
|
||||
f(3, s)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package main
|
||||
|
||||
func source() string {
|
||||
return "untrusted data"
|
||||
}
|
||||
|
||||
func sink(string) {
|
||||
}
|
||||
|
||||
type GenericStruct1[T any] struct {
|
||||
Field T
|
||||
}
|
||||
|
||||
func (g GenericStruct1[U]) Identity(u U) U { return u }
|
||||
func (g GenericStruct1[U]) Getter() U { return g.Field }
|
||||
func (g GenericStruct1[U]) Setter(u U) { g.Field = u }
|
||||
|
||||
type GenericStruct2[S, T any] struct {
|
||||
Field1 S
|
||||
Field2 T
|
||||
}
|
||||
|
||||
func (g GenericStruct2[U, _]) Identity1(u U) U { return u }
|
||||
func (g GenericStruct2[U, _]) Getter1() U { return g.Field1 }
|
||||
func (g GenericStruct2[U, _]) Setter1(u U) { g.Field1 = u }
|
||||
|
||||
func (g GenericStruct2[_, V]) Identity2(v V) V { return v }
|
||||
func (g GenericStruct2[_, V]) Getter2() V { return g.Field2 }
|
||||
func (g GenericStruct2[_, V]) Setter2(v V) { g.Field2 = v }
|
||||
|
||||
func main() {
|
||||
{
|
||||
gs1 := GenericStruct1[string]{source()}
|
||||
sink(gs1.Field) // $ hasValueFlow="selection of Field"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
sink(gs1.Identity(source())) // $ hasValueFlow="call to Identity"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
f := gs1.Identity
|
||||
sink(f(source())) // $ hasValueFlow="call to f"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
gs1.Field = source()
|
||||
sink(gs1.Getter()) // $ hasValueFlow="call to Getter"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
gs1.Field = source()
|
||||
f := gs1.Getter
|
||||
sink(f()) // $ MISSING: hasValueFlow="call to f"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
gs1.Setter(source())
|
||||
sink(gs1.Field) // $ hasValueFlow="selection of Field"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
f := gs1.Setter
|
||||
f(source())
|
||||
sink(gs1.Field) // $ MISSING: hasValueFlow="selection of Field"
|
||||
}
|
||||
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{source(), ""}
|
||||
sink(gs2.Field1) // $ hasValueFlow="selection of Field1"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
sink(gs2.Identity1(source())) // $ hasValueFlow="call to Identity1"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
f := gs2.Identity1
|
||||
sink(f(source())) // $ hasValueFlow="call to f"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Field1 = source()
|
||||
sink(gs2.Getter1()) // $ hasValueFlow="call to Getter1"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Field1 = source()
|
||||
f := gs2.Getter1
|
||||
sink(f()) // $ MISSING: hasValueFlow="call to f"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Setter1(source())
|
||||
sink(gs2.Field1) // $ hasValueFlow="selection of Field1"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
f := gs2.Setter1
|
||||
f(source())
|
||||
sink(gs2.Field1) // $ MISSING: hasValueFlow="selection of Field1"
|
||||
}
|
||||
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", source()}
|
||||
sink(gs2.Field2) // $ hasValueFlow="selection of Field2"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
sink(gs2.Identity2(source())) // $ hasValueFlow="call to Identity2"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
f := gs2.Identity2
|
||||
sink(f(source())) // $ hasValueFlow="call to f"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Field2 = source()
|
||||
sink(gs2.Getter2()) // $ hasValueFlow="call to Getter2"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Field2 = source()
|
||||
f := gs2.Getter2
|
||||
sink(f()) // $ MISSING: hasValueFlow="call to f"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Setter2(source())
|
||||
sink(gs2.Field2) // $ hasValueFlow="selection of Field2"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
f := gs2.Setter2
|
||||
f(source())
|
||||
sink(gs2.Field2) // $ MISSING: hasValueFlow="selection of Field2"
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ edges
|
|||
| test.go:30:20:30:26 | selection of c : subBindMe | test.go:30:13:30:29 | type conversion |
|
||||
| test.go:35:20:35:42 | call to Cookie : string | test.go:35:13:35:43 | type conversion |
|
||||
| test.go:40:20:40:31 | call to Data : map type | test.go:40:13:40:52 | type conversion |
|
||||
| test.go:45:20:45:43 | call to GetData : interface type | test.go:45:13:45:53 | type conversion |
|
||||
| test.go:45:20:45:43 | call to GetData : basic interface type | test.go:45:13:45:53 | type conversion |
|
||||
| test.go:50:20:50:42 | call to Header : string | test.go:50:13:50:43 | type conversion |
|
||||
| test.go:55:20:55:41 | call to Param : string | test.go:55:13:55:42 | type conversion |
|
||||
| test.go:60:20:60:33 | call to Params : map type | test.go:60:13:60:45 | type conversion |
|
||||
|
@ -153,7 +153,7 @@ nodes
|
|||
| test.go:40:13:40:52 | type conversion | semmle.label | type conversion |
|
||||
| test.go:40:20:40:31 | call to Data : map type | semmle.label | call to Data : map type |
|
||||
| test.go:45:13:45:53 | type conversion | semmle.label | type conversion |
|
||||
| test.go:45:20:45:43 | call to GetData : interface type | semmle.label | call to GetData : interface type |
|
||||
| test.go:45:20:45:43 | call to GetData : basic interface type | semmle.label | call to GetData : basic interface type |
|
||||
| test.go:50:13:50:43 | type conversion | semmle.label | type conversion |
|
||||
| test.go:50:20:50:42 | call to Header : string | semmle.label | call to Header : string |
|
||||
| test.go:55:13:55:42 | type conversion | semmle.label | type conversion |
|
||||
|
@ -267,7 +267,7 @@ subpaths
|
|||
| test.go:30:13:30:29 | type conversion | test.go:26:6:26:10 | definition of bound : bindMe | test.go:30:13:30:29 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:26:6:26:10 | definition of bound | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||
| test.go:35:13:35:43 | type conversion | test.go:35:20:35:42 | call to Cookie : string | test.go:35:13:35:43 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:35:20:35:42 | call to Cookie | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||
| test.go:40:13:40:52 | type conversion | test.go:40:20:40:31 | call to Data : map type | test.go:40:13:40:52 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:40:20:40:31 | call to Data | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||
| test.go:45:13:45:53 | type conversion | test.go:45:20:45:43 | call to GetData : interface type | test.go:45:13:45:53 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:45:20:45:43 | call to GetData | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||
| test.go:45:13:45:53 | type conversion | test.go:45:20:45:43 | call to GetData : basic interface type | test.go:45:13:45:53 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:45:20:45:43 | call to GetData | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||
| test.go:50:13:50:43 | type conversion | test.go:50:20:50:42 | call to Header : string | test.go:50:13:50:43 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:50:20:50:42 | call to Header | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||
| test.go:55:13:55:42 | type conversion | test.go:55:20:55:41 | call to Param : string | test.go:55:13:55:42 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:55:20:55:41 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||
| test.go:60:13:60:45 | type conversion | test.go:60:20:60:33 | call to Params : map type | test.go:60:13:60:45 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:60:20:60:33 | call to Params | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||
|
|
|
@ -9,13 +9,13 @@ edges
|
|||
| test.go:82:22:82:26 | &... : pointer type | test.go:83:13:83:30 | type conversion |
|
||||
| test.go:86:21:86:25 | &... : pointer type | test.go:87:13:87:30 | type conversion |
|
||||
| test.go:92:20:92:36 | call to Value : string | test.go:92:13:92:37 | type conversion |
|
||||
| test.go:93:20:93:39 | call to RawValue : interface type | test.go:93:13:93:49 | type conversion |
|
||||
| test.go:93:20:93:39 | call to RawValue : basic interface type | test.go:93:13:93:49 | type conversion |
|
||||
| test.go:94:20:94:37 | call to String : string | test.go:94:13:94:38 | type conversion |
|
||||
| test.go:95:20:95:36 | call to Value : string | test.go:95:13:95:37 | type conversion |
|
||||
| test.go:96:20:96:39 | call to RawValue : interface type | test.go:96:13:96:49 | type conversion |
|
||||
| test.go:96:20:96:39 | call to RawValue : basic interface type | test.go:96:13:96:49 | type conversion |
|
||||
| test.go:97:20:97:37 | call to String : string | test.go:97:13:97:38 | type conversion |
|
||||
| test.go:98:20:98:37 | call to Value : string | test.go:98:13:98:38 | type conversion |
|
||||
| test.go:99:20:99:40 | call to RawValue : interface type | test.go:99:13:99:50 | type conversion |
|
||||
| test.go:99:20:99:40 | call to RawValue : basic interface type | test.go:99:13:99:50 | type conversion |
|
||||
| test.go:100:20:100:38 | call to String : string | test.go:100:13:100:39 | type conversion |
|
||||
| test.go:106:9:106:13 | &... : pointer type | test.go:107:13:107:33 | type conversion |
|
||||
| test.go:106:9:106:13 | &... : pointer type | test.go:107:20:107:26 | implicit dereference : MyStruct |
|
||||
|
@ -52,19 +52,19 @@ nodes
|
|||
| test.go:92:13:92:37 | type conversion | semmle.label | type conversion |
|
||||
| test.go:92:20:92:36 | call to Value : string | semmle.label | call to Value : string |
|
||||
| test.go:93:13:93:49 | type conversion | semmle.label | type conversion |
|
||||
| test.go:93:20:93:39 | call to RawValue : interface type | semmle.label | call to RawValue : interface type |
|
||||
| test.go:93:20:93:39 | call to RawValue : basic interface type | semmle.label | call to RawValue : basic interface type |
|
||||
| test.go:94:13:94:38 | type conversion | semmle.label | type conversion |
|
||||
| test.go:94:20:94:37 | call to String : string | semmle.label | call to String : string |
|
||||
| test.go:95:13:95:37 | type conversion | semmle.label | type conversion |
|
||||
| test.go:95:20:95:36 | call to Value : string | semmle.label | call to Value : string |
|
||||
| test.go:96:13:96:49 | type conversion | semmle.label | type conversion |
|
||||
| test.go:96:20:96:39 | call to RawValue : interface type | semmle.label | call to RawValue : interface type |
|
||||
| test.go:96:20:96:39 | call to RawValue : basic interface type | semmle.label | call to RawValue : basic interface type |
|
||||
| test.go:97:13:97:38 | type conversion | semmle.label | type conversion |
|
||||
| test.go:97:20:97:37 | call to String : string | semmle.label | call to String : string |
|
||||
| test.go:98:13:98:38 | type conversion | semmle.label | type conversion |
|
||||
| test.go:98:20:98:37 | call to Value : string | semmle.label | call to Value : string |
|
||||
| test.go:99:13:99:50 | type conversion | semmle.label | type conversion |
|
||||
| test.go:99:20:99:40 | call to RawValue : interface type | semmle.label | call to RawValue : interface type |
|
||||
| test.go:99:20:99:40 | call to RawValue : basic interface type | semmle.label | call to RawValue : basic interface type |
|
||||
| test.go:100:13:100:39 | type conversion | semmle.label | type conversion |
|
||||
| test.go:100:20:100:38 | call to String : string | semmle.label | call to String : string |
|
||||
| test.go:106:9:106:13 | &... : pointer type | semmle.label | &... : pointer type |
|
||||
|
@ -104,13 +104,13 @@ subpaths
|
|||
| test.go:83:13:83:30 | type conversion | test.go:82:22:82:26 | &... : pointer type | test.go:83:13:83:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:82:22:82:26 | &... | stored value |
|
||||
| test.go:87:13:87:30 | type conversion | test.go:86:21:86:25 | &... : pointer type | test.go:87:13:87:30 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:86:21:86:25 | &... | stored value |
|
||||
| test.go:92:13:92:37 | type conversion | test.go:92:20:92:36 | call to Value : string | test.go:92:13:92:37 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:92:20:92:36 | call to Value | stored value |
|
||||
| test.go:93:13:93:49 | type conversion | test.go:93:20:93:39 | call to RawValue : interface type | test.go:93:13:93:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:93:20:93:39 | call to RawValue | stored value |
|
||||
| test.go:93:13:93:49 | type conversion | test.go:93:20:93:39 | call to RawValue : basic interface type | test.go:93:13:93:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:93:20:93:39 | call to RawValue | stored value |
|
||||
| test.go:94:13:94:38 | type conversion | test.go:94:20:94:37 | call to String : string | test.go:94:13:94:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:94:20:94:37 | call to String | stored value |
|
||||
| test.go:95:13:95:37 | type conversion | test.go:95:20:95:36 | call to Value : string | test.go:95:13:95:37 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:95:20:95:36 | call to Value | stored value |
|
||||
| test.go:96:13:96:49 | type conversion | test.go:96:20:96:39 | call to RawValue : interface type | test.go:96:13:96:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:96:20:96:39 | call to RawValue | stored value |
|
||||
| test.go:96:13:96:49 | type conversion | test.go:96:20:96:39 | call to RawValue : basic interface type | test.go:96:13:96:49 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:96:20:96:39 | call to RawValue | stored value |
|
||||
| test.go:97:13:97:38 | type conversion | test.go:97:20:97:37 | call to String : string | test.go:97:13:97:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:97:20:97:37 | call to String | stored value |
|
||||
| test.go:98:13:98:38 | type conversion | test.go:98:20:98:37 | call to Value : string | test.go:98:13:98:38 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:98:20:98:37 | call to Value | stored value |
|
||||
| test.go:99:13:99:50 | type conversion | test.go:99:20:99:40 | call to RawValue : interface type | test.go:99:13:99:50 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:99:20:99:40 | call to RawValue | stored value |
|
||||
| test.go:99:13:99:50 | type conversion | test.go:99:20:99:40 | call to RawValue : basic interface type | test.go:99:13:99:50 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:99:20:99:40 | call to RawValue | stored value |
|
||||
| test.go:100:13:100:39 | type conversion | test.go:100:20:100:38 | call to String : string | test.go:100:13:100:39 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:100:20:100:38 | call to String | stored value |
|
||||
| test.go:107:13:107:33 | type conversion | test.go:106:9:106:13 | &... : pointer type | test.go:107:13:107:33 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:106:9:106:13 | &... | stored value |
|
||||
| test.go:111:13:111:29 | type conversion | test.go:110:9:110:12 | &... : pointer type | test.go:111:13:111:29 | type conversion | Stored cross-site scripting vulnerability due to $@. | test.go:110:9:110:12 | &... | stored value |
|
||||
|
|
Загрузка…
Ссылка в новой задаче