Skip to content

Commit d7b1d7b

Browse files
authored
Merge pull request #19677 from owen-mc/go/better-class-names-and-helpers
Go: Improve two class names and add some helper predicates
2 parents 6803bf3 + ecd0291 commit d7b1d7b

File tree

7 files changed

+140
-28
lines changed

7 files changed

+140
-28
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: deprecated
3+
---
4+
* The class `BuiltinType` is now deprecated. Use the new replacement `BuiltinTypeEntity` instead.
5+
* The class `DeclaredType` is now deprecated. Use the new replacement `DeclaredTypeEntity` instead.

go/ql/lib/semmle/go/Decls.qll

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,20 @@ class TypeSpec extends @typespec, Spec, TypeParamDeclParent {
381381
string getName() { result = this.getNameExpr().getName() }
382382

383383
/**
384-
* Gets the expression denoting the underlying type to which the newly declared type is bound.
384+
* Gets the declared type of this specifier.
385+
*
386+
* Note that for alias types this will give the underlying type.
387+
*/
388+
Type getDeclaredType() { result = this.getNameExpr().getType() }
389+
390+
/**
391+
* Gets the expression denoting the underlying type to which the declared type is bound.
385392
*/
386393
Expr getTypeExpr() { result = this.getChildExpr(1) }
387394

395+
/** Gets the underlying type to which the declared type is bound. */
396+
Type getRhsType() { result = this.getTypeExpr().getType() }
397+
388398
override string toString() { result = "type declaration specifier" }
389399

390400
override string getAPrimaryQlClass() { result = "TypeSpec" }
@@ -461,6 +471,7 @@ class FieldBase extends @field, ExprParent {
461471
* Examples:
462472
*
463473
* ```go
474+
* io.Reader
464475
* Name string `json:"name"`
465476
* x, y int
466477
* ```
@@ -469,8 +480,9 @@ class FieldBase extends @field, ExprParent {
469480
*
470481
* ```go
471482
* struct {
472-
* Name string `json:"name"`
473-
* x, y int
483+
* io.Reader // embedded field
484+
* Name string `json:"name"` // field with tag
485+
* x, y int // declares two fields with the same type
474486
* }
475487
* ```
476488
*/
@@ -482,12 +494,24 @@ class FieldDecl extends FieldBase, Documentable, ExprParent {
482494
/**
483495
* Gets the expression representing the name of the `i`th field declared in this declaration
484496
* (0-based).
497+
*
498+
* This is not defined for embedded fields.
485499
*/
486500
Expr getNameExpr(int i) {
487501
i >= 0 and
488502
result = this.getChildExpr(i + 1)
489503
}
490504

505+
/**
506+
* Gets the `i`th field declared in this declaration (0-based).
507+
*
508+
* This is not defined for embedded fields.
509+
*/
510+
Field getField(int i) { this.getNameExpr(i).(Ident).declares(result) }
511+
512+
/** Holds if this field declaration declares an embedded type. */
513+
predicate isEmbedded() { not exists(this.getNameExpr(_)) }
514+
491515
/** Gets the tag expression of this field declaration, if any. */
492516
Expr getTag() { result = this.getChildExpr(-1) }
493517

go/ql/lib/semmle/go/Scopes.qll

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,19 @@ class TypeEntity extends Entity, @typeobject { }
202202
class TypeParamParentEntity extends Entity, @typeparamparentobject { }
203203

204204
/** A named type which has a declaration. */
205-
class DeclaredType extends TypeEntity, DeclaredEntity, TypeParamParentEntity, @decltypeobject {
205+
class DeclaredTypeEntity extends TypeEntity, DeclaredEntity, TypeParamParentEntity, @decltypeobject {
206206
/** Gets the declaration specifier declaring this type. */
207207
TypeSpec getSpec() { result.getNameExpr() = this.getDeclaration() }
208208
}
209209

210+
/** DEPRECATED: Use `DeclaredTypeEntity` instead. */
211+
deprecated class DeclaredType = DeclaredTypeEntity;
212+
210213
/** A built-in type. */
211-
class BuiltinType extends TypeEntity, BuiltinEntity, @builtintypeobject { }
214+
class BuiltinTypeEntity extends TypeEntity, BuiltinEntity, @builtintypeobject { }
215+
216+
/** DEPRECATED: Use `BuiltinTypeEntity` instead. */
217+
deprecated class BuiltinType = BuiltinTypeEntity;
212218

213219
/** A built-in or declared constant, variable, field, method or function. */
214220
class ValueEntity extends Entity, @valueobject {
@@ -754,64 +760,64 @@ private predicate builtinFunction(
754760
module Builtin {
755761
// built-in types
756762
/** Gets the built-in type `bool`. */
757-
BuiltinType bool() { result.getName() = "bool" }
763+
BuiltinTypeEntity bool() { result.getName() = "bool" }
758764

759765
/** Gets the built-in type `byte`. */
760-
BuiltinType byte() { result.getName() = "byte" }
766+
BuiltinTypeEntity byte() { result.getName() = "byte" }
761767

762768
/** Gets the built-in type `complex64`. */
763-
BuiltinType complex64() { result.getName() = "complex64" }
769+
BuiltinTypeEntity complex64() { result.getName() = "complex64" }
764770

765771
/** Gets the built-in type `complex128`. */
766-
BuiltinType complex128() { result.getName() = "complex128" }
772+
BuiltinTypeEntity complex128() { result.getName() = "complex128" }
767773

768774
/** Gets the built-in type `error`. */
769-
BuiltinType error() { result.getName() = "error" }
775+
BuiltinTypeEntity error() { result.getName() = "error" }
770776

771777
/** Gets the built-in type `float32`. */
772-
BuiltinType float32() { result.getName() = "float32" }
778+
BuiltinTypeEntity float32() { result.getName() = "float32" }
773779

774780
/** Gets the built-in type `float64`. */
775-
BuiltinType float64() { result.getName() = "float64" }
781+
BuiltinTypeEntity float64() { result.getName() = "float64" }
776782

777783
/** Gets the built-in type `int`. */
778-
BuiltinType int_() { result.getName() = "int" }
784+
BuiltinTypeEntity int_() { result.getName() = "int" }
779785

780786
/** Gets the built-in type `int8`. */
781-
BuiltinType int8() { result.getName() = "int8" }
787+
BuiltinTypeEntity int8() { result.getName() = "int8" }
782788

783789
/** Gets the built-in type `int16`. */
784-
BuiltinType int16() { result.getName() = "int16" }
790+
BuiltinTypeEntity int16() { result.getName() = "int16" }
785791

786792
/** Gets the built-in type `int32`. */
787-
BuiltinType int32() { result.getName() = "int32" }
793+
BuiltinTypeEntity int32() { result.getName() = "int32" }
788794

789795
/** Gets the built-in type `int64`. */
790-
BuiltinType int64() { result.getName() = "int64" }
796+
BuiltinTypeEntity int64() { result.getName() = "int64" }
791797

792798
/** Gets the built-in type `rune`. */
793-
BuiltinType rune() { result.getName() = "rune" }
799+
BuiltinTypeEntity rune() { result.getName() = "rune" }
794800

795801
/** Gets the built-in type `string`. */
796-
BuiltinType string_() { result.getName() = "string" }
802+
BuiltinTypeEntity string_() { result.getName() = "string" }
797803

798804
/** Gets the built-in type `uint`. */
799-
BuiltinType uint() { result.getName() = "uint" }
805+
BuiltinTypeEntity uint() { result.getName() = "uint" }
800806

801807
/** Gets the built-in type `uint8`. */
802-
BuiltinType uint8() { result.getName() = "uint8" }
808+
BuiltinTypeEntity uint8() { result.getName() = "uint8" }
803809

804810
/** Gets the built-in type `uint16`. */
805-
BuiltinType uint16() { result.getName() = "uint16" }
811+
BuiltinTypeEntity uint16() { result.getName() = "uint16" }
806812

807813
/** Gets the built-in type `uint32`. */
808-
BuiltinType uint32() { result.getName() = "uint32" }
814+
BuiltinTypeEntity uint32() { result.getName() = "uint32" }
809815

810816
/** Gets the built-in type `uint64`. */
811-
BuiltinType uint64() { result.getName() = "uint64" }
817+
BuiltinTypeEntity uint64() { result.getName() = "uint64" }
812818

813819
/** Gets the built-in type `uintptr`. */
814-
BuiltinType uintptr() { result.getName() = "uintptr" }
820+
BuiltinTypeEntity uintptr() { result.getName() = "uintptr" }
815821

816822
// built-in constants
817823
/** Gets the built-in constant `true`. */
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
| main.go:3:6:3:15 | type declaration specifier | status | int | def |
2-
| main.go:5:6:5:20 | type declaration specifier | intlist | []int | alias |
1+
| main.go:3:6:3:15 | type declaration specifier | status | status | main.go:3:13:3:15 | int | int | def |
2+
| main.go:5:6:5:20 | type declaration specifier | intlist | []int | main.go:5:16:5:20 | array type | []int | alias |

go/ql/test/library-tests/semmle/go/Decl/TypeSpec.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ import go
22

33
from TypeSpec ts, string kind
44
where if ts instanceof AliasSpec then kind = "alias" else kind = "def"
5-
select ts, ts.getName(), ts.getTypeExpr().getType().pp(), kind
5+
select ts, ts.getName(), ts.getDeclaredType().pp(), ts.getTypeExpr(), ts.getRhsType().pp(), kind
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
fieldDeclWithNamedFields
2+
| aliases.go:6:26:6:35 | field declaration | 0 | aliases.go:6:26:6:26 | x |
3+
| aliases.go:6:26:6:35 | field declaration | 0 | aliases.go:8:26:8:26 | x |
4+
| aliases.go:6:26:6:35 | field declaration | 0 | aliases.go:19:17:19:17 | x |
5+
| aliases.go:8:26:8:35 | field declaration | 0 | aliases.go:6:26:6:26 | x |
6+
| aliases.go:8:26:8:35 | field declaration | 0 | aliases.go:8:26:8:26 | x |
7+
| aliases.go:8:26:8:35 | field declaration | 0 | aliases.go:19:17:19:17 | x |
8+
| aliases.go:19:17:19:21 | field declaration | 0 | aliases.go:6:26:6:26 | x |
9+
| aliases.go:19:17:19:21 | field declaration | 0 | aliases.go:8:26:8:26 | x |
10+
| aliases.go:19:17:19:21 | field declaration | 0 | aliases.go:19:17:19:17 | x |
11+
| aliases.go:29:34:29:42 | field declaration | 0 | aliases.go:29:34:29:34 | x |
12+
| cyclic.go:9:2:9:6 | field declaration | 0 | cyclic.go:9:2:9:2 | f |
13+
| depth.go:11:2:11:6 | field declaration | 0 | depth.go:11:2:11:2 | f |
14+
| depth.go:19:2:19:9 | field declaration | 0 | depth.go:19:2:19:2 | f |
15+
| embedded.go:4:2:4:9 | field declaration | 0 | embedded.go:4:2:4:2 | A |
16+
| embedded.go:13:2:13:11 | field declaration | 0 | embedded.go:13:2:13:4 | Baz |
17+
| generic.go:4:2:4:15 | field declaration | 0 | generic.go:4:2:4:11 | valueField |
18+
| generic.go:5:2:5:16 | field declaration | 0 | generic.go:5:2:5:13 | pointerField |
19+
| generic.go:6:2:6:19 | field declaration | 0 | generic.go:6:2:6:11 | arrayField |
20+
| generic.go:7:2:7:17 | field declaration | 0 | generic.go:7:2:7:11 | sliceField |
21+
| generic.go:8:2:8:26 | field declaration | 0 | generic.go:8:2:8:9 | mapField |
22+
| generic.go:12:2:12:40 | field declaration | 0 | generic.go:12:2:12:13 | pointerField |
23+
| generic.go:16:2:16:31 | field declaration | 0 | generic.go:16:2:16:5 | root |
24+
| generic.go:20:2:20:30 | field declaration | 0 | generic.go:20:2:20:12 | structField |
25+
| generic.go:21:2:21:20 | field declaration | 0 | generic.go:21:2:21:9 | mapField |
26+
| generic.go:25:2:25:33 | field declaration | 0 | generic.go:25:2:25:12 | structField |
27+
| generic.go:29:2:29:43 | field declaration | 0 | generic.go:29:2:29:13 | pointerField |
28+
| pkg1/embedding.go:37:2:37:6 | field declaration | 0 | pkg1/embedding.go:37:2:37:2 | f |
29+
| pkg1/promotedStructs.go:5:2:5:14 | field declaration | 0 | pkg1/promotedStructs.go:5:2:5:7 | SField |
30+
| pkg1/promotedStructs.go:14:2:14:14 | field declaration | 0 | pkg1/promotedStructs.go:14:2:14:7 | PField |
31+
| pkg1/tst.go:6:2:6:6 | field declaration | 0 | pkg1/tst.go:6:2:6:2 | f |
32+
| pkg1/tst.go:12:2:12:8 | field declaration | 0 | pkg1/tst.go:12:2:12:4 | Foo |
33+
| pkg1/tst.go:23:2:23:8 | field declaration | 0 | pkg1/tst.go:23:2:23:4 | Bar |
34+
| pkg1/tst.go:27:2:27:9 | field declaration | 0 | pkg1/tst.go:27:2:27:4 | val |
35+
| pkg1/tst.go:28:2:28:10 | field declaration | 0 | pkg1/tst.go:28:2:28:5 | flag |
36+
| pkg1/tst.go:32:2:32:10 | field declaration | 0 | pkg1/tst.go:32:2:32:5 | flag |
37+
| pkg2/tst.go:4:2:4:6 | field declaration | 0 | pkg2/tst.go:4:2:4:2 | g |
38+
| pkg2/tst.go:4:2:4:6 | field declaration | 0 | pkg2/tst.go:8:2:8:2 | g |
39+
| pkg2/tst.go:8:2:8:6 | field declaration | 0 | pkg2/tst.go:4:2:4:2 | g |
40+
| pkg2/tst.go:8:2:8:6 | field declaration | 0 | pkg2/tst.go:8:2:8:2 | g |
41+
| pkg2/tst.go:17:2:17:15 | field declaration | 0 | pkg2/tst.go:17:2:17:8 | NCField |
42+
| struct_tags.go:4:2:4:19 | field declaration | 0 | struct_tags.go:4:2:4:7 | field1 |
43+
| struct_tags.go:5:2:5:19 | field declaration | 0 | struct_tags.go:5:2:5:7 | field2 |
44+
| struct_tags.go:9:2:9:19 | field declaration | 0 | struct_tags.go:9:2:9:7 | field1 |
45+
| struct_tags.go:10:2:10:19 | field declaration | 0 | struct_tags.go:10:2:10:7 | field2 |
46+
fieldDeclWithEmbeddedField
47+
| cyclic.go:4:2:4:3 | field declaration | * s |
48+
| cyclic.go:8:2:8:3 | field declaration | * u |
49+
| cyclic.go:13:2:13:2 | field declaration | t |
50+
| cyclic.go:17:2:17:2 | field declaration | s |
51+
| depth.go:6:2:6:2 | field declaration | b |
52+
| depth.go:7:2:7:2 | field declaration | c |
53+
| depth.go:15:2:15:2 | field declaration | d |
54+
| embedded.go:8:2:8:5 | field declaration | * Baz |
55+
| embedded.go:12:2:12:4 | field declaration | Qux |
56+
| main.go:18:2:18:15 | field declaration | NameClash |
57+
| pkg1/embedding.go:19:23:19:26 | field declaration | base |
58+
| pkg1/embedding.go:22:26:22:30 | field declaration | * base |
59+
| pkg1/embedding.go:25:24:25:31 | field declaration | embedder |
60+
| pkg1/embedding.go:28:24:28:31 | field declaration | embedder |
61+
| pkg1/embedding.go:36:2:36:5 | field declaration | base |
62+
| pkg1/promotedStructs.go:22:22:22:22 | field declaration | S |
63+
| pkg1/promotedStructs.go:25:22:25:22 | field declaration | P |
64+
| pkg1/tst.go:7:2:7:4 | field declaration | Foo |
65+
| pkg1/tst.go:8:2:8:4 | field declaration | Bar |
66+
| pkg1/tst.go:13:2:13:4 | field declaration | Bar |
67+
| pkg1/tst.go:17:2:17:5 | field declaration | * Foo |
68+
| pkg1/tst.go:18:2:18:5 | field declaration | * Bar |
69+
| pkg1/tst.go:22:2:22:5 | field declaration | * Foo |
70+
| pkg1/tst.go:62:2:62:15 | field declaration | NameClash |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import go
2+
3+
query predicate fieldDeclWithNamedFields(FieldDecl fd, int i, Field f) { fd.getField(i) = f }
4+
5+
query predicate fieldDeclWithEmbeddedField(FieldDecl fd, string tp) {
6+
fd.isEmbedded() and tp = fd.getType().pp()
7+
}

0 commit comments

Comments
 (0)