Merge pull request #19677 from owen-mc/go/better-class-names-and-helpers

Go: Improve two class names and add some helper predicates
This commit is contained in:
Owen Mansel-Chan
2025-06-26 00:17:32 +01:00
committed by GitHub
7 changed files with 140 additions and 28 deletions

View File

@@ -0,0 +1,5 @@
---
category: deprecated
---
* The class `BuiltinType` is now deprecated. Use the new replacement `BuiltinTypeEntity` instead.
* The class `DeclaredType` is now deprecated. Use the new replacement `DeclaredTypeEntity` instead.

View File

@@ -381,10 +381,20 @@ class TypeSpec extends @typespec, Spec, TypeParamDeclParent {
string getName() { result = this.getNameExpr().getName() }
/**
* Gets the expression denoting the underlying type to which the newly declared type is bound.
* Gets the declared type of this specifier.
*
* Note that for alias types this will give the underlying type.
*/
Type getDeclaredType() { result = this.getNameExpr().getType() }
/**
* Gets the expression denoting the underlying type to which the declared type is bound.
*/
Expr getTypeExpr() { result = this.getChildExpr(1) }
/** Gets the underlying type to which the declared type is bound. */
Type getRhsType() { result = this.getTypeExpr().getType() }
override string toString() { result = "type declaration specifier" }
override string getAPrimaryQlClass() { result = "TypeSpec" }
@@ -461,6 +471,7 @@ class FieldBase extends @field, ExprParent {
* Examples:
*
* ```go
* io.Reader
* Name string `json:"name"`
* x, y int
* ```
@@ -469,8 +480,9 @@ class FieldBase extends @field, ExprParent {
*
* ```go
* struct {
* Name string `json:"name"`
* x, y int
* io.Reader // embedded field
* Name string `json:"name"` // field with tag
* x, y int // declares two fields with the same type
* }
* ```
*/
@@ -482,12 +494,24 @@ class FieldDecl extends FieldBase, Documentable, ExprParent {
/**
* Gets the expression representing the name of the `i`th field declared in this declaration
* (0-based).
*
* This is not defined for embedded fields.
*/
Expr getNameExpr(int i) {
i >= 0 and
result = this.getChildExpr(i + 1)
}
/**
* Gets the `i`th field declared in this declaration (0-based).
*
* This is not defined for embedded fields.
*/
Field getField(int i) { this.getNameExpr(i).(Ident).declares(result) }
/** Holds if this field declaration declares an embedded type. */
predicate isEmbedded() { not exists(this.getNameExpr(_)) }
/** Gets the tag expression of this field declaration, if any. */
Expr getTag() { result = this.getChildExpr(-1) }

View File

@@ -202,13 +202,19 @@ class TypeEntity extends Entity, @typeobject { }
class TypeParamParentEntity extends Entity, @typeparamparentobject { }
/** A named type which has a declaration. */
class DeclaredType extends TypeEntity, DeclaredEntity, TypeParamParentEntity, @decltypeobject {
class DeclaredTypeEntity extends TypeEntity, DeclaredEntity, TypeParamParentEntity, @decltypeobject {
/** Gets the declaration specifier declaring this type. */
TypeSpec getSpec() { result.getNameExpr() = this.getDeclaration() }
}
/** DEPRECATED: Use `DeclaredTypeEntity` instead. */
deprecated class DeclaredType = DeclaredTypeEntity;
/** A built-in type. */
class BuiltinType extends TypeEntity, BuiltinEntity, @builtintypeobject { }
class BuiltinTypeEntity extends TypeEntity, BuiltinEntity, @builtintypeobject { }
/** DEPRECATED: Use `BuiltinTypeEntity` instead. */
deprecated class BuiltinType = BuiltinTypeEntity;
/** A built-in or declared constant, variable, field, method or function. */
class ValueEntity extends Entity, @valueobject {
@@ -754,64 +760,64 @@ private predicate builtinFunction(
module Builtin {
// built-in types
/** Gets the built-in type `bool`. */
BuiltinType bool() { result.getName() = "bool" }
BuiltinTypeEntity bool() { result.getName() = "bool" }
/** Gets the built-in type `byte`. */
BuiltinType byte() { result.getName() = "byte" }
BuiltinTypeEntity byte() { result.getName() = "byte" }
/** Gets the built-in type `complex64`. */
BuiltinType complex64() { result.getName() = "complex64" }
BuiltinTypeEntity complex64() { result.getName() = "complex64" }
/** Gets the built-in type `complex128`. */
BuiltinType complex128() { result.getName() = "complex128" }
BuiltinTypeEntity complex128() { result.getName() = "complex128" }
/** Gets the built-in type `error`. */
BuiltinType error() { result.getName() = "error" }
BuiltinTypeEntity error() { result.getName() = "error" }
/** Gets the built-in type `float32`. */
BuiltinType float32() { result.getName() = "float32" }
BuiltinTypeEntity float32() { result.getName() = "float32" }
/** Gets the built-in type `float64`. */
BuiltinType float64() { result.getName() = "float64" }
BuiltinTypeEntity float64() { result.getName() = "float64" }
/** Gets the built-in type `int`. */
BuiltinType int_() { result.getName() = "int" }
BuiltinTypeEntity int_() { result.getName() = "int" }
/** Gets the built-in type `int8`. */
BuiltinType int8() { result.getName() = "int8" }
BuiltinTypeEntity int8() { result.getName() = "int8" }
/** Gets the built-in type `int16`. */
BuiltinType int16() { result.getName() = "int16" }
BuiltinTypeEntity int16() { result.getName() = "int16" }
/** Gets the built-in type `int32`. */
BuiltinType int32() { result.getName() = "int32" }
BuiltinTypeEntity int32() { result.getName() = "int32" }
/** Gets the built-in type `int64`. */
BuiltinType int64() { result.getName() = "int64" }
BuiltinTypeEntity int64() { result.getName() = "int64" }
/** Gets the built-in type `rune`. */
BuiltinType rune() { result.getName() = "rune" }
BuiltinTypeEntity rune() { result.getName() = "rune" }
/** Gets the built-in type `string`. */
BuiltinType string_() { result.getName() = "string" }
BuiltinTypeEntity string_() { result.getName() = "string" }
/** Gets the built-in type `uint`. */
BuiltinType uint() { result.getName() = "uint" }
BuiltinTypeEntity uint() { result.getName() = "uint" }
/** Gets the built-in type `uint8`. */
BuiltinType uint8() { result.getName() = "uint8" }
BuiltinTypeEntity uint8() { result.getName() = "uint8" }
/** Gets the built-in type `uint16`. */
BuiltinType uint16() { result.getName() = "uint16" }
BuiltinTypeEntity uint16() { result.getName() = "uint16" }
/** Gets the built-in type `uint32`. */
BuiltinType uint32() { result.getName() = "uint32" }
BuiltinTypeEntity uint32() { result.getName() = "uint32" }
/** Gets the built-in type `uint64`. */
BuiltinType uint64() { result.getName() = "uint64" }
BuiltinTypeEntity uint64() { result.getName() = "uint64" }
/** Gets the built-in type `uintptr`. */
BuiltinType uintptr() { result.getName() = "uintptr" }
BuiltinTypeEntity uintptr() { result.getName() = "uintptr" }
// built-in constants
/** Gets the built-in constant `true`. */

View File

@@ -1,2 +1,2 @@
| main.go:3:6:3:15 | type declaration specifier | status | int | def |
| main.go:5:6:5:20 | type declaration specifier | intlist | []int | alias |
| main.go:3:6:3:15 | type declaration specifier | status | status | main.go:3:13:3:15 | int | int | def |
| main.go:5:6:5:20 | type declaration specifier | intlist | []int | main.go:5:16:5:20 | array type | []int | alias |

View File

@@ -2,4 +2,4 @@ import go
from TypeSpec ts, string kind
where if ts instanceof AliasSpec then kind = "alias" else kind = "def"
select ts, ts.getName(), ts.getTypeExpr().getType().pp(), kind
select ts, ts.getName(), ts.getDeclaredType().pp(), ts.getTypeExpr(), ts.getRhsType().pp(), kind

View File

@@ -0,0 +1,70 @@
fieldDeclWithNamedFields
| aliases.go:6:26:6:35 | field declaration | 0 | aliases.go:6:26:6:26 | x |
| aliases.go:6:26:6:35 | field declaration | 0 | aliases.go:8:26:8:26 | x |
| aliases.go:6:26:6:35 | field declaration | 0 | aliases.go:19:17:19:17 | x |
| aliases.go:8:26:8:35 | field declaration | 0 | aliases.go:6:26:6:26 | x |
| aliases.go:8:26:8:35 | field declaration | 0 | aliases.go:8:26:8:26 | x |
| aliases.go:8:26:8:35 | field declaration | 0 | aliases.go:19:17:19:17 | x |
| aliases.go:19:17:19:21 | field declaration | 0 | aliases.go:6:26:6:26 | x |
| aliases.go:19:17:19:21 | field declaration | 0 | aliases.go:8:26:8:26 | x |
| aliases.go:19:17:19:21 | field declaration | 0 | aliases.go:19:17:19:17 | x |
| aliases.go:29:34:29:42 | field declaration | 0 | aliases.go:29:34:29:34 | x |
| cyclic.go:9:2:9:6 | field declaration | 0 | cyclic.go:9:2:9:2 | f |
| depth.go:11:2:11:6 | field declaration | 0 | depth.go:11:2:11:2 | f |
| depth.go:19:2:19:9 | field declaration | 0 | depth.go:19:2:19:2 | f |
| embedded.go:4:2:4:9 | field declaration | 0 | embedded.go:4:2:4:2 | A |
| embedded.go:13:2:13:11 | field declaration | 0 | embedded.go:13:2:13:4 | Baz |
| generic.go:4:2:4:15 | field declaration | 0 | generic.go:4:2:4:11 | valueField |
| generic.go:5:2:5:16 | field declaration | 0 | generic.go:5:2:5:13 | pointerField |
| generic.go:6:2:6:19 | field declaration | 0 | generic.go:6:2:6:11 | arrayField |
| generic.go:7:2:7:17 | field declaration | 0 | generic.go:7:2:7:11 | sliceField |
| generic.go:8:2:8:26 | field declaration | 0 | generic.go:8:2:8:9 | mapField |
| generic.go:12:2:12:40 | field declaration | 0 | generic.go:12:2:12:13 | pointerField |
| generic.go:16:2:16:31 | field declaration | 0 | generic.go:16:2:16:5 | root |
| generic.go:20:2:20:30 | field declaration | 0 | generic.go:20:2:20:12 | structField |
| generic.go:21:2:21:20 | field declaration | 0 | generic.go:21:2:21:9 | mapField |
| generic.go:25:2:25:33 | field declaration | 0 | generic.go:25:2:25:12 | structField |
| generic.go:29:2:29:43 | field declaration | 0 | generic.go:29:2:29:13 | pointerField |
| pkg1/embedding.go:37:2:37:6 | field declaration | 0 | pkg1/embedding.go:37:2:37:2 | f |
| pkg1/promotedStructs.go:5:2:5:14 | field declaration | 0 | pkg1/promotedStructs.go:5:2:5:7 | SField |
| pkg1/promotedStructs.go:14:2:14:14 | field declaration | 0 | pkg1/promotedStructs.go:14:2:14:7 | PField |
| pkg1/tst.go:6:2:6:6 | field declaration | 0 | pkg1/tst.go:6:2:6:2 | f |
| pkg1/tst.go:12:2:12:8 | field declaration | 0 | pkg1/tst.go:12:2:12:4 | Foo |
| pkg1/tst.go:23:2:23:8 | field declaration | 0 | pkg1/tst.go:23:2:23:4 | Bar |
| pkg1/tst.go:27:2:27:9 | field declaration | 0 | pkg1/tst.go:27:2:27:4 | val |
| pkg1/tst.go:28:2:28:10 | field declaration | 0 | pkg1/tst.go:28:2:28:5 | flag |
| pkg1/tst.go:32:2:32:10 | field declaration | 0 | pkg1/tst.go:32:2:32:5 | flag |
| pkg2/tst.go:4:2:4:6 | field declaration | 0 | pkg2/tst.go:4:2:4:2 | g |
| pkg2/tst.go:4:2:4:6 | field declaration | 0 | pkg2/tst.go:8:2:8:2 | g |
| pkg2/tst.go:8:2:8:6 | field declaration | 0 | pkg2/tst.go:4:2:4:2 | g |
| pkg2/tst.go:8:2:8:6 | field declaration | 0 | pkg2/tst.go:8:2:8:2 | g |
| pkg2/tst.go:17:2:17:15 | field declaration | 0 | pkg2/tst.go:17:2:17:8 | NCField |
| struct_tags.go:4:2:4:19 | field declaration | 0 | struct_tags.go:4:2:4:7 | field1 |
| struct_tags.go:5:2:5:19 | field declaration | 0 | struct_tags.go:5:2:5:7 | field2 |
| struct_tags.go:9:2:9:19 | field declaration | 0 | struct_tags.go:9:2:9:7 | field1 |
| struct_tags.go:10:2:10:19 | field declaration | 0 | struct_tags.go:10:2:10:7 | field2 |
fieldDeclWithEmbeddedField
| cyclic.go:4:2:4:3 | field declaration | * s |
| cyclic.go:8:2:8:3 | field declaration | * u |
| cyclic.go:13:2:13:2 | field declaration | t |
| cyclic.go:17:2:17:2 | field declaration | s |
| depth.go:6:2:6:2 | field declaration | b |
| depth.go:7:2:7:2 | field declaration | c |
| depth.go:15:2:15:2 | field declaration | d |
| embedded.go:8:2:8:5 | field declaration | * Baz |
| embedded.go:12:2:12:4 | field declaration | Qux |
| main.go:18:2:18:15 | field declaration | NameClash |
| pkg1/embedding.go:19:23:19:26 | field declaration | base |
| pkg1/embedding.go:22:26:22:30 | field declaration | * base |
| pkg1/embedding.go:25:24:25:31 | field declaration | embedder |
| pkg1/embedding.go:28:24:28:31 | field declaration | embedder |
| pkg1/embedding.go:36:2:36:5 | field declaration | base |
| pkg1/promotedStructs.go:22:22:22:22 | field declaration | S |
| pkg1/promotedStructs.go:25:22:25:22 | field declaration | P |
| pkg1/tst.go:7:2:7:4 | field declaration | Foo |
| pkg1/tst.go:8:2:8:4 | field declaration | Bar |
| pkg1/tst.go:13:2:13:4 | field declaration | Bar |
| pkg1/tst.go:17:2:17:5 | field declaration | * Foo |
| pkg1/tst.go:18:2:18:5 | field declaration | * Bar |
| pkg1/tst.go:22:2:22:5 | field declaration | * Foo |
| pkg1/tst.go:62:2:62:15 | field declaration | NameClash |

View File

@@ -0,0 +1,7 @@
import go
query predicate fieldDeclWithNamedFields(FieldDecl fd, int i, Field f) { fd.getField(i) = f }
query predicate fieldDeclWithEmbeddedField(FieldDecl fd, string tp) {
fd.isEmbedded() and tp = fd.getType().pp()
}