mirror of
https://github.com/github/codeql.git
synced 2026-01-29 06:12:58 +01:00
Extract type parameters in types, not just decls
This commit is contained in:
committed by
Chris Smowton
parent
213fa1fec2
commit
92c331402d
@@ -682,6 +682,9 @@ var ObjectType = NewPrimaryKeyType("@object")
|
||||
// ObjectKind is a case type for distinguishing different kinds of built-in and declared objects
|
||||
var ObjectKind = NewCaseType(ObjectType, "kind")
|
||||
|
||||
// TypeParamParentObjectType is the type of objects that can have type parameters as children
|
||||
var TypeParamParentObjectType = NewUnionType("@typeparamparentobject")
|
||||
|
||||
// DeclObjectType is the type of declared objects
|
||||
var DeclObjectType = NewUnionType("@declobject")
|
||||
|
||||
@@ -695,7 +698,7 @@ var PkgObjectType = ObjectKind.NewBranch("@pkgobject")
|
||||
var TypeObjectType = NewUnionType("@typeobject")
|
||||
|
||||
// DeclTypeObjectType is the type of declared named types
|
||||
var DeclTypeObjectType = ObjectKind.NewBranch("@decltypeobject", TypeObjectType, DeclObjectType)
|
||||
var DeclTypeObjectType = ObjectKind.NewBranch("@decltypeobject", TypeObjectType, DeclObjectType, TypeParamParentObjectType)
|
||||
|
||||
// BuiltinTypeObjectType is the type of built-in named types
|
||||
var BuiltinTypeObjectType = ObjectKind.NewBranch("@builtintypeobject", TypeObjectType, BuiltinObjectType)
|
||||
@@ -722,7 +725,7 @@ var DeclVarObjectType = ObjectKind.NewBranch("@declvarobject", VarObjectType, De
|
||||
var FunctionObjectType = NewUnionType("@functionobject", ValueObjectType)
|
||||
|
||||
// DeclFuncObjectType is the type of declared functions, including (abstract and concrete) methods
|
||||
var DeclFuncObjectType = ObjectKind.NewBranch("@declfunctionobject", FunctionObjectType, DeclObjectType)
|
||||
var DeclFuncObjectType = ObjectKind.NewBranch("@declfunctionobject", FunctionObjectType, DeclObjectType, TypeParamParentObjectType)
|
||||
|
||||
// BuiltinFuncObjectType is the type of built-in functions
|
||||
var BuiltinFuncObjectType = ObjectKind.NewBranch("@builtinfunctionobject", FunctionObjectType, BuiltinObjectType)
|
||||
@@ -1206,8 +1209,11 @@ var VariadicTable = NewTable("variadic",
|
||||
EntityColumn(SignatureType, "id"),
|
||||
)
|
||||
|
||||
// TypeParamTable is the table describing type parameter types
|
||||
var TypeParamTable = NewTable("typeparam",
|
||||
EntityColumn(TypeParamType, "tp").Unique(),
|
||||
StringColumn("name"),
|
||||
EntityColumn(CompositeType, "bound"),
|
||||
)
|
||||
EntityColumn(TypeParamParentObjectType, "parent"),
|
||||
IntColumn("idx"),
|
||||
).KeySet("parent", "idx")
|
||||
|
||||
@@ -363,6 +363,15 @@ func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label)
|
||||
obj := scope.Lookup(name)
|
||||
lbl, exists := tw.Labeler.ScopedObjectID(obj, func() trap.Label { return extractType(tw, obj.Type()) })
|
||||
if !exists {
|
||||
if funcObj, ok := obj.(*types.Func); ok {
|
||||
populateTypeParamParents(tw, funcObj.Type().(*types.Signature).TypeParams(), lbl)
|
||||
populateTypeParamParents(tw, funcObj.Type().(*types.Signature).RecvTypeParams(), lbl)
|
||||
}
|
||||
if typeNameObj, ok := obj.(*types.TypeName); ok {
|
||||
if tp, ok := typeNameObj.Type().(*types.Named); ok {
|
||||
populateTypeParamParents(tw, tp.TypeParams(), lbl)
|
||||
}
|
||||
}
|
||||
extractObject(tw, obj, lbl)
|
||||
}
|
||||
|
||||
@@ -378,10 +387,14 @@ func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label)
|
||||
func extractMethod(tw *trap.Writer, meth *types.Func) trap.Label {
|
||||
// get the receiver type of the method
|
||||
recvtyp := meth.Type().(*types.Signature).Recv().Type()
|
||||
recvlbl := extractType(tw, recvtyp) // ensure receiver type has been extracted
|
||||
// ensure receiver type has been extracted
|
||||
recvlbl := extractType(tw, recvtyp)
|
||||
|
||||
// if the method label does not exist, extract it
|
||||
methlbl, exists := tw.Labeler.MethodID(meth, recvlbl)
|
||||
if !exists {
|
||||
populateTypeParamParents(tw, meth.Type().(*types.Signature).TypeParams(), methlbl)
|
||||
populateTypeParamParents(tw, meth.Type().(*types.Signature).RecvTypeParams(), methlbl)
|
||||
extractObject(tw, meth, methlbl)
|
||||
}
|
||||
|
||||
@@ -1512,7 +1525,12 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
||||
}
|
||||
case *types.TypeParam:
|
||||
kind = dbscheme.TypeParamType.Index()
|
||||
dbscheme.TypeParamTable.Emit(tw, lbl, tp.Obj().Name(), extractType(tw, tp.Constraint()))
|
||||
parentlbl, exists := tw.TypeParamParent[tp]
|
||||
if !exists {
|
||||
log.Fatalf("Parent of type parameter does not exist: %s", tp.String())
|
||||
}
|
||||
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++ {
|
||||
@@ -1651,7 +1669,8 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
|
||||
}
|
||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%s};namedtype", entitylbl))
|
||||
case *types.TypeParam:
|
||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%s},{%s};typeparamtype", tp.Obj().Name(), extractType(tw, tp.Constraint())))
|
||||
parentlbl := tw.TypeParamParent[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++ {
|
||||
@@ -1828,3 +1847,12 @@ func extractTypeParamDecls(tw *trap.Writer, fields *ast.FieldList, parent trap.L
|
||||
idx += 1
|
||||
}
|
||||
}
|
||||
|
||||
// populateTypeParamParents sets `parentlbl` as the parent of the elements of `typeparams`
|
||||
func populateTypeParamParents(tw *trap.Writer, typeparams *types.TypeParamList, parentlbl trap.Label) {
|
||||
if typeparams != nil {
|
||||
for idx := 0; idx < typeparams.Len(); idx++ {
|
||||
tw.TypeParamParent[typeparams.At(idx)] = parentlbl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,15 @@ import (
|
||||
|
||||
// A Writer provides methods for writing data to a TRAP file
|
||||
type Writer struct {
|
||||
zip *gzip.Writer
|
||||
w *bufio.Writer
|
||||
file *os.File
|
||||
Labeler *Labeler
|
||||
path string
|
||||
trapFilePath string
|
||||
Package *packages.Package
|
||||
TypesOverride map[ast.Expr]types.Type
|
||||
zip *gzip.Writer
|
||||
w *bufio.Writer
|
||||
file *os.File
|
||||
Labeler *Labeler
|
||||
path string
|
||||
trapFilePath string
|
||||
Package *packages.Package
|
||||
TypesOverride map[ast.Expr]types.Type
|
||||
TypeParamParent map[*types.TypeParam]Label
|
||||
}
|
||||
|
||||
func FileFor(path string) (string, error) {
|
||||
@@ -64,6 +65,7 @@ func NewWriter(path string, pkg *packages.Package) (*Writer, error) {
|
||||
trapFilePath,
|
||||
pkg,
|
||||
make(map[ast.Expr]types.Type),
|
||||
make(map[*types.TypeParam]Label),
|
||||
}
|
||||
tw.Labeler = newLabeler(tw)
|
||||
return tw, nil
|
||||
|
||||
@@ -227,7 +227,9 @@ has_ellipsis(int id: @callorconversionexpr ref);
|
||||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype 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;
|
||||
|
||||
@@ -248,7 +250,7 @@ typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound:
|
||||
|
||||
@declparent = @file | @declstmt;
|
||||
|
||||
@typeparamdeclparent = @functypeexpr | @typespec;
|
||||
@typeparamdeclparent = @funcdecl | @typespec;
|
||||
|
||||
@funcdef = @funclit | @funcdecl;
|
||||
|
||||
@@ -439,6 +441,8 @@ case @object.kind of
|
||||
| 7 = @builtinfunctionobject
|
||||
| 8 = @labelobject;
|
||||
|
||||
@typeparamparentobject = @decltypeobject | @declfunctionobject;
|
||||
|
||||
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
|
||||
|
||||
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
|
||||
|
||||
@@ -367,10 +367,10 @@ 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, _) }
|
||||
string getParamName() { typeparam(this, result, _, _, _) }
|
||||
|
||||
/** Gets the constraint of this type parameter type. */
|
||||
Type getConstraint() { typeparam(this, _, result) }
|
||||
Type getConstraint() { typeparam(this, _, result, _, _) }
|
||||
|
||||
override InterfaceType getUnderlyingType() { result = this.getConstraint().getUnderlyingType() }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user