зеркало из 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
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go 1.17
|
- name: Set up Go 1.18.1
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.18.1
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Set up CodeQL CLI
|
- name: Set up CodeQL CLI
|
||||||
|
@ -59,10 +59,10 @@ jobs:
|
||||||
name: Test MacOS
|
name: Test MacOS
|
||||||
runs-on: macOS-latest
|
runs-on: macOS-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.17
|
- name: Set up Go 1.18.1
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.18.1
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Set up CodeQL CLI
|
- name: Set up CodeQL CLI
|
||||||
|
@ -99,10 +99,10 @@ jobs:
|
||||||
name: Test Windows
|
name: Test Windows
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.17
|
- name: Set up Go 1.18.1
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.18.1
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Set up CodeQL CLI
|
- 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/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
gotypes "go/types"
|
gotypes "go/types"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"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
|
// DeclParentType is the type of AST nodes that can have declarations as children
|
||||||
var DeclParentType = NewUnionType("@declparent", NodeType)
|
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
|
// FuncDefType is the type of AST nodes that define functions, that is, function
|
||||||
// declarations and function literals
|
// declarations and function literals
|
||||||
var FuncDefType = NewUnionType("@funcdef", StmtParentType, ExprParentType)
|
var FuncDefType = NewUnionType("@funcdef", StmtParentType, ExprParentType)
|
||||||
|
@ -308,6 +312,9 @@ var StmtType = NewPrimaryKeyType("@stmt", ExprParentType, StmtParentType)
|
||||||
// DeclType is the type of declaration AST nodes
|
// DeclType is the type of declaration AST nodes
|
||||||
var DeclType = NewPrimaryKeyType("@decl", ExprParentType, StmtParentType, FieldParentType)
|
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
|
// SpecType is the type of spec AST nodes
|
||||||
var SpecType = NewPrimaryKeyType("@spec", ExprParentType, DocumentableType)
|
var SpecType = NewPrimaryKeyType("@spec", ExprParentType, DocumentableType)
|
||||||
|
|
||||||
|
@ -371,9 +378,23 @@ var ParenExpr = ExprKind.NewBranch("@parenexpr")
|
||||||
// SelectorExpr is the type of selector expression AST nodes
|
// SelectorExpr is the type of selector expression AST nodes
|
||||||
var SelectorExpr = ExprKind.NewBranch("@selectorexpr")
|
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")
|
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
|
// SliceExpr is the type of slice expression AST nodes
|
||||||
var SliceExpr = ExprKind.NewBranch("@sliceexpr")
|
var SliceExpr = ExprKind.NewBranch("@sliceexpr")
|
||||||
|
|
||||||
|
@ -453,6 +474,9 @@ var InterfaceTypeExpr = ExprKind.NewBranch("@interfacetypeexpr", FieldParentType
|
||||||
// MapTypeExpr is the type of map type AST nodes
|
// MapTypeExpr is the type of map type AST nodes
|
||||||
var MapTypeExpr = ExprKind.NewBranch("@maptypeexpr")
|
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
|
// ChanTypeExpr is the type of channel type AST nodes
|
||||||
var ChanTypeExpr = NewUnionType("@chantypeexpr")
|
var ChanTypeExpr = NewUnionType("@chantypeexpr")
|
||||||
|
|
||||||
|
@ -635,7 +659,7 @@ var TypeDeclType = DeclKind.NewBranch("@typedecl", GenDeclType)
|
||||||
var VarDeclType = DeclKind.NewBranch("@vardecl", GenDeclType)
|
var VarDeclType = DeclKind.NewBranch("@vardecl", GenDeclType)
|
||||||
|
|
||||||
// FuncDeclType is the type of function declaration AST nodes
|
// 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
|
// SpecKind is a case type for distinguishing different kinds of declaration specification nodes
|
||||||
var SpecKind = NewCaseType(SpecType, "kind")
|
var SpecKind = NewCaseType(SpecType, "kind")
|
||||||
|
@ -647,7 +671,7 @@ var ImportSpecType = SpecKind.NewBranch("@importspec")
|
||||||
var ValueSpecType = SpecKind.NewBranch("@valuespec")
|
var ValueSpecType = SpecKind.NewBranch("@valuespec")
|
||||||
|
|
||||||
// TypeSpecType is the type of type declaration specification nodes
|
// 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
|
// TypeDefSpecType is the type of type declaration specification nodes corresponding to type definitions
|
||||||
var TypeDefSpecType = SpecKind.NewBranch("@typedefspec", TypeSpecType)
|
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
|
// ObjectKind is a case type for distinguishing different kinds of built-in and declared objects
|
||||||
var ObjectKind = NewCaseType(ObjectType, "kind")
|
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
|
// DeclObjectType is the type of declared objects
|
||||||
var DeclObjectType = NewUnionType("@declobject")
|
var DeclObjectType = NewUnionType("@declobject")
|
||||||
|
|
||||||
|
@ -674,7 +701,7 @@ var PkgObjectType = ObjectKind.NewBranch("@pkgobject")
|
||||||
var TypeObjectType = NewUnionType("@typeobject")
|
var TypeObjectType = NewUnionType("@typeobject")
|
||||||
|
|
||||||
// DeclTypeObjectType is the type of declared named types
|
// 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
|
// BuiltinTypeObjectType is the type of built-in named types
|
||||||
var BuiltinTypeObjectType = ObjectKind.NewBranch("@builtintypeobject", TypeObjectType, BuiltinObjectType)
|
var BuiltinTypeObjectType = ObjectKind.NewBranch("@builtintypeobject", TypeObjectType, BuiltinObjectType)
|
||||||
|
@ -701,7 +728,7 @@ var DeclVarObjectType = ObjectKind.NewBranch("@declvarobject", VarObjectType, De
|
||||||
var FunctionObjectType = NewUnionType("@functionobject", ValueObjectType)
|
var FunctionObjectType = NewUnionType("@functionobject", ValueObjectType)
|
||||||
|
|
||||||
// DeclFuncObjectType is the type of declared functions, including (abstract and concrete) methods
|
// 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
|
// BuiltinFuncObjectType is the type of built-in functions
|
||||||
var BuiltinFuncObjectType = ObjectKind.NewBranch("@builtinfunctionobject", FunctionObjectType, BuiltinObjectType)
|
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
|
// CompositeType is the type of all composite (that is, non-basic) types
|
||||||
var CompositeType = NewUnionType("@compositetype")
|
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
|
// ElementContainerType is the type of types that have elements, such as arrays
|
||||||
// and channels
|
// and channels
|
||||||
var ElementContainerType = NewUnionType("@containertype", CompositeType)
|
var ElementContainerType = NewUnionType("@containertype", CompositeType)
|
||||||
|
@ -831,6 +861,9 @@ var ChanTypes = map[gotypes.ChanDir]*BranchType{
|
||||||
// NamedType is the type of named types
|
// NamedType is the type of named types
|
||||||
var NamedType = TypeKind.NewBranch("@namedtype", CompositeType)
|
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
|
// PackageType is the type of packages
|
||||||
var PackageType = NewPrimaryKeyType("@package")
|
var PackageType = NewPrimaryKeyType("@package")
|
||||||
|
|
||||||
|
@ -970,6 +1003,13 @@ var FieldsTable = NewTable("fields",
|
||||||
IntColumn("idx"),
|
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
|
// StmtsTable is the table defining statement AST nodes
|
||||||
var StmtsTable = NewTable("stmts",
|
var StmtsTable = NewTable("stmts",
|
||||||
EntityColumn(StmtType, "id").Key(),
|
EntityColumn(StmtType, "id").Key(),
|
||||||
|
@ -1171,3 +1211,12 @@ var HasEllipsisTable = NewTable("has_ellipsis",
|
||||||
var VariadicTable = NewTable("variadic",
|
var VariadicTable = NewTable("variadic",
|
||||||
EntityColumn(SignatureType, "id"),
|
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 MaxGoRoutines int
|
||||||
|
var typeParamParent map[*types.TypeParam]types.Object = make(map[*types.TypeParam]types.Object)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// this sets the number of threads that the Go runtime will spawn; this is separate
|
// 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
|
// root directories of packages that we want to extract
|
||||||
wantedRoots := make(map[string]bool)
|
wantedRoots := make(map[string]bool)
|
||||||
|
|
||||||
// recursively visit all packages in depth-first order;
|
// Do a post-order traversal and extract the package scope of each package
|
||||||
// on the way down, associate each package scope with its corresponding package,
|
|
||||||
// and on the way up extract the package's scope
|
|
||||||
packages.Visit(pkgs, func(pkg *packages.Package) bool {
|
packages.Visit(pkgs, func(pkg *packages.Package) bool {
|
||||||
return true
|
return true
|
||||||
}, func(pkg *packages.Package) {
|
}, func(pkg *packages.Package) {
|
||||||
|
@ -138,7 +137,7 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
||||||
defer tw.Close()
|
defer tw.Close()
|
||||||
|
|
||||||
scope := extractPackageScope(tw, pkg)
|
scope := extractPackageScope(tw, pkg)
|
||||||
tw.ForEachObject(extractObjectType)
|
extractObjectTypes(tw)
|
||||||
lbl := tw.Labeler.GlobalID(util.EscapeTrapSpecialChars(pkg.PkgPath) + ";pkg")
|
lbl := tw.Labeler.GlobalID(util.EscapeTrapSpecialChars(pkg.PkgPath) + ";pkg")
|
||||||
dbscheme.PackagesTable.Emit(tw, lbl, pkg.Name, pkg.PkgPath, scope)
|
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) {
|
func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label) {
|
||||||
for _, name := range scope.Names() {
|
for _, name := range scope.Names() {
|
||||||
obj := scope.Lookup(name)
|
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 {
|
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)
|
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 {
|
func extractMethod(tw *trap.Writer, meth *types.Func) trap.Label {
|
||||||
// get the receiver type of the method
|
// get the receiver type of the method
|
||||||
recvtyp := meth.Type().(*types.Signature).Recv().Type()
|
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
|
// 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 {
|
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)
|
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
|
// extractObjectType extracts type and receiver information for a given object
|
||||||
func extractObjectType(tw *trap.Writer, obj types.Object, lbl trap.Label) {
|
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 {
|
if tp := obj.Type(); tp != nil {
|
||||||
dbscheme.ObjectTypesTable.Emit(tw, lbl, extractType(tw, tp))
|
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)
|
extractFileNode(tw, ast)
|
||||||
|
|
||||||
tw.ForEachObject(extractObjectType)
|
extractObjectTypes(tw)
|
||||||
|
|
||||||
extractNumLines(tw, path, ast)
|
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
|
// 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) {
|
func extractScopes(tw *trap.Writer, nd *ast.File, pkg *packages.Package) {
|
||||||
pkgScopeLabel := extractPackageScope(tw, pkg)
|
pkgScopeLabel := extractPackageScope(tw, pkg)
|
||||||
fileScope := pkg.TypesInfo.Scopes[nd]
|
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)
|
dbscheme.DefsTable.Emit(tw, lbl, objlbl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
use := tw.Package.TypesInfo.Uses[expr]
|
use := getObjectBeingUsed(tw, expr)
|
||||||
if use != nil {
|
if use != nil {
|
||||||
useTyp := extractType(tw, use.Type())
|
useTyp := extractType(tw, use.Type())
|
||||||
objlbl, exists := tw.Labeler.LookupObjectID(use, useTyp)
|
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 {
|
if expr == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
kind = dbscheme.IndexExpr.Index()
|
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.X, lbl, 0)
|
||||||
extractExpr(tw, expr.Index, lbl, 1)
|
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:
|
case *ast.SliceExpr:
|
||||||
if expr == nil {
|
if expr == nil {
|
||||||
return
|
return
|
||||||
|
@ -923,23 +1000,33 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int) {
|
||||||
if expr == nil {
|
if expr == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tp := dbscheme.UnaryExprs[expr.Op]
|
if expr.Op == token.TILDE {
|
||||||
if tp == nil {
|
kind = dbscheme.TypeSetLiteralExpr.Index()
|
||||||
log.Fatalf("unsupported unary operator %s", expr.Op)
|
} else {
|
||||||
|
tp := dbscheme.UnaryExprs[expr.Op]
|
||||||
|
if tp == nil {
|
||||||
|
log.Fatalf("unsupported unary operator %s", expr.Op)
|
||||||
|
}
|
||||||
|
kind = tp.Index()
|
||||||
}
|
}
|
||||||
kind = tp.Index()
|
|
||||||
extractExpr(tw, expr.X, lbl, 0)
|
extractExpr(tw, expr.X, lbl, 0)
|
||||||
case *ast.BinaryExpr:
|
case *ast.BinaryExpr:
|
||||||
if expr == nil {
|
if expr == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tp := dbscheme.BinaryExprs[expr.Op]
|
_, isUnionType := typeOf(tw, expr).(*types.Union)
|
||||||
if tp == nil {
|
if expr.Op == token.OR && isUnionType {
|
||||||
log.Fatalf("unsupported binary operator %s", expr.Op)
|
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)
|
||||||
|
}
|
||||||
|
kind = tp.Index()
|
||||||
|
extractExpr(tw, expr.X, lbl, 0)
|
||||||
|
extractExpr(tw, expr.Y, lbl, 1)
|
||||||
}
|
}
|
||||||
kind = tp.Index()
|
|
||||||
extractExpr(tw, expr.X, lbl, 0)
|
|
||||||
extractExpr(tw, expr.Y, lbl, 1)
|
|
||||||
case *ast.ArrayType:
|
case *ast.ArrayType:
|
||||||
if expr == nil {
|
if expr == nil {
|
||||||
return
|
return
|
||||||
|
@ -966,6 +1053,9 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
kind = dbscheme.InterfaceTypeExpr.Index()
|
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)
|
extractFields(tw, expr.Methods, lbl, 0, 1)
|
||||||
case *ast.MapType:
|
case *ast.MapType:
|
||||||
if expr == nil {
|
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
|
// 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
|
// extracted, and associates it with `expr` in the `type_of` table
|
||||||
func extractTypeOf(tw *trap.Writer, expr ast.Expr, lbl trap.Label) {
|
func extractTypeOf(tw *trap.Writer, expr ast.Expr, lbl trap.Label) {
|
||||||
tp := tw.Package.TypesInfo.TypeOf(expr)
|
tp := typeOf(tw, expr)
|
||||||
if tp != nil {
|
if tp != nil {
|
||||||
tplbl := extractType(tw, tp)
|
tplbl := extractType(tw, tp)
|
||||||
dbscheme.TypeOfTable.Emit(tw, lbl, tplbl)
|
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)
|
extractExpr(tw, decl.Type, lbl, 1)
|
||||||
extractStmt(tw, decl.Body, lbl, 2)
|
extractStmt(tw, decl.Body, lbl, 2)
|
||||||
extractDoc(tw, decl.Doc, lbl)
|
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:
|
default:
|
||||||
log.Fatalf("unknown declaration of type %T", decl)
|
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()
|
kind = dbscheme.TypeDefSpecType.Index()
|
||||||
}
|
}
|
||||||
extractExpr(tw, spec.Name, lbl, 0)
|
extractExpr(tw, spec.Name, lbl, 0)
|
||||||
|
extractTypeParamDecls(tw, spec.TypeParams, lbl)
|
||||||
extractExpr(tw, spec.Type, lbl, 1)
|
extractExpr(tw, spec.Type, lbl, 1)
|
||||||
extractDoc(tw, spec.Doc, lbl)
|
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++ {
|
for i := 0; i < tp.NumFields(); i++ {
|
||||||
field := tp.Field(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)
|
fieldlbl, exists := tw.Labeler.FieldID(field, i, lbl)
|
||||||
if !exists {
|
if !exists {
|
||||||
extractObject(tw, field, fieldlbl)
|
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++ {
|
for i := 0; i < tp.NumMethods(); i++ {
|
||||||
meth := tp.Method(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)
|
extractMethod(tw, meth)
|
||||||
|
|
||||||
extractComponentType(tw, lbl, i, meth.Name(), meth.Type())
|
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:
|
case *types.Tuple:
|
||||||
kind = dbscheme.TupleType.Index()
|
kind = dbscheme.TupleType.Index()
|
||||||
for i := 0; i < tp.Len(); i++ {
|
for i := 0; i < tp.Len(); i++ {
|
||||||
|
@ -1410,11 +1518,11 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
||||||
}
|
}
|
||||||
case *types.Signature:
|
case *types.Signature:
|
||||||
kind = dbscheme.SignatureType.Index()
|
kind = dbscheme.SignatureType.Index()
|
||||||
parms, results := tp.Params(), tp.Results()
|
params, results := tp.Params(), tp.Results()
|
||||||
if parms != nil {
|
if params != nil {
|
||||||
for i := 0; i < parms.Len(); i++ {
|
for i := 0; i < params.Len(); i++ {
|
||||||
parm := parms.At(i)
|
param := params.At(i)
|
||||||
extractComponentType(tw, lbl, i+1, "", parm.Type())
|
extractComponentType(tw, lbl, i+1, "", param.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if results != nil {
|
if results != nil {
|
||||||
|
@ -1434,24 +1542,27 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
||||||
kind = dbscheme.ChanTypes[tp.Dir()].Index()
|
kind = dbscheme.ChanTypes[tp.Dir()].Index()
|
||||||
extractElementType(tw, lbl, tp.Elem())
|
extractElementType(tw, lbl, tp.Elem())
|
||||||
case *types.Named:
|
case *types.Named:
|
||||||
|
origintp := tp.Origin()
|
||||||
kind = dbscheme.NamedType.Index()
|
kind = dbscheme.NamedType.Index()
|
||||||
dbscheme.TypeNameTable.Emit(tw, lbl, tp.Obj().Name())
|
dbscheme.TypeNameTable.Emit(tw, lbl, origintp.Obj().Name())
|
||||||
underlying := tp.Underlying()
|
underlying := origintp.Underlying()
|
||||||
extractUnderlyingType(tw, lbl, 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 {
|
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 {
|
} else {
|
||||||
if !exists {
|
if !exists {
|
||||||
extractObject(tw, tp.Obj(), entitylbl)
|
extractObject(tw, origintp.Obj(), entitylbl)
|
||||||
}
|
}
|
||||||
dbscheme.TypeObjectTable.Emit(tw, lbl, entitylbl)
|
dbscheme.TypeObjectTable.Emit(tw, lbl, entitylbl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure all methods have labels
|
// ensure all methods have labels - note that methods do not have a
|
||||||
for i := 0; i < tp.NumMethods(); i++ {
|
// parent scope, so they are not dealt with by `extractScopes`
|
||||||
meth := tp.Method(i)
|
for i := 0; i < origintp.NumMethods(); i++ {
|
||||||
|
meth := origintp.Method(i)
|
||||||
|
|
||||||
extractMethod(tw, meth)
|
extractMethod(tw, meth)
|
||||||
}
|
}
|
||||||
|
@ -1463,6 +1574,21 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
||||||
dbscheme.MethodHostsTable.Emit(tw, methlbl, lbl)
|
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:
|
default:
|
||||||
log.Fatalf("unexpected type %T", tp)
|
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)
|
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()))
|
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%s;interfacetype", b.String()))
|
||||||
case *types.Tuple:
|
case *types.Tuple:
|
||||||
var b strings.Builder
|
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()))
|
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%s;tupletype", b.String()))
|
||||||
case *types.Signature:
|
case *types.Signature:
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
parms, results := tp.Params(), tp.Results()
|
params, results := tp.Params(), tp.Results()
|
||||||
if parms != nil {
|
if params != nil {
|
||||||
for i := 0; i < parms.Len(); i++ {
|
for i := 0; i < params.Len(); i++ {
|
||||||
parmLbl := extractType(tw, parms.At(i).Type())
|
paramLbl := extractType(tw, params.At(i).Type())
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
b.WriteString(",")
|
b.WriteString(",")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(&b, "{%s}", parmLbl)
|
fmt.Fprintf(&b, "{%s}", paramLbl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.WriteString(";")
|
b.WriteString(";")
|
||||||
|
@ -1568,14 +1707,33 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
|
||||||
elem := extractType(tw, tp.Elem())
|
elem := extractType(tw, tp.Elem())
|
||||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%v,{%s};chantype", dir, elem))
|
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%v,{%s};chantype", dir, elem))
|
||||||
case *types.Named:
|
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 {
|
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 {
|
if !exists {
|
||||||
extractObject(tw, tp.Obj(), entitylbl)
|
extractObject(tw, origintp.Obj(), entitylbl)
|
||||||
}
|
}
|
||||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%s};namedtype", 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
|
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)
|
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
|
label = InvalidLabel
|
||||||
} else {
|
} else {
|
||||||
label, exists = l.ScopedObjectID(object, typelbl)
|
label, exists = l.ScopedObjectID(object, func() Label { return typelbl })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return label, exists
|
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
|
// 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
|
// from several files via the method. As the type label is required to construct
|
||||||
// the receiver object id, it is also required here.
|
// 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]
|
label, exists := l.objectLabels[object]
|
||||||
if !exists {
|
if !exists {
|
||||||
scope := object.Parent()
|
scope := object.Parent()
|
||||||
|
@ -154,19 +154,17 @@ func (l *Labeler) ScopedObjectID(object types.Object, typelbl Label) (Label, boo
|
||||||
} else {
|
} else {
|
||||||
// associate method receiver objects to special keys, because those can be
|
// associate method receiver objects to special keys, because those can be
|
||||||
// referenced from other files via their method
|
// referenced from other files via their method
|
||||||
isRecv := false
|
meth := findMethodWithGivenReceiver(object.Type(), object)
|
||||||
if namedType, ok := object.Type().(*types.Named); ok {
|
if meth == nil {
|
||||||
for i := 0; i < namedType.NumMethods(); i++ {
|
if pointerType, ok := object.Type().(*types.Pointer); ok {
|
||||||
meth := namedType.Method(i)
|
meth = findMethodWithGivenReceiver(pointerType.Elem(), object)
|
||||||
if object == meth.Type().(*types.Signature).Recv() {
|
|
||||||
isRecv = true
|
|
||||||
methlbl, _ := l.MethodID(meth, typelbl)
|
|
||||||
label, _ = l.ReceiverObjectID(object, methlbl)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isRecv {
|
if meth != nil {
|
||||||
|
methlbl, _ := l.MethodID(meth, getTypeLabel())
|
||||||
|
label, _ = l.ReceiverObjectID(object, methlbl)
|
||||||
|
} else {
|
||||||
scopeLbl := l.ScopeID(scope, object.Pkg())
|
scopeLbl := l.ScopeID(scope, object.Pkg())
|
||||||
label = l.GlobalID(fmt.Sprintf("{%v},%s;object", scopeLbl, object.Name()))
|
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
|
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
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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]
|
label, exists := l.objectLabels[method]
|
||||||
if !exists {
|
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
|
l.objectLabels[method] = label
|
||||||
}
|
}
|
||||||
return label, exists
|
return label, exists
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
"go/types"
|
"go/types"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -17,13 +18,15 @@ import (
|
||||||
|
|
||||||
// A Writer provides methods for writing data to a TRAP file
|
// A Writer provides methods for writing data to a TRAP file
|
||||||
type Writer struct {
|
type Writer struct {
|
||||||
zip *gzip.Writer
|
zip *gzip.Writer
|
||||||
w *bufio.Writer
|
w *bufio.Writer
|
||||||
file *os.File
|
file *os.File
|
||||||
Labeler *Labeler
|
Labeler *Labeler
|
||||||
path string
|
path string
|
||||||
trapFilePath string
|
trapFilePath string
|
||||||
Package *packages.Package
|
Package *packages.Package
|
||||||
|
TypesOverride map[ast.Expr]types.Type
|
||||||
|
ObjectsOverride map[types.Object]types.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
func FileFor(path string) (string, error) {
|
func FileFor(path string) (string, error) {
|
||||||
|
@ -61,6 +64,8 @@ func NewWriter(path string, pkg *packages.Package) (*Writer, error) {
|
||||||
path,
|
path,
|
||||||
trapFilePath,
|
trapFilePath,
|
||||||
pkg,
|
pkg,
|
||||||
|
make(map[ast.Expr]types.Type),
|
||||||
|
make(map[types.Object]types.Object),
|
||||||
}
|
}
|
||||||
tw.Labeler = newLabeler(tw)
|
tw.Labeler = newLabeler(tw)
|
||||||
return tw, nil
|
return tw, nil
|
||||||
|
@ -104,11 +109,22 @@ func (tw *Writer) Close() error {
|
||||||
|
|
||||||
// ForEachObject iterates over all objects labeled by this labeler, and invokes
|
// 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
|
// the provided callback with a writer for the trap file, the object, and its
|
||||||
// label.
|
// label. It returns true if any extra objects were labeled and false otherwise.
|
||||||
func (tw *Writer) ForEachObject(cb func(*Writer, types.Object, Label)) {
|
func (tw *Writer) ForEachObject(cb func(*Writer, types.Object, Label)) bool {
|
||||||
for object, lbl := range tw.Labeler.objectLabels {
|
// copy the objects into an array so that our behaviour is deterministic even
|
||||||
cb(tw, object, lbl)
|
// 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
|
const max_strlen = 1024 * 1024
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -1,6 +1,6 @@
|
||||||
module github.com/github/codeql-go
|
module github.com/github/codeql-go
|
||||||
|
|
||||||
go 1.17
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
golang.org/x/mod v0.5.0
|
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);
|
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]
|
#keyset[parent, idx]
|
||||||
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
|
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);
|
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;
|
@container = @file | @folder;
|
||||||
|
|
||||||
@locatable = @xmllocatable | @node | @localscope;
|
@locatable = @xmllocatable | @node | @localscope;
|
||||||
|
|
||||||
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @scopenode
|
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
|
||||||
| @comment_group | @comment;
|
| @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;
|
@modexprparent = @file | @modexpr;
|
||||||
|
|
||||||
|
@ -244,6 +250,8 @@ variadic(int id: @signaturetype ref);
|
||||||
|
|
||||||
@declparent = @file | @declstmt;
|
@declparent = @file | @declstmt;
|
||||||
|
|
||||||
|
@typeparamdeclparent = @funcdecl | @typespec;
|
||||||
|
|
||||||
@funcdef = @funclit | @funcdecl;
|
@funcdef = @funclit | @funcdecl;
|
||||||
|
|
||||||
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
|
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
|
||||||
|
@ -270,46 +278,49 @@ case @expr.kind of
|
||||||
| 10 = @parenexpr
|
| 10 = @parenexpr
|
||||||
| 11 = @selectorexpr
|
| 11 = @selectorexpr
|
||||||
| 12 = @indexexpr
|
| 12 = @indexexpr
|
||||||
| 13 = @sliceexpr
|
| 13 = @genericfunctioninstantiationexpr
|
||||||
| 14 = @typeassertexpr
|
| 14 = @generictypeinstantiationexpr
|
||||||
| 15 = @callorconversionexpr
|
| 15 = @sliceexpr
|
||||||
| 16 = @starexpr
|
| 16 = @typeassertexpr
|
||||||
| 17 = @keyvalueexpr
|
| 17 = @callorconversionexpr
|
||||||
| 18 = @arraytypeexpr
|
| 18 = @starexpr
|
||||||
| 19 = @structtypeexpr
|
| 19 = @keyvalueexpr
|
||||||
| 20 = @functypeexpr
|
| 20 = @arraytypeexpr
|
||||||
| 21 = @interfacetypeexpr
|
| 21 = @structtypeexpr
|
||||||
| 22 = @maptypeexpr
|
| 22 = @functypeexpr
|
||||||
| 23 = @plusexpr
|
| 23 = @interfacetypeexpr
|
||||||
| 24 = @minusexpr
|
| 24 = @maptypeexpr
|
||||||
| 25 = @notexpr
|
| 25 = @typesetliteralexpr
|
||||||
| 26 = @complementexpr
|
| 26 = @plusexpr
|
||||||
| 27 = @derefexpr
|
| 27 = @minusexpr
|
||||||
| 28 = @addressexpr
|
| 28 = @notexpr
|
||||||
| 29 = @arrowexpr
|
| 29 = @complementexpr
|
||||||
| 30 = @lorexpr
|
| 30 = @derefexpr
|
||||||
| 31 = @landexpr
|
| 31 = @addressexpr
|
||||||
| 32 = @eqlexpr
|
| 32 = @arrowexpr
|
||||||
| 33 = @neqexpr
|
| 33 = @lorexpr
|
||||||
| 34 = @lssexpr
|
| 34 = @landexpr
|
||||||
| 35 = @leqexpr
|
| 35 = @eqlexpr
|
||||||
| 36 = @gtrexpr
|
| 36 = @neqexpr
|
||||||
| 37 = @geqexpr
|
| 37 = @lssexpr
|
||||||
| 38 = @addexpr
|
| 38 = @leqexpr
|
||||||
| 39 = @subexpr
|
| 39 = @gtrexpr
|
||||||
| 40 = @orexpr
|
| 40 = @geqexpr
|
||||||
| 41 = @xorexpr
|
| 41 = @addexpr
|
||||||
| 42 = @mulexpr
|
| 42 = @subexpr
|
||||||
| 43 = @quoexpr
|
| 43 = @orexpr
|
||||||
| 44 = @remexpr
|
| 44 = @xorexpr
|
||||||
| 45 = @shlexpr
|
| 45 = @mulexpr
|
||||||
| 46 = @shrexpr
|
| 46 = @quoexpr
|
||||||
| 47 = @andexpr
|
| 47 = @remexpr
|
||||||
| 48 = @andnotexpr
|
| 48 = @shlexpr
|
||||||
| 49 = @sendchantypeexpr
|
| 49 = @shrexpr
|
||||||
| 50 = @recvchantypeexpr
|
| 50 = @andexpr
|
||||||
| 51 = @sendrcvchantypeexpr
|
| 51 = @andnotexpr
|
||||||
| 52 = @errorexpr;
|
| 52 = @sendchantypeexpr
|
||||||
|
| 53 = @recvchantypeexpr
|
||||||
|
| 54 = @sendrcvchantypeexpr
|
||||||
|
| 55 = @errorexpr;
|
||||||
|
|
||||||
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
|
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
|
||||||
|
|
||||||
|
@ -430,6 +441,8 @@ case @object.kind of
|
||||||
| 7 = @builtinfunctionobject
|
| 7 = @builtinfunctionobject
|
||||||
| 8 = @labelobject;
|
| 8 = @labelobject;
|
||||||
|
|
||||||
|
@typeparamparentobject = @decltypeobject | @declfunctionobject;
|
||||||
|
|
||||||
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
|
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
|
||||||
|
|
||||||
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
|
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
|
||||||
|
@ -476,18 +489,20 @@ case @type.kind of
|
||||||
| 23 = @complexliteraltype
|
| 23 = @complexliteraltype
|
||||||
| 24 = @stringliteraltype
|
| 24 = @stringliteraltype
|
||||||
| 25 = @nilliteraltype
|
| 25 = @nilliteraltype
|
||||||
| 26 = @arraytype
|
| 26 = @typeparamtype
|
||||||
| 27 = @slicetype
|
| 27 = @arraytype
|
||||||
| 28 = @structtype
|
| 28 = @slicetype
|
||||||
| 29 = @pointertype
|
| 29 = @structtype
|
||||||
| 30 = @interfacetype
|
| 30 = @pointertype
|
||||||
| 31 = @tupletype
|
| 31 = @interfacetype
|
||||||
| 32 = @signaturetype
|
| 32 = @tupletype
|
||||||
| 33 = @maptype
|
| 33 = @signaturetype
|
||||||
| 34 = @sendchantype
|
| 34 = @maptype
|
||||||
| 35 = @recvchantype
|
| 35 = @sendchantype
|
||||||
| 36 = @sendrcvchantype
|
| 36 = @recvchantype
|
||||||
| 37 = @namedtype;
|
| 37 = @sendrcvchantype
|
||||||
|
| 38 = @namedtype
|
||||||
|
| 39 = @typesetliteraltype;
|
||||||
|
|
||||||
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
|
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
|
||||||
|
|
||||||
|
@ -510,7 +525,8 @@ case @type.kind of
|
||||||
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
|
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
|
||||||
| @stringliteraltype | @nilliteraltype;
|
| @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;
|
@containertype = @arraytype | @slicetype | @maptype | @chantype;
|
||||||
|
|
||||||
|
|
|
@ -216,6 +216,24 @@ class FieldParent extends @fieldparent, AstNode {
|
||||||
int getNumFields() { result = count(getAField()) }
|
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.
|
* An AST node which may induce a scope.
|
||||||
*
|
*
|
||||||
|
|
|
@ -146,7 +146,7 @@ class FuncDef extends @funcdef, StmtParent, ExprParent {
|
||||||
/**
|
/**
|
||||||
* A function declaration.
|
* 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. */
|
/** Gets the identifier denoting the name of this function. */
|
||||||
Ident getNameExpr() { result = this.getChildExpr(0) }
|
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. */
|
/** Gets the identifier denoting the name of the declared type. */
|
||||||
Ident getNameExpr() { result = this.getChildExpr(0) }
|
Ident getNameExpr() { result = this.getChildExpr(0) }
|
||||||
|
|
||||||
|
@ -562,6 +562,57 @@ class ResultVariableDecl extends ParameterOrResultDecl {
|
||||||
override string getAPrimaryQlClass() { result = "ResultVariableDecl" }
|
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.
|
* 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.
|
* An index expression, that is, a base expression followed by an index.
|
||||||
|
* Expressions which represent generic type instantiations have been
|
||||||
|
* excluded.
|
||||||
*
|
*
|
||||||
* Examples:
|
* Examples:
|
||||||
*
|
*
|
||||||
* ```go
|
* ```go
|
||||||
* a[i]
|
* array[i]
|
||||||
|
* arrayptr[i]
|
||||||
|
* slice[i]
|
||||||
|
* map[key]
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class IndexExpr extends @indexexpr, Expr {
|
class IndexExpr extends @indexexpr, Expr {
|
||||||
|
IndexExpr() { not isTypeExprBottomUp(this.getChildExpr(0)) }
|
||||||
|
|
||||||
/** Gets the base of this index expression. */
|
/** Gets the base of this index expression. */
|
||||||
Expr getBase() { result = this.getChildExpr(0) }
|
Expr getBase() { result = this.getChildExpr(0) }
|
||||||
|
|
||||||
|
@ -647,6 +654,68 @@ class IndexExpr extends @indexexpr, Expr {
|
||||||
override string getAPrimaryQlClass() { result = "IndexExpr" }
|
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.
|
* 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. */
|
/** 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). */
|
/** Gets the `i`th argument expression of this call (0-based). */
|
||||||
Expr getArgument(int i) {
|
Expr getArgument(int i) {
|
||||||
|
@ -995,6 +1068,22 @@ class MapTypeExpr extends @maptypeexpr, TypeExpr {
|
||||||
override string getAPrimaryQlClass() { result = "MapTypeExpr" }
|
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.
|
* 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.
|
* a bottom-up analysis. In such cases, `isTypeExprTopDown` below is useful.
|
||||||
*/
|
*/
|
||||||
private predicate isTypeExprBottomUp(Expr e) {
|
private predicate isTypeExprBottomUp(Expr e) {
|
||||||
e instanceof TypeName or
|
e instanceof TypeName
|
||||||
e instanceof @arraytypeexpr or
|
or
|
||||||
e instanceof @structtypeexpr or
|
e instanceof @arraytypeexpr
|
||||||
e instanceof @functypeexpr or
|
or
|
||||||
e instanceof @interfacetypeexpr or
|
e instanceof @structtypeexpr
|
||||||
e instanceof @maptypeexpr or
|
or
|
||||||
e instanceof @chantypeexpr or
|
e instanceof @functypeexpr
|
||||||
isTypeExprBottomUp(e.(ParenExpr).getExpr()) or
|
or
|
||||||
isTypeExprBottomUp(e.(StarExpr).getBase()) 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())
|
isTypeExprBottomUp(e.(Ellipsis).getOperand())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1989,6 +2093,10 @@ private predicate isTypeExprTopDown(Expr e) {
|
||||||
or
|
or
|
||||||
e = any(ParameterDecl pd).getTypeExpr()
|
e = any(ParameterDecl pd).getTypeExpr()
|
||||||
or
|
or
|
||||||
|
e = any(TypeParamDecl tpd).getTypeConstraintExpr()
|
||||||
|
or
|
||||||
|
e = any(TypeParamDecl tpd).getNameExpr(_)
|
||||||
|
or
|
||||||
e = any(ReceiverDecl rd).getTypeExpr()
|
e = any(ReceiverDecl rd).getTypeExpr()
|
||||||
or
|
or
|
||||||
e = any(ResultVariableDecl rvd).getTypeExpr()
|
e = any(ResultVariableDecl rvd).getTypeExpr()
|
||||||
|
@ -2005,6 +2113,10 @@ private predicate isTypeExprTopDown(Expr e) {
|
||||||
or
|
or
|
||||||
e = any(TypeSpec s).getTypeExpr()
|
e = any(TypeSpec s).getTypeExpr()
|
||||||
or
|
or
|
||||||
|
e = any(GenericTypeInstantiationExpr gtie).getBase()
|
||||||
|
or
|
||||||
|
e = any(GenericTypeInstantiationExpr gtie).getTypeArgument(_)
|
||||||
|
or
|
||||||
e = any(TypeSwitchStmt s).getACase().getExpr(_) and
|
e = any(TypeSwitchStmt s).getACase().getExpr(_) and
|
||||||
// special case: `nil` is allowed in a type case but isn't a type
|
// special case: `nil` is allowed in a type case but isn't a type
|
||||||
not e = Builtin::nil().getAReference()
|
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`
|
* 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) {
|
predicate implements(InterfaceType i) {
|
||||||
isEmptyInterface(i)
|
if i = any(ComparableType comparable).getUnderlyingType()
|
||||||
or
|
then this.implementsComparable()
|
||||||
this.hasMethod(getExampleMethodName(i), _) and
|
else this.implementsNotComparable(i)
|
||||||
forall(string m, SignatureType t | i.hasMethod(m, t) | this.hasMethod(m, t))
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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`,
|
* 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) {
|
predicate implements(string pkg, string name) {
|
||||||
exists(Type t | t.hasQualifiedName(pkg, name) | this.implements(t.getUnderlyingType()))
|
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. */
|
/** A composite type, that is, not a basic type. */
|
||||||
class CompositeType extends @compositetype, 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. */
|
/** An array type. */
|
||||||
class ArrayType extends @arraytype, CompositeType {
|
class ArrayType extends @arraytype, CompositeType {
|
||||||
/** Gets the element type of this array type. */
|
/** Gets the element type of this array type. */
|
||||||
|
@ -532,33 +609,269 @@ class PointerType extends @pointertype, CompositeType {
|
||||||
override string toString() { result = "pointer type" }
|
override string toString() { result = "pointer type" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An interface type. */
|
private newtype TTypeSetTerm =
|
||||||
class InterfaceType extends @interfacetype, CompositeType {
|
MkTypeSetTerm(TypeSetLiteralType tslit, int index) { component_types(tslit, index, _, _) }
|
||||||
/** Gets the type of method `name` of this interface type. */
|
|
||||||
Type getMethodType(string name) { component_types(this, _, name, result) }
|
|
||||||
|
|
||||||
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]
|
language[monotonicAggregates]
|
||||||
override string pp() {
|
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 =
|
meth =
|
||||||
concat(string name, Type tp |
|
concat(string name, Type tp |
|
||||||
tp = this.getMethodType(name)
|
tp = this.getMethodType(name)
|
||||||
|
|
|
|
||||||
" " + name + " " + tp.pp(), ";" order by 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" }
|
override string toString() { result = "interface type" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An empty interface type. */
|
// This predicate is needed for performance reasons.
|
||||||
class EmptyInterfaceType extends InterfaceType {
|
pragma[noinline]
|
||||||
EmptyInterfaceType() { not this.hasMethod(_, _) }
|
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. */
|
/** A tuple type. */
|
||||||
|
@ -693,12 +1006,6 @@ class ErrorType extends Type {
|
||||||
ErrorType() { this.implements(Builtin::error().getType().getUnderlyingType()) }
|
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`.
|
* 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
|
not this.(SelectorExpr).getBase() instanceof ValueExpr and
|
||||||
nd = mkExprOrSkipNode(this) and
|
nd = mkExprOrSkipNode(this) and
|
||||||
cmpl = Done()
|
cmpl = Done()
|
||||||
|
or
|
||||||
|
this instanceof GenericFunctionInstantiationExpr and
|
||||||
|
nd = MkExprNode(this) and
|
||||||
|
cmpl = Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate firstNode(ControlFlow::Node first) { first = nd }
|
override predicate firstNode(ControlFlow::Node first) { first = nd }
|
||||||
|
|
|
@ -443,7 +443,8 @@ module Public {
|
||||||
*/
|
*/
|
||||||
private DataFlow::Node getACalleeSource(DataFlow::CallNode cn) {
|
private DataFlow::Node getACalleeSource(DataFlow::CallNode cn) {
|
||||||
result = cn.getCalleeNode() or
|
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. */
|
/** 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(
|
files(
|
||||||
unique int id: @file,
|
unique int id: @file,
|
||||||
string name: string ref,
|
string name: string ref
|
||||||
string simple: string ref,
|
|
||||||
string ext: string ref,
|
|
||||||
int fromSource: int ref // deprecated
|
|
||||||
);
|
);
|
||||||
|
|
||||||
folders(
|
folders(
|
||||||
unique int id: @folder,
|
unique int id: @folder,
|
||||||
string name: string ref,
|
string name: string ref
|
||||||
string simple: string ref
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@container = @folder | @file
|
@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: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 | 0 | main.go:9:15:9:15 | x |
|
||||||
| main.go:9:12:9:13 | f2 | 1 | main.go:9:18:9:18 | y |
|
| 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: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: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 |
|
| 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: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: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 |
|
| 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: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: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 |
|
| 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.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.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 |
|
| 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: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: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 |
|
| 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 | 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 | 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 |
|
| 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 |
|
| B | 2 |
|
||||||
| C | 2 |
|
| C | 2 |
|
||||||
| Foo | 1 |
|
| Foo | 1 |
|
||||||
|
| GenericInterface | 1 |
|
||||||
|
| MyInterface | 17 |
|
||||||
| T | 1 |
|
| T | 1 |
|
||||||
| T3 | 1 |
|
| T3 | 1 |
|
||||||
| T4 | 1 |
|
| T4 | 1 |
|
||||||
|
@ -20,4 +22,14 @@
|
||||||
| embedder | 1 |
|
| embedder | 1 |
|
||||||
| embedder2 | 1 |
|
| embedder2 | 1 |
|
||||||
| embedder3 | 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 |
|
| ptrembedder | 2 |
|
||||||
|
|
|
@ -10,6 +10,24 @@
|
||||||
| B | n | func() |
|
| B | n | func() |
|
||||||
| C | n | func() |
|
| C | n | func() |
|
||||||
| C | o | 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 |
|
| T | half | func() Foo |
|
||||||
| T3 | half | func() Foo |
|
| T3 | half | func() Foo |
|
||||||
| T4 | half | func() Foo |
|
| T4 | half | func() Foo |
|
||||||
|
@ -17,5 +35,19 @@
|
||||||
| embedder2 | f | func() int |
|
| embedder2 | f | func() int |
|
||||||
| embedder3 | f | func() int |
|
| embedder3 | f | func() int |
|
||||||
| embedder4 | 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 | f | func() int |
|
||||||
| ptrembedder | g | 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 | 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 | 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 |
|
| 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 | 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 | 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 |
|
| 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 | n | pkg1/interfaces.go:13:2:13:2 | n |
|
||||||
| C | o | pkg1/interfaces.go:14:2:14:2 | o |
|
| C | o | pkg1/interfaces.go:14:2:14:2 | o |
|
||||||
| Foo | half | pkg1/tst.go:33:16:33:19 | half |
|
| 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 |
|
| T | half | pkg1/tst.go:33:16:33:19 | half |
|
||||||
| T3 | 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 |
|
| T4 | half | pkg1/tst.go:33:16:33:19 | half |
|
||||||
|
@ -30,5 +48,19 @@
|
||||||
| embedder | f | pkg1/embedding.go:10:13:10:13 | f |
|
| embedder | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||||
| embedder2 | 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 |
|
| 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 | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||||
| ptrembedder | g | pkg1/embedding.go:14:14:14:14 | g |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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/pkg1.T |
|
||||||
| T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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:5:1:5:30 | function declaration | 1 |
|
||||||
| main.go:7:1:9:1 | function declaration | 2 |
|
| main.go:7:1:9:1 | function declaration | 2 |
|
||||||
| main.go:11:1:11:14 | function declaration | 0 |
|
| main.go:11:1:11:14 | function declaration | 0 |
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
| depth.go:22:1:25:1 | function declaration | 0 |
|
| 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:5:1:5:30 | function declaration | 0 |
|
||||||
| main.go:7:1:9:1 | function declaration | 2 |
|
| main.go:7:1:9:1 | function declaration | 2 |
|
||||||
| main.go:11:1:11:14 | function declaration | 0 |
|
| 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 |
|
| Bar | pkg1/tst.go:29:10:31:1 | struct type | flag | bool |
|
||||||
| Baz | embedded.go:3:10:5:1 | struct type | A | string |
|
| 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 | Baz | string |
|
||||||
| EmbedsBaz | embedded.go:12:16:15:1 | struct type | Qux | Qux |
|
| 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 | flag | bool |
|
||||||
| Foo | pkg1/tst.go:24:10:27:1 | struct type | val | int |
|
| 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:3:8:5:1 | struct type | g | int |
|
||||||
| G | pkg2/tst.go:7:8:9: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 | A | string |
|
||||||
| Qux | embedded.go:7:10:9:1 | struct type | Baz | * Baz |
|
| Qux | embedded.go:7:10:9:1 | struct type | Baz | * Baz |
|
||||||
| T | pkg1/tst.go:3:8:7:1 | struct type | Bar | Bar |
|
| 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 | Foo | * Foo |
|
||||||
| T4 | pkg1/tst.go:19:9:22:1 | struct type | flag | bool |
|
| T4 | pkg1/tst.go:19:9:22:1 | struct type | flag | bool |
|
||||||
| T4 | pkg1/tst.go:19:9:22:1 | struct type | val | int |
|
| 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 | b | b |
|
||||||
| a | depth.go:5:8:8:1 | struct type | c | c |
|
| a | depth.go:5:8:8:1 | struct type | c | c |
|
||||||
| a | depth.go:5:8:8:1 | struct type | d | d |
|
| a | depth.go:5:8:8:1 | struct type | d | d |
|
||||||
|
|
|
@ -7,15 +7,36 @@
|
||||||
| Bar | Bar |
|
| Bar | Bar |
|
||||||
| Baz | Baz |
|
| Baz | Baz |
|
||||||
| C | C |
|
| C | C |
|
||||||
|
| CircularGenericStruct1 | CircularGenericStruct1 |
|
||||||
|
| CircularGenericStruct2 | CircularGenericStruct2 |
|
||||||
| EmbedsBaz | EmbedsBaz |
|
| EmbedsBaz | EmbedsBaz |
|
||||||
| Foo | Foo |
|
| Foo | Foo |
|
||||||
| G | G |
|
| 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 |
|
| Qux | Qux |
|
||||||
| T | T |
|
| T | T |
|
||||||
| T | T |
|
| T | T |
|
||||||
| T2 | T2 |
|
| T2 | T2 |
|
||||||
| T3 | T3 |
|
| T3 | T3 |
|
||||||
| T4 | T4 |
|
| T4 | T4 |
|
||||||
|
| UsesCircularGenericStruct1 | UsesCircularGenericStruct1 |
|
||||||
| a | a |
|
| a | a |
|
||||||
| b | b |
|
| b | b |
|
||||||
| base | base |
|
| base | base |
|
||||||
|
@ -25,8 +46,54 @@
|
||||||
| embedder2 | embedder2 |
|
| embedder2 | embedder2 |
|
||||||
| embedder3 | embedder3 |
|
| embedder3 | embedder3 |
|
||||||
| embedder4 | embedder4 |
|
| 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 |
|
| ptrembedder | ptrembedder |
|
||||||
| s | s |
|
| s | s |
|
||||||
| t | t |
|
| 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 |
|
| u | u |
|
||||||
| v | v |
|
| 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 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:16:94:16 | (...) is true | exprs.go:94:9:94:21 | ...\|\|... |
|
||||||
| exprs.go:94:21:94:21 | z | 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: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: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 |
|
| 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 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:16:94:16 | (...) is true | exprs.go:94:9:94:21 | ...\|\|... |
|
||||||
| exprs.go:94:21:94:21 | z | 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: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: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 |
|
| 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: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: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: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: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: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 |
|
| 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: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: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: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: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: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 |
|
| 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: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: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: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: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: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 | |
|
| 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: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: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: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: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: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: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: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: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:13:107:33 | type conversion |
|
||||||
| test.go:106:9:106:13 | &... : pointer type | test.go:107:20:107:26 | implicit dereference : MyStruct |
|
| 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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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 |
|
| 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: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: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: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: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: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: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: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: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: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 |
|
| 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 |
|
||||||
|
|
Загрузка…
Ссылка в новой задаче