Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go: extract and expose struct tags, interface method IDs #17357

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
546 changes: 546 additions & 0 deletions go/downgrades/4bd57e093275e5e892dfb16b55ed4bd76ea662be/go.dbscheme

Large diffs are not rendered by default.

552 changes: 552 additions & 0 deletions go/downgrades/4bd57e093275e5e892dfb16b55ed4bd76ea662be/old.dbscheme

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
description: Remove component-tags and interface-method-id tables
compatibility: full

struct_tags.rel: delete
interface_private_method_ids.rel: delete
2 changes: 1 addition & 1 deletion go/extractor/dbscheme/dbscheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ func AddDefaultSnippet(snippet string) bool {

// PrintDbScheme prints the schema of this database to the writer `w`
func PrintDbScheme(w io.Writer) {
fmt.Fprintf(w, "/** Auto-generated dbscheme; do not edit. */\n\n")
fmt.Fprintf(w, "/** Auto-generated dbscheme; do not edit. Run `make gen` in directory `go/` to regenerate. */\n\n")
smowton marked this conversation as resolved.
Show resolved Hide resolved
for _, snippet := range defaultSnippets {
fmt.Fprintf(w, "%s\n", snippet)
}
Expand Down
14 changes: 14 additions & 0 deletions go/extractor/dbscheme/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,20 @@ var ComponentTypesTable = NewTable("component_types",
EntityColumn(TypeType, "tp"),
).KeySet("parent", "index")

// StructTagsTable is the table associating struct types with their component types' tags
var StructTagsTable = NewTable("struct_tags",
EntityColumn(StructType, "parent"),
IntColumn("index"),
StringColumn("tag"),
).KeySet("parent", "index")

// InterfacePrivateMethodIdsTable is the table associating interface types with the indices and ids of their private methods.
var InterfacePrivateMethodIdsTable = NewTable("interface_private_method_ids",
EntityColumn(InterfaceType, "interface"),
IntColumn("index"),
StringColumn("id"),
).KeySet("interface", "index")

// ArrayLengthTable is the table associating array types with their length (represented as a string
// since Go array lengths are 64-bit and hence do not always fit into a QL integer)
var ArrayLengthTable = NewTable("array_length",
Expand Down
7 changes: 7 additions & 0 deletions go/extractor/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1624,6 +1624,9 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
name = ""
}
extractComponentType(tw, lbl, i, name, field.Type())
if tp.Tag(i) != "" {
dbscheme.StructTagsTable.Emit(tw, lbl, i, tp.Tag(i))
}
}
case *types.Pointer:
kind = dbscheme.PointerType.Index()
Expand All @@ -1641,6 +1644,10 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
extractMethod(tw, meth)

extractComponentType(tw, lbl, i, meth.Name(), meth.Type())

if !meth.Exported() {
dbscheme.InterfacePrivateMethodIdsTable.Emit(tw, lbl, i, meth.Id())
}
}
for i := 0; i < tp.NumEmbeddeds(); i++ {
component := tp.EmbeddedType(i)
Expand Down
5 changes: 5 additions & 0 deletions go/ql/lib/change-notes/2024-09-03-tags-and-interface-ids.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added member predicates `StructTag.hasOwnFieldWithTag` and `Field.getTag`, which enable CodeQL queries to examine struct field tags.
* Added member predicate `InterfaceType.hasPrivateMethodWithQualifiedName`, which enables CodeQL queries to distinguish interfaces with matching non-exported method names that are declared in different packages, and are therefore incompatible.
8 changes: 7 additions & 1 deletion go/ql/lib/go.dbscheme
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** Auto-generated dbscheme; do not edit. */
/** Auto-generated dbscheme; do not edit. Run `make gen` in directory `go/` to regenerate. */


/** Duplicate code **/
Expand Down Expand Up @@ -207,6 +207,12 @@ 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);

#keyset[parent, index]
struct_tags(int parent: @structtype ref, int index: int ref, string tag: string ref);

#keyset[interface, index]
interface_private_method_ids(int interface: @interfacetype ref, int index: int ref, string id: string ref);

array_length(unique int tp: @arraytype ref, string len: string ref);

type_objects(unique int tp: @type ref, int object: @object ref);
Expand Down
Loading
Loading