Extract generic function instantiations to new table

This commit is contained in:
Owen Mansel-Chan
2022-01-27 15:01:17 +00:00
committed by Chris Smowton
parent b8ab46d969
commit e84db95f9c
4 changed files with 104 additions and 44 deletions

View File

@@ -371,9 +371,15 @@ var ParenExpr = ExprKind.NewBranch("@parenexpr")
// SelectorExpr is the type of selector expression AST nodes
var SelectorExpr = ExprKind.NewBranch("@selectorexpr")
// IndexExpr is the type of index expression AST nodes
// IndexExpr is the type of index expression AST nodes which are not generic type
// instantiation expressions
var IndexExpr = ExprKind.NewBranch("@indexexpr")
// GenericFunctionInstantiationExpr is the type of AST nodes that represent a 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")
// SliceExpr is the type of slice expression AST nodes
var SliceExpr = ExprKind.NewBranch("@sliceexpr")

View File

@@ -877,9 +877,24 @@ func extractExpr(tw *trap.Writer, expr ast.Expr, parent trap.Label, idx int) {
if expr == nil {
return
}
kind = dbscheme.IndexExpr.Index()
switch tp := tw.Package.TypesInfo.TypeOf(expr.X).Underlying().(type) {
case *types.Signature:
kind = dbscheme.GenericFunctionInstantiationExpr.Index()
case *types.Map, *types.Array, *types.Slice, *types.Basic, *types.Pointer:
// map, array, slice, string or pointer to array
kind = dbscheme.IndexExpr.Index()
default:
log.Fatalf("unsupported IndexExpr: its base expression is a %s.", tp.String())
}
extractExpr(tw, expr.X, lbl, 0)
extractExpr(tw, expr.Index, lbl, 1)
case *ast.IndexListExpr:
if expr == nil {
return
}
kind = dbscheme.GenericFunctionInstantiationExpr.Index()
extractExpr(tw, expr.X, lbl, 0)
extractExprs(tw, expr.Indices, lbl, 1, 1)
case *ast.SliceExpr:
if expr == nil {
return

View File

@@ -272,46 +272,47 @@ case @expr.kind of
| 10 = @parenexpr
| 11 = @selectorexpr
| 12 = @indexexpr
| 13 = @sliceexpr
| 14 = @typeassertexpr
| 15 = @callorconversionexpr
| 16 = @starexpr
| 17 = @keyvalueexpr
| 18 = @arraytypeexpr
| 19 = @structtypeexpr
| 20 = @functypeexpr
| 21 = @interfacetypeexpr
| 22 = @maptypeexpr
| 23 = @plusexpr
| 24 = @minusexpr
| 25 = @notexpr
| 26 = @complementexpr
| 27 = @derefexpr
| 28 = @addressexpr
| 29 = @arrowexpr
| 30 = @lorexpr
| 31 = @landexpr
| 32 = @eqlexpr
| 33 = @neqexpr
| 34 = @lssexpr
| 35 = @leqexpr
| 36 = @gtrexpr
| 37 = @geqexpr
| 38 = @addexpr
| 39 = @subexpr
| 40 = @orexpr
| 41 = @xorexpr
| 42 = @mulexpr
| 43 = @quoexpr
| 44 = @remexpr
| 45 = @shlexpr
| 46 = @shrexpr
| 47 = @andexpr
| 48 = @andnotexpr
| 49 = @sendchantypeexpr
| 50 = @recvchantypeexpr
| 51 = @sendrcvchantypeexpr
| 52 = @errorexpr;
| 13 = @genericfunctioninstantiationexpr
| 14 = @sliceexpr
| 15 = @typeassertexpr
| 16 = @callorconversionexpr
| 17 = @starexpr
| 18 = @keyvalueexpr
| 19 = @arraytypeexpr
| 20 = @structtypeexpr
| 21 = @functypeexpr
| 22 = @interfacetypeexpr
| 23 = @maptypeexpr
| 24 = @plusexpr
| 25 = @minusexpr
| 26 = @notexpr
| 27 = @complementexpr
| 28 = @derefexpr
| 29 = @addressexpr
| 30 = @arrowexpr
| 31 = @lorexpr
| 32 = @landexpr
| 33 = @eqlexpr
| 34 = @neqexpr
| 35 = @lssexpr
| 36 = @leqexpr
| 37 = @gtrexpr
| 38 = @geqexpr
| 39 = @addexpr
| 40 = @subexpr
| 41 = @orexpr
| 42 = @xorexpr
| 43 = @mulexpr
| 44 = @quoexpr
| 45 = @remexpr
| 46 = @shlexpr
| 47 = @shrexpr
| 48 = @andexpr
| 49 = @andnotexpr
| 50 = @sendchantypeexpr
| 51 = @recvchantypeexpr
| 52 = @sendrcvchantypeexpr
| 53 = @errorexpr;
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;

View File

@@ -626,11 +626,16 @@ class PromotedSelector extends SelectorExpr {
/**
* An index expression, that is, a base expression followed by an index.
* Expressions which represent generic type instantiations have been
* excluded.
*
* Examples:
*
* ```go
* a[i]
* array[i]
* arrayptr[i]
* slice[i]
* map[key]
* ```
*/
class IndexExpr extends @indexexpr, Expr {
@@ -647,6 +652,34 @@ class IndexExpr extends @indexexpr, Expr {
override string getAPrimaryQlClass() { result = "IndexExpr" }
}
/**
* A generic function instantiation, that is, a base expression that represents
* a generic function, followed by a list of type arguments.
*
* Examples:
*
* ```go
* genericfunction[type]
* genericfunction[type1, type2]
* ```
*/
class GenericFunctionInstantiationExpr extends @genericfunctioninstantiationexpr, Expr {
/** Gets the generic 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 function instantiation expression" }
override string getAPrimaryQlClass() { result = "GenericFunctionInstantiationExpr" }
}
/**
* A slice expression, that is, a base expression followed by slice indices.
*
@@ -797,11 +830,16 @@ class CallExpr extends CallOrConversionExpr {
result = callee.(Ident).getName()
or
result = callee.(SelectorExpr).getSelector().getName()
or
result = callee.(GenericFunctionInstantiationExpr).getBase().(Ident).getName()
)
}
/** Gets the declared target of this call. */
Function getTarget() { this.getCalleeExpr() = result.getAReference() }
Function getTarget() {
this.getCalleeExpr() = result.getAReference() or
this.getCalleeExpr().(GenericFunctionInstantiationExpr).getBase() = result.getAReference()
}
/** Holds if this call has an ellipsis after its last argument. */
predicate hasEllipsis() { has_ellipsis(this) }