Skip to content

Commit ab99509

Browse files
committed
Rework interface for querying private interface method ids
1 parent 0f95a8d commit ab99509

File tree

3 files changed

+12
-24
lines changed

3 files changed

+12
-24
lines changed

go/ql/lib/change-notes/2024-09-03-tags-and-interface-ids.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
category: minorAnalysis
33
---
44
* Added member predicates `StructTag.hasOwnFieldWithTag` and `Field.getTag`, which enable CodeQL queries to examine struct field tags.
5-
* Added member predicate `InterfaceType.getMethodTypeByQualifiedName`, which enables CodeQL queries to distinguish interfaces with matching non-exported method names that are declared in different packages, and are therefore incompatible.
5+
* 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.

go/ql/lib/semmle/go/Types.qll

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -769,29 +769,13 @@ class InterfaceType extends @interfacetype, CompositeType {
769769
}
770770

771771
/**
772-
* Gets the type of method `qname` of this interface type.
773-
*
774-
* This differs from `getMethodType` in that if the method is not exported, the `qname`
775-
* will be package-qualified. This means that the set of `qname`s` together with any
776-
* embedded types fully distinguishes the interface from any other, whereas the set
777-
* of names matched by `getMethodName` may be ambiguous between interfaces with matching
778-
* exported methods and unexported methods that have matching names but belong to
779-
* different packages.
780-
*
781-
* For example, `interface { Exported() int; notExported() int }` declared in two
782-
* different packages defines two distinct types, but they appear identical according to
783-
* `getMethodType`. If the packages were named `a` and `b`, `getMethodType` would yield
784-
* `notExported -> int` for both, whereas this method would yield `a.notExported -> int`
785-
* and `b.notExported -> int` respectively, while both yielding `Exported -> int`.
772+
* Holds if this interface type has a private method `name`,
773+
* with qualified name `qname` and type `type`.
786774
*/
787-
Type getMethodTypeByQualifiedName(string qname) {
788-
exists(int i, string name | i >= 0 |
789-
component_types(this, i, name, result) and
790-
(
791-
interface_private_method_ids(this, i, qname)
792-
or
793-
name = qname and not interface_private_method_ids(this, i, _)
794-
)
775+
predicate hasPrivateMethodWithQualifiedName(string name, string qname, Type type) {
776+
exists(int i | i >= 0 |
777+
component_types(this, i, name, type) and
778+
interface_private_method_ids(this, i, qname)
795779
)
796780
}
797781

go/ql/test/library-tests/semmle/go/Types/InterfaceMethodIds.ql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@ from NamedType nt, InterfaceType it, Type methodType, string id
44
where
55
nt.getName() = "MixedExportedAndNot" and
66
it = nt.getUnderlyingType() and
7-
methodType = it.getMethodTypeByQualifiedName(id)
7+
(
8+
it.hasPrivateMethodWithQualifiedName(_, id, methodType)
9+
or
10+
it.hasMethod(id, methodType) and not it.hasPrivateMethodWithQualifiedName(id, _, _)
11+
)
812
select it.pp(), methodType.pp(), id

0 commit comments

Comments
 (0)