mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Rename "named type" to "defined type"
This commit is contained in:
@@ -694,13 +694,13 @@ var BuiltinObjectType = NewUnionType("@builtinobject")
|
|||||||
// PkgObjectType is the type of imported packages
|
// PkgObjectType is the type of imported packages
|
||||||
var PkgObjectType = ObjectKind.NewBranch("@pkgobject")
|
var PkgObjectType = ObjectKind.NewBranch("@pkgobject")
|
||||||
|
|
||||||
// TypeObjectType is the type of declared or built-in named types
|
// TypeObjectType is the type of named types (predeclared types, defined types, type parameters and aliases which refer to those things)
|
||||||
var TypeObjectType = NewUnionType("@typeobject")
|
var TypeObjectType = NewUnionType("@typeobject")
|
||||||
|
|
||||||
// DeclTypeObjectType is the type of declared named types
|
// DeclTypeObjectType is the type of defined types, type parameters and aliases which refer to named types
|
||||||
var DeclTypeObjectType = ObjectKind.NewBranch("@decltypeobject", TypeObjectType, DeclObjectType, TypeParamParentObjectType)
|
var DeclTypeObjectType = ObjectKind.NewBranch("@decltypeobject", TypeObjectType, DeclObjectType, TypeParamParentObjectType)
|
||||||
|
|
||||||
// BuiltinTypeObjectType is the type of built-in named types
|
// BuiltinTypeObjectType is the type of built-in types (predeclared types)
|
||||||
var BuiltinTypeObjectType = ObjectKind.NewBranch("@builtintypeobject", TypeObjectType, BuiltinObjectType)
|
var BuiltinTypeObjectType = ObjectKind.NewBranch("@builtintypeobject", TypeObjectType, BuiltinObjectType)
|
||||||
|
|
||||||
// ValueObjectType is the type of declared or built-in variables or constants
|
// ValueObjectType is the type of declared or built-in variables or constants
|
||||||
@@ -855,8 +855,8 @@ var ChanTypes = map[gotypes.ChanDir]*BranchType{
|
|||||||
gotypes.SendRecv: TypeKind.NewBranch("@sendrcvchantype", ChanType),
|
gotypes.SendRecv: TypeKind.NewBranch("@sendrcvchantype", ChanType),
|
||||||
}
|
}
|
||||||
|
|
||||||
// NamedType is the type of named types
|
// DefinedType is the type of defined types
|
||||||
var NamedType = TypeKind.NewBranch("@namedtype", CompositeType)
|
var DefinedType = TypeKind.NewBranch("@namedtype", CompositeType)
|
||||||
|
|
||||||
// TypeSetLiteral is the type of type set literals
|
// TypeSetLiteral is the type of type set literals
|
||||||
var TypeSetLiteral = TypeKind.NewBranch("@typesetliteraltype", CompositeType)
|
var TypeSetLiteral = TypeKind.NewBranch("@typesetliteraltype", CompositeType)
|
||||||
@@ -1080,10 +1080,10 @@ var FieldStructsTable = NewTable("fieldstructs",
|
|||||||
EntityColumn(StructType, "struct"),
|
EntityColumn(StructType, "struct"),
|
||||||
)
|
)
|
||||||
|
|
||||||
// MethodHostsTable maps interface methods to the named type they belong to
|
// MethodHostsTable maps interface methods to the defined type they belong to
|
||||||
var MethodHostsTable = NewTable("methodhosts",
|
var MethodHostsTable = NewTable("methodhosts",
|
||||||
EntityColumn(ObjectType, "method"),
|
EntityColumn(ObjectType, "method"),
|
||||||
EntityColumn(NamedType, "host"),
|
EntityColumn(DefinedType, "host"),
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefsTable maps identifiers to the objects they define
|
// DefsTable maps identifiers to the objects they define
|
||||||
@@ -1110,7 +1110,7 @@ var TypeOfTable = NewTable("type_of",
|
|||||||
EntityColumn(TypeType, "tp"),
|
EntityColumn(TypeType, "tp"),
|
||||||
)
|
)
|
||||||
|
|
||||||
// TypeNameTable is the table associating named types with their names
|
// TypeNameTable is the table associating defined types with their names
|
||||||
var TypeNameTable = NewTable("typename",
|
var TypeNameTable = NewTable("typename",
|
||||||
EntityColumn(TypeType, "tp").Unique(),
|
EntityColumn(TypeType, "tp").Unique(),
|
||||||
StringColumn("name"),
|
StringColumn("name"),
|
||||||
@@ -1135,10 +1135,10 @@ var BaseTypeTable = NewTable("base_type",
|
|||||||
EntityColumn(TypeType, "tp"),
|
EntityColumn(TypeType, "tp"),
|
||||||
)
|
)
|
||||||
|
|
||||||
// UnderlyingTypeTable is the table associating named types with their
|
// UnderlyingTypeTable is the table associating defined types with their
|
||||||
// underlying type
|
// underlying type
|
||||||
var UnderlyingTypeTable = NewTable("underlying_type",
|
var UnderlyingTypeTable = NewTable("underlying_type",
|
||||||
EntityColumn(NamedType, "named").Unique(),
|
EntityColumn(DefinedType, "named").Unique(),
|
||||||
EntityColumn(TypeType, "tp"),
|
EntityColumn(TypeType, "tp"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -475,7 +475,7 @@ func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label)
|
|||||||
populateTypeParamParents(funcObj.Type().(*types.Signature).TypeParams(), obj)
|
populateTypeParamParents(funcObj.Type().(*types.Signature).TypeParams(), obj)
|
||||||
populateTypeParamParents(funcObj.Type().(*types.Signature).RecvTypeParams(), obj)
|
populateTypeParamParents(funcObj.Type().(*types.Signature).RecvTypeParams(), obj)
|
||||||
}
|
}
|
||||||
// Populate type parameter parents for named types.
|
// Populate type parameter parents for defined types and alias types.
|
||||||
if typeNameObj, ok := obj.(*types.TypeName); ok {
|
if typeNameObj, ok := obj.(*types.TypeName); ok {
|
||||||
// `types.TypeName` represents a type with a name: a defined
|
// `types.TypeName` represents a type with a name: a defined
|
||||||
// type, an alias type, a type parameter, or a predeclared
|
// type, an alias type, a type parameter, or a predeclared
|
||||||
@@ -574,7 +574,7 @@ func extractObject(tw *trap.Writer, obj types.Object, lbl trap.Label) {
|
|||||||
// For more information on objects, see:
|
// For more information on objects, see:
|
||||||
// https://github.com/golang/example/blob/master/gotypes/README.md#objects
|
// https://github.com/golang/example/blob/master/gotypes/README.md#objects
|
||||||
func extractObjectTypes(tw *trap.Writer) {
|
func extractObjectTypes(tw *trap.Writer) {
|
||||||
// calling `extractType` on a named type will extract all methods defined
|
// calling `extractType` on a defined type will extract all methods defined
|
||||||
// on it, which will add new objects. Therefore we need to do this first
|
// on it, which will add new objects. Therefore we need to do this first
|
||||||
// before we loop over all objects and emit them.
|
// before we loop over all objects and emit them.
|
||||||
changed := true
|
changed := true
|
||||||
@@ -1695,7 +1695,7 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
|||||||
extractElementType(tw, lbl, tp.Elem())
|
extractElementType(tw, lbl, tp.Elem())
|
||||||
case *types.Named:
|
case *types.Named:
|
||||||
origintp := tp.Origin()
|
origintp := tp.Origin()
|
||||||
kind = dbscheme.NamedType.Index()
|
kind = dbscheme.DefinedType.Index()
|
||||||
dbscheme.TypeNameTable.Emit(tw, lbl, origintp.Obj().Name())
|
dbscheme.TypeNameTable.Emit(tw, lbl, origintp.Obj().Name())
|
||||||
underlying := origintp.Underlying()
|
underlying := origintp.Underlying()
|
||||||
extractUnderlyingType(tw, lbl, underlying)
|
extractUnderlyingType(tw, lbl, underlying)
|
||||||
@@ -1767,9 +1767,9 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
|
|||||||
// Type labels refer to global keys to ensure that if the same type is
|
// Type labels refer to global keys to ensure that if the same type is
|
||||||
// encountered during the extraction of different files it is still ultimately
|
// encountered during the extraction of different files it is still ultimately
|
||||||
// mapped to the same entity. In particular, this means that keys for compound
|
// mapped to the same entity. In particular, this means that keys for compound
|
||||||
// types refer to the labels of their component types. For named types, the key
|
// types refer to the labels of their component types. For defined types, the key
|
||||||
// is constructed from their globally unique ID. This prevents cyclic type keys
|
// is constructed from their globally unique ID. This prevents cyclic type keys
|
||||||
// since type recursion in Go always goes through named types.
|
// since type recursion in Go always goes through defined types.
|
||||||
func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
|
func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
|
||||||
tp = resolveTypeAlias(tp)
|
tp = resolveTypeAlias(tp)
|
||||||
lbl, exists := tw.Labeler.TypeLabels[tp]
|
lbl, exists := tw.Labeler.TypeLabels[tp]
|
||||||
@@ -1874,12 +1874,12 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
|
|||||||
origintp := tp.Origin()
|
origintp := tp.Origin()
|
||||||
entitylbl, exists := tw.Labeler.LookupObjectID(origintp.Obj(), lbl)
|
entitylbl, exists := tw.Labeler.LookupObjectID(origintp.Obj(), lbl)
|
||||||
if entitylbl == trap.InvalidLabel {
|
if entitylbl == trap.InvalidLabel {
|
||||||
panic(fmt.Sprintf("Cannot construct label for named type %v (underlying object is %v).\n", origintp, origintp.Obj()))
|
panic(fmt.Sprintf("Cannot construct label for defined type %v (underlying object is %v).\n", origintp, origintp.Obj()))
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
extractObject(tw, origintp.Obj(), entitylbl)
|
extractObject(tw, origintp.Obj(), entitylbl)
|
||||||
}
|
}
|
||||||
lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%s};namedtype", entitylbl))
|
lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%s};definedtype", entitylbl))
|
||||||
case *types.TypeParam:
|
case *types.TypeParam:
|
||||||
parentlbl := getTypeParamParentLabel(tw, tp)
|
parentlbl := getTypeParamParentLabel(tw, tp)
|
||||||
idx := tp.Index()
|
idx := tp.Index()
|
||||||
@@ -1921,9 +1921,9 @@ func extractBaseType(tw *trap.Writer, ptr trap.Label, base types.Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extractUnderlyingType extracts `underlying` as the underlying type of the
|
// extractUnderlyingType extracts `underlying` as the underlying type of the
|
||||||
// named type `named`
|
// defined type `defined`
|
||||||
func extractUnderlyingType(tw *trap.Writer, named trap.Label, underlying types.Type) {
|
func extractUnderlyingType(tw *trap.Writer, defined trap.Label, underlying types.Type) {
|
||||||
dbscheme.UnderlyingTypeTable.Emit(tw, named, extractType(tw, underlying))
|
dbscheme.UnderlyingTypeTable.Emit(tw, defined, extractType(tw, underlying))
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractComponentType extracts `component` as the `idx`th component type of `parent` with name `name`
|
// extractComponentType extracts `component` as the `idx`th component type of `parent` with name `name`
|
||||||
@@ -2173,8 +2173,8 @@ func checkObjectNotSpecialized(obj types.Object) {
|
|||||||
log.Fatalf("Encountered unexpected specialization %s of generic variable object %s", varObj.String(), varObj.Origin().String())
|
log.Fatalf("Encountered unexpected specialization %s of generic variable object %s", varObj.String(), varObj.Origin().String())
|
||||||
}
|
}
|
||||||
if typeNameObj, ok := obj.(*types.TypeName); ok {
|
if typeNameObj, ok := obj.(*types.TypeName); ok {
|
||||||
if namedType, ok := typeNameObj.Type().(*types.Named); ok && namedType != namedType.Origin() {
|
if definedType, ok := typeNameObj.Type().(*types.Named); ok && definedType != definedType.Origin() {
|
||||||
log.Fatalf("Encountered type object for specialization %s of named type %s", namedType.String(), namedType.Origin().String())
|
log.Fatalf("Encountered type object for specialization %s of defined type %s", definedType.String(), definedType.Origin().String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,9 +181,9 @@ func findMethodWithGivenReceiver(object types.Object) *types.Func {
|
|||||||
|
|
||||||
// findMethodWithGivenReceiver finds a method on type `tp` with `object` as its receiver, if one exists
|
// findMethodWithGivenReceiver finds a method on type `tp` with `object` as its receiver, if one exists
|
||||||
func findMethodOnTypeWithGivenReceiver(tp types.Type, object types.Object) *types.Func {
|
func findMethodOnTypeWithGivenReceiver(tp types.Type, object types.Object) *types.Func {
|
||||||
if namedType, ok := tp.(*types.Named); ok {
|
if definedType, ok := tp.(*types.Named); ok {
|
||||||
for i := 0; i < namedType.NumMethods(); i++ {
|
for i := 0; i < definedType.NumMethods(); i++ {
|
||||||
meth := namedType.Method(i)
|
meth := definedType.Method(i)
|
||||||
if object == meth.Type().(*types.Signature).Recv() {
|
if object == meth.Type().(*types.Signature).Recv() {
|
||||||
return meth
|
return meth
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
import go
|
import go
|
||||||
|
|
||||||
from ExpressionSwitchStmt ss, DeclaredConstant c, NamedType t
|
from ExpressionSwitchStmt ss, DeclaredConstant c, DefinedType t
|
||||||
where
|
where
|
||||||
t.getUnderlyingType() instanceof IntegerType and
|
t.getUnderlyingType() instanceof IntegerType and
|
||||||
t = ss.getExpr().getType() and
|
t = ss.getExpr().getType() and
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ class MethodDecl extends FuncDecl {
|
|||||||
*
|
*
|
||||||
* is `Rectangle`.
|
* is `Rectangle`.
|
||||||
*/
|
*/
|
||||||
NamedType getReceiverBaseType() { result = lookThroughPointerType(this.getReceiverType()) }
|
DefinedType getReceiverBaseType() { result = lookThroughPointerType(this.getReceiverType()) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the receiver variable of this method.
|
* Gets the receiver variable of this method.
|
||||||
|
|||||||
@@ -194,19 +194,22 @@ class BuiltinEntity extends Entity, @builtinobject { }
|
|||||||
/** An imported package. */
|
/** An imported package. */
|
||||||
class PackageEntity extends Entity, @pkgobject { }
|
class PackageEntity extends Entity, @pkgobject { }
|
||||||
|
|
||||||
/** A built-in or declared named type. */
|
/**
|
||||||
|
* A named type (predeclared types, defined types, type parameters and aliases
|
||||||
|
* which refer to those things).
|
||||||
|
*/
|
||||||
class TypeEntity extends Entity, @typeobject { }
|
class TypeEntity extends Entity, @typeobject { }
|
||||||
|
|
||||||
/** The parent of a type parameter type, either a declared type or a declared function. */
|
/** The parent of a type parameter type, either a declared type or a declared function. */
|
||||||
class TypeParamParentEntity extends Entity, @typeparamparentobject { }
|
class TypeParamParentEntity extends Entity, @typeparamparentobject { }
|
||||||
|
|
||||||
/** A declared named type. */
|
/** A named type which has a declaration. */
|
||||||
class DeclaredType extends TypeEntity, DeclaredEntity, TypeParamParentEntity, @decltypeobject {
|
class DeclaredType extends TypeEntity, DeclaredEntity, TypeParamParentEntity, @decltypeobject {
|
||||||
/** Gets the declaration specifier declaring this type. */
|
/** Gets the declaration specifier declaring this type. */
|
||||||
TypeSpec getSpec() { result.getNameExpr() = this.getDeclaration() }
|
TypeSpec getSpec() { result.getNameExpr() = this.getDeclaration() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A built-in named type. */
|
/** A built-in type. */
|
||||||
class BuiltinType extends TypeEntity, BuiltinEntity, @builtintypeobject { }
|
class BuiltinType extends TypeEntity, BuiltinEntity, @builtintypeobject { }
|
||||||
|
|
||||||
/** A built-in or declared constant, variable, field, method or function. */
|
/** A built-in or declared constant, variable, field, method or function. */
|
||||||
@@ -522,7 +525,7 @@ class Method extends Function {
|
|||||||
Type getReceiverBaseType() { result = lookThroughPointerType(this.getReceiverType()) }
|
Type getReceiverBaseType() { result = lookThroughPointerType(this.getReceiverType()) }
|
||||||
|
|
||||||
/** Holds if this method has name `m` and belongs to the method set of type `tp` or `*tp`. */
|
/** Holds if this method has name `m` and belongs to the method set of type `tp` or `*tp`. */
|
||||||
private predicate isIn(NamedType tp, string m) {
|
private predicate isIn(DefinedType tp, string m) {
|
||||||
this = tp.getMethod(m) or
|
this = tp.getMethod(m) or
|
||||||
this = tp.getPointerType().getMethod(m)
|
this = tp.getPointerType().getMethod(m)
|
||||||
}
|
}
|
||||||
@@ -536,7 +539,7 @@ class Method extends Function {
|
|||||||
* distinguishes between the method sets of `T` and `*T`, while the former does not.
|
* distinguishes between the method sets of `T` and `*T`, while the former does not.
|
||||||
*/
|
*/
|
||||||
override predicate hasQualifiedName(string tp, string m) {
|
override predicate hasQualifiedName(string tp, string m) {
|
||||||
exists(NamedType t |
|
exists(DefinedType t |
|
||||||
this.isIn(t, m) and
|
this.isIn(t, m) and
|
||||||
tp = t.getQualifiedName()
|
tp = t.getQualifiedName()
|
||||||
)
|
)
|
||||||
@@ -552,7 +555,7 @@ class Method extends Function {
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate hasQualifiedName(string pkg, string tp, string m) {
|
predicate hasQualifiedName(string pkg, string tp, string m) {
|
||||||
exists(NamedType t |
|
exists(DefinedType t |
|
||||||
this.isIn(t, m) and
|
this.isIn(t, m) and
|
||||||
t.hasQualifiedName(pkg, tp)
|
t.hasQualifiedName(pkg, tp)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class Type extends @type {
|
|||||||
/**
|
/**
|
||||||
* Gets the qualified name of this type, if any.
|
* Gets the qualified name of this type, if any.
|
||||||
*
|
*
|
||||||
* Only (defined) named types like `io.Writer` have a qualified name. Basic types like `int`,
|
* Only defined types like `io.Writer` have a qualified name. Basic types like `int`,
|
||||||
* pointer types like `*io.Writer`, and other composite types do not have a qualified name.
|
* pointer types like `*io.Writer`, and other composite types do not have a qualified name.
|
||||||
*/
|
*/
|
||||||
string getQualifiedName() { result = this.getEntity().getQualifiedName() }
|
string getQualifiedName() { result = this.getEntity().getQualifiedName() }
|
||||||
@@ -34,7 +34,7 @@ class Type extends @type {
|
|||||||
/**
|
/**
|
||||||
* Holds if this type is declared in a package with path `pkg` and has name `name`.
|
* Holds if this type is declared in a package with path `pkg` and has name `name`.
|
||||||
*
|
*
|
||||||
* Only (defined) named types like `io.Writer` have a qualified name. Basic types like `int`,
|
* Only defined types like `io.Writer` have a qualified name. Basic types like `int`,
|
||||||
* pointer types like `*io.Writer`, and other composite types do not have a qualified name.
|
* pointer types like `*io.Writer`, and other composite types do not have a qualified name.
|
||||||
*/
|
*/
|
||||||
predicate hasQualifiedName(string pkg, string name) {
|
predicate hasQualifiedName(string pkg, string name) {
|
||||||
@@ -50,7 +50,7 @@ class Type extends @type {
|
|||||||
* Gets the method `m` belonging to the method set of this type, if any.
|
* Gets the method `m` belonging to the method set of this type, if any.
|
||||||
*
|
*
|
||||||
* Note that this predicate never has a result for struct types. Methods are associated
|
* Note that this predicate never has a result for struct types. Methods are associated
|
||||||
* with the corresponding named type instead.
|
* with the corresponding defined type instead.
|
||||||
*/
|
*/
|
||||||
Method getMethod(string m) {
|
Method getMethod(string m) {
|
||||||
result.getReceiverType() = this and
|
result.getReceiverType() = this and
|
||||||
@@ -446,7 +446,7 @@ class StructType extends @structtype, CompositeType {
|
|||||||
if n = ""
|
if n = ""
|
||||||
then (
|
then (
|
||||||
isEmbedded = true and
|
isEmbedded = true and
|
||||||
name = lookThroughPointerType(tp).(NamedType).getName()
|
name = lookThroughPointerType(tp).(DefinedType).getName()
|
||||||
) else (
|
) else (
|
||||||
isEmbedded = false and
|
isEmbedded = false and
|
||||||
name = n
|
name = n
|
||||||
@@ -497,7 +497,7 @@ class StructType extends @structtype, CompositeType {
|
|||||||
// embeddedParent is a field of 'this' at depth 'depth - 1'
|
// embeddedParent is a field of 'this' at depth 'depth - 1'
|
||||||
this.hasFieldCand(_, embeddedParent, depth - 1, true) and
|
this.hasFieldCand(_, embeddedParent, depth - 1, true) and
|
||||||
// embeddedParent's type has the result field. Note that it is invalid Go
|
// embeddedParent's type has the result field. Note that it is invalid Go
|
||||||
// to have an embedded field with a named type whose underlying type is a
|
// to have an embedded field with a defined type whose underlying type is a
|
||||||
// pointer, so we don't have to have
|
// pointer, so we don't have to have
|
||||||
// `lookThroughPointerType(embeddedParent.getType().getUnderlyingType())`.
|
// `lookThroughPointerType(embeddedParent.getType().getUnderlyingType())`.
|
||||||
result =
|
result =
|
||||||
@@ -613,7 +613,7 @@ class PointerType extends @pointertype, CompositeType {
|
|||||||
or
|
or
|
||||||
// promoted methods from embedded types
|
// promoted methods from embedded types
|
||||||
exists(StructType s, Type embedded |
|
exists(StructType s, Type embedded |
|
||||||
s = this.getBaseType().(NamedType).getUnderlyingType() and
|
s = this.getBaseType().(DefinedType).getUnderlyingType() and
|
||||||
s.hasOwnField(_, _, embedded, true) and
|
s.hasOwnField(_, _, embedded, true) and
|
||||||
// ensure that `m` can be promoted
|
// ensure that `m` can be promoted
|
||||||
not s.hasOwnField(_, m, _, _) and
|
not s.hasOwnField(_, m, _, _) and
|
||||||
@@ -918,7 +918,7 @@ class EmptyInterfaceType extends BasicInterfaceType {
|
|||||||
/**
|
/**
|
||||||
* The predeclared `comparable` type.
|
* The predeclared `comparable` type.
|
||||||
*/
|
*/
|
||||||
class ComparableType extends NamedType {
|
class ComparableType extends DefinedType {
|
||||||
ComparableType() { this.getName() = "comparable" }
|
ComparableType() { this.getName() = "comparable" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,8 +1028,11 @@ class SendRecvChanType extends @sendrcvchantype, ChanType {
|
|||||||
override string toString() { result = "send-receive-channel type" }
|
override string toString() { result = "send-receive-channel type" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A named type. */
|
/** DEPRECATED: Use `DefinedType` instead. */
|
||||||
class NamedType extends @namedtype, CompositeType {
|
deprecated class NamedType = DefinedType;
|
||||||
|
|
||||||
|
/** A defined type. */
|
||||||
|
class DefinedType extends @namedtype, CompositeType {
|
||||||
/** Gets the type which this type is defined to be. */
|
/** Gets the type which this type is defined to be. */
|
||||||
Type getBaseType() { underlying_type(this, result) }
|
Type getBaseType() { underlying_type(this, result) }
|
||||||
|
|
||||||
|
|||||||
@@ -47,28 +47,31 @@ module GoMicro {
|
|||||||
* A Server Interface type.
|
* A Server Interface type.
|
||||||
*/
|
*/
|
||||||
class ServiceInterfaceType extends InterfaceType {
|
class ServiceInterfaceType extends InterfaceType {
|
||||||
NamedType namedType;
|
DefinedType definedType;
|
||||||
|
|
||||||
ServiceInterfaceType() {
|
ServiceInterfaceType() {
|
||||||
this = namedType.getUnderlyingType() and
|
this = definedType.getUnderlyingType() and
|
||||||
namedType.hasLocationInfo(any(ProtocGeneratedFile f).getAbsolutePath(), _, _, _, _)
|
definedType.hasLocationInfo(any(ProtocGeneratedFile f).getAbsolutePath(), _, _, _, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name of the interface.
|
* Gets the name of the interface.
|
||||||
*/
|
*/
|
||||||
override string getName() { result = namedType.getName() }
|
override string getName() { result = definedType.getName() }
|
||||||
|
|
||||||
|
/** DEPRECATED: Use `getDefinedType` instead. */
|
||||||
|
deprecated DefinedType getNamedType() { result = definedType }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the named type on top of this interface type.
|
* Gets the defined type on top of this interface type.
|
||||||
*/
|
*/
|
||||||
NamedType getNamedType() { result = namedType }
|
DefinedType getDefinedType() { result = definedType }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Service server handler type.
|
* A Service server handler type.
|
||||||
*/
|
*/
|
||||||
class ServiceServerType extends NamedType {
|
class ServiceServerType extends DefinedType {
|
||||||
ServiceServerType() {
|
ServiceServerType() {
|
||||||
this.implements(any(ServiceInterfaceType i)) and
|
this.implements(any(ServiceInterfaceType i)) and
|
||||||
this.getName().regexpMatch("(?i).*Handler") and
|
this.getName().regexpMatch("(?i).*Handler") and
|
||||||
@@ -79,7 +82,7 @@ module GoMicro {
|
|||||||
/**
|
/**
|
||||||
* A Client server handler type.
|
* A Client server handler type.
|
||||||
*/
|
*/
|
||||||
class ClientServiceType extends NamedType {
|
class ClientServiceType extends DefinedType {
|
||||||
ClientServiceType() {
|
ClientServiceType() {
|
||||||
this.implements(any(ServiceInterfaceType i)) and
|
this.implements(any(ServiceInterfaceType i)) and
|
||||||
this.getName().regexpMatch("(?i).*Service") and
|
this.getName().regexpMatch("(?i).*Service") and
|
||||||
@@ -101,7 +104,7 @@ module GoMicro {
|
|||||||
bindingset[m]
|
bindingset[m]
|
||||||
pragma[inline_late]
|
pragma[inline_late]
|
||||||
private predicate implementsServiceType(Method m) {
|
private predicate implementsServiceType(Method m) {
|
||||||
m.implements(any(ServiceInterfaceType i).getNamedType().getMethod(_))
|
m.implements(any(ServiceInterfaceType i).getDefinedType().getMethod(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -44,22 +44,25 @@ module Twirp {
|
|||||||
|
|
||||||
/** An interface type representing a Twirp service. */
|
/** An interface type representing a Twirp service. */
|
||||||
class ServiceInterfaceType extends InterfaceType {
|
class ServiceInterfaceType extends InterfaceType {
|
||||||
NamedType namedType;
|
DefinedType definedType;
|
||||||
|
|
||||||
ServiceInterfaceType() {
|
ServiceInterfaceType() {
|
||||||
namedType.getUnderlyingType() = this and
|
definedType.getUnderlyingType() = this and
|
||||||
namedType.hasLocationInfo(any(ServicesGeneratedFile f).getAbsolutePath(), _, _, _, _)
|
definedType.hasLocationInfo(any(ServicesGeneratedFile f).getAbsolutePath(), _, _, _, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the name of the interface. */
|
/** Gets the name of the interface. */
|
||||||
override string getName() { result = namedType.getName() }
|
override string getName() { result = definedType.getName() }
|
||||||
|
|
||||||
/** Gets the named type on top of this interface type. */
|
/** DEPRECATED: Use `getDefinedType` instead. */
|
||||||
NamedType getNamedType() { result = namedType }
|
deprecated DefinedType getNamedType() { result = this.getDefinedType() }
|
||||||
|
|
||||||
|
/** Gets the defined type on top of this interface type. */
|
||||||
|
DefinedType getDefinedType() { result = definedType }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A Twirp client. */
|
/** A Twirp client. */
|
||||||
class ServiceClientType extends NamedType {
|
class ServiceClientType extends DefinedType {
|
||||||
ServiceClientType() {
|
ServiceClientType() {
|
||||||
exists(ServiceInterfaceType i, PointerType p |
|
exists(ServiceInterfaceType i, PointerType p |
|
||||||
p.implements(i) and
|
p.implements(i) and
|
||||||
@@ -71,7 +74,7 @@ module Twirp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A Twirp server. */
|
/** A Twirp server. */
|
||||||
class ServiceServerType extends NamedType {
|
class ServiceServerType extends DefinedType {
|
||||||
ServiceServerType() {
|
ServiceServerType() {
|
||||||
exists(ServiceInterfaceType i |
|
exists(ServiceInterfaceType i |
|
||||||
this.implements(i) and
|
this.implements(i) and
|
||||||
@@ -99,7 +102,7 @@ module Twirp {
|
|||||||
class ServerConstructor extends Function {
|
class ServerConstructor extends Function {
|
||||||
ServerConstructor() {
|
ServerConstructor() {
|
||||||
this.getName().regexpMatch("(?i)new" + any(ServiceServerType c).getName()) and
|
this.getName().regexpMatch("(?i)new" + any(ServiceServerType c).getName()) and
|
||||||
this.getParameterType(0) = any(ServiceInterfaceType i).getNamedType() and
|
this.getParameterType(0) = any(ServiceInterfaceType i).getDefinedType() and
|
||||||
this.hasLocationInfo(any(ServicesGeneratedFile f).getAbsolutePath(), _, _, _, _)
|
this.hasLocationInfo(any(ServicesGeneratedFile f).getAbsolutePath(), _, _, _, _)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,7 +124,7 @@ module Twirp {
|
|||||||
bindingset[m]
|
bindingset[m]
|
||||||
pragma[inline_late]
|
pragma[inline_late]
|
||||||
private predicate implementsServiceType(Method m) {
|
private predicate implementsServiceType(Method m) {
|
||||||
m.implements(any(ServiceInterfaceType i).getNamedType().getMethod(_))
|
m.implements(any(ServiceInterfaceType i).getDefinedType().getMethod(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A service handler. */
|
/** A service handler. */
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ module AllocationSizeOverflow {
|
|||||||
t instanceof BasicType and
|
t instanceof BasicType and
|
||||||
not t instanceof StringType
|
not t instanceof StringType
|
||||||
or
|
or
|
||||||
isSmallType(t.(NamedType).getUnderlyingType())
|
isSmallType(t.(DefinedType).getUnderlyingType())
|
||||||
or
|
or
|
||||||
isSmallType(t.(PointerType).getBaseType())
|
isSmallType(t.(PointerType).getBaseType())
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ predicate elementRead(
|
|||||||
}
|
}
|
||||||
|
|
||||||
predicate isRegexpMethodCall(DataFlow::MethodCallNode c) {
|
predicate isRegexpMethodCall(DataFlow::MethodCallNode c) {
|
||||||
exists(NamedType regexp, Type recvtp |
|
exists(DefinedType regexp, Type recvtp |
|
||||||
regexp.getName() = "Regexp" and recvtp = c.getReceiver().getType()
|
regexp.getName() = "Regexp" and recvtp = c.getReceiver().getType()
|
||||||
|
|
|
|
||||||
lookThroughPointerType(recvtp) = regexp
|
lookThroughPointerType(recvtp) = regexp
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class DangerousScheme extends string {
|
|||||||
/** Gets a data-flow node that checks an instance of `g` against the given `scheme`. */
|
/** Gets a data-flow node that checks an instance of `g` against the given `scheme`. */
|
||||||
DataFlow::Node schemeCheck(GVN g, DangerousScheme scheme) {
|
DataFlow::Node schemeCheck(GVN g, DangerousScheme scheme) {
|
||||||
// check of the form `nd.Scheme == scheme`
|
// check of the form `nd.Scheme == scheme`
|
||||||
exists(NamedType url, DataFlow::FieldReadNode fr, DataFlow::Node s |
|
exists(DefinedType url, DataFlow::FieldReadNode fr, DataFlow::Node s |
|
||||||
url.hasQualifiedName("net/url", "URL") and
|
url.hasQualifiedName("net/url", "URL") and
|
||||||
fr.readsField(g.getANode(), url.getField("Scheme")) and
|
fr.readsField(g.getANode(), url.getField("Scheme")) and
|
||||||
s.getStringValue() = scheme and
|
s.getStringValue() = scheme and
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ class InsecureIgnoreHostKey extends Function {
|
|||||||
/** An SSH host-key checking function. */
|
/** An SSH host-key checking function. */
|
||||||
class HostKeyCallbackFunc extends DataFlow::Node {
|
class HostKeyCallbackFunc extends DataFlow::Node {
|
||||||
HostKeyCallbackFunc() {
|
HostKeyCallbackFunc() {
|
||||||
exists(NamedType nt | nt.hasQualifiedName(cryptoSshPackage(), "HostKeyCallback") |
|
exists(DefinedType dt | dt.hasQualifiedName(cryptoSshPackage(), "HostKeyCallback") |
|
||||||
this.getType().getUnderlyingType() = nt.getUnderlyingType()
|
this.getType().getUnderlyingType() = dt.getUnderlyingType()
|
||||||
) and
|
) and
|
||||||
// Restrict possible sources to either function definitions or
|
// Restrict possible sources to either function definitions or
|
||||||
// the result of some external function call (e.g. InsecureIgnoreHostKey())
|
// the result of some external function call (e.g. InsecureIgnoreHostKey())
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
import go
|
import go
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the type after all aliases, named types, and pointer
|
* Returns the type after all aliases, defined types, and pointer
|
||||||
* types have been replaced with the actual underlying type.
|
* types have been replaced with the actual underlying type.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import go
|
import go
|
||||||
|
|
||||||
from NamedType t
|
from DefinedType t
|
||||||
where t.getPackage().getName().matches("%main")
|
where t.getPackage().getName().matches("%main")
|
||||||
select t, t.getName(), t.getMethod(_)
|
select t, t.getName(), t.getMethod(_)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
| generic.go:60:12:60:28 | generic type instantiation expression | generic.go:60:12:60:22 | GenericMap2 | 0 | generic.go:60:24:60:24 | U |
|
| generic.go:60:12:60:28 | generic type instantiation expression | generic.go:60:12:60:22 | GenericMap2 | 0 | generic.go:60:24:60:24 | U |
|
||||||
| generic.go:60:12:60:28 | generic type instantiation expression | generic.go:60:12:60:22 | GenericMap2 | 1 | generic.go:60:27:60:27 | U |
|
| generic.go:60:12:60:28 | generic type instantiation expression | generic.go:60:12:60:22 | GenericMap2 | 1 | generic.go:60:27:60:27 | U |
|
||||||
| generic.go:61:12:61:28 | generic type instantiation expression | generic.go:61:12:61:25 | GenericChannel | 0 | generic.go:61:27:61:27 | U |
|
| generic.go:61:12:61:28 | generic type instantiation expression | generic.go:61:12:61:25 | GenericChannel | 0 | generic.go:61:27:61:27 | U |
|
||||||
| generic.go:62:12:62:26 | generic type instantiation expression | generic.go:62:12:62:23 | GenericNamed | 0 | generic.go:62:25:62:25 | U |
|
| generic.go:62:12:62:28 | generic type instantiation expression | generic.go:62:12:62:25 | GenericDefined | 0 | generic.go:62:27:62:27 | U |
|
||||||
| generic.go:70:42:70:64 | generic type instantiation expression | generic.go:70:42:70:57 | GenericInterface | 0 | generic.go:70:59:70:63 | int32 |
|
| generic.go:70:42:70:64 | generic type instantiation expression | generic.go:70:42:70:57 | GenericInterface | 0 | generic.go:70:59:70:63 | int32 |
|
||||||
| generic.go:74:41:74:62 | generic type instantiation expression | generic.go:74:41:74:54 | GenericStruct1 | 0 | generic.go:74:56:74:61 | string |
|
| generic.go:74:41:74:62 | generic type instantiation expression | generic.go:74:41:74:54 | GenericStruct1 | 0 | generic.go:74:56:74:61 | string |
|
||||||
| generic.go:82:18:82:34 | generic type instantiation expression | generic.go:82:18:82:29 | GenericArray | 0 | generic.go:82:31:82:33 | int |
|
| generic.go:82:18:82:34 | generic type instantiation expression | generic.go:82:18:82:29 | GenericArray | 0 | generic.go:82:31:82:33 | int |
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import go
|
import go
|
||||||
|
|
||||||
from NamedType nt, InterfaceType it, Type methodType, string id
|
from DefinedType dt, InterfaceType it, Type methodType, string id
|
||||||
where
|
where
|
||||||
nt.getName() = "MixedExportedAndNot" and
|
dt.getName() = "MixedExportedAndNot" and
|
||||||
it = nt.getUnderlyingType() and
|
it = dt.getUnderlyingType() and
|
||||||
(
|
(
|
||||||
it.hasPrivateMethodWithQualifiedName(_, id, methodType)
|
it.hasPrivateMethodWithQualifiedName(_, id, methodType)
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
| generic.go:47:6:47:16 | MyInterface | dummy14 | func() GenericMap1 |
|
| generic.go:47:6:47:16 | MyInterface | dummy14 | func() GenericMap1 |
|
||||||
| generic.go:47:6:47:16 | MyInterface | dummy15 | func() GenericMap2 |
|
| generic.go:47:6:47:16 | MyInterface | dummy15 | func() GenericMap2 |
|
||||||
| generic.go:47:6:47:16 | MyInterface | dummy17 | func() GenericChannel |
|
| generic.go:47:6:47:16 | MyInterface | dummy17 | func() GenericChannel |
|
||||||
| generic.go:47:6:47:16 | MyInterface | dummy18 | func() GenericNamed |
|
| generic.go:47:6:47:16 | MyInterface | dummy18 | func() GenericDefined |
|
||||||
| generic.go:47:6:47:16 | MyInterface | dummy19 | func() MyFuncType1 |
|
| generic.go:47:6:47:16 | MyInterface | dummy19 | func() MyFuncType1 |
|
||||||
| generic.go:47:6:47:16 | MyInterface | dummy20 | func() MyFuncType2 |
|
| generic.go:47:6:47:16 | MyInterface | dummy20 | func() MyFuncType2 |
|
||||||
| interface.go:28:6:28:7 | i6 | String | func() string |
|
| interface.go:28:6:28:7 | i6 | String | func() string |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import go
|
import go
|
||||||
|
|
||||||
from NamedType t, string m, Type tp
|
from DefinedType t, string m, Type tp
|
||||||
where
|
where
|
||||||
exists(t.getEntity().getDeclaration()) and
|
exists(t.getEntity().getDeclaration()) and
|
||||||
t.getBaseType().hasMethod(m, tp)
|
t.getBaseType().hasMethod(m, tp)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
| generic.go:40:6:40:16 | GenericMap2 | codeql-go-types.GenericMap2 |
|
| generic.go:40:6:40:16 | GenericMap2 | codeql-go-types.GenericMap2 |
|
||||||
| generic.go:41:6:41:19 | GenericChannel | codeql-go-types.GenericChannel |
|
| generic.go:41:6:41:19 | GenericChannel | codeql-go-types.GenericChannel |
|
||||||
| generic.go:42:6:42:14 | MyMapType | codeql-go-types.MyMapType |
|
| generic.go:42:6:42:14 | MyMapType | codeql-go-types.MyMapType |
|
||||||
| generic.go:43:6:43:17 | GenericNamed | codeql-go-types.GenericNamed |
|
| generic.go:43:6:43:19 | GenericDefined | codeql-go-types.GenericDefined |
|
||||||
| generic.go:44:6:44:16 | MyFuncType1 | codeql-go-types.MyFuncType1 |
|
| generic.go:44:6:44:16 | MyFuncType1 | codeql-go-types.MyFuncType1 |
|
||||||
| generic.go:45:6:45:16 | MyFuncType2 | codeql-go-types.MyFuncType2 |
|
| generic.go:45:6:45:16 | MyFuncType2 | codeql-go-types.MyFuncType2 |
|
||||||
| generic.go:47:6:47:16 | MyInterface | codeql-go-types.MyInterface |
|
| generic.go:47:6:47:16 | MyInterface | codeql-go-types.MyInterface |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import go
|
import go
|
||||||
|
|
||||||
from StructTypeExpr ste, NamedType named, string name, Type tp
|
from StructTypeExpr ste, DefinedType defined, string name, Type tp
|
||||||
where
|
where
|
||||||
named.getUnderlyingType() = ste.getType() and
|
defined.getUnderlyingType() = ste.getType() and
|
||||||
ste.getType().(StructType).hasField(name, tp)
|
ste.getType().(StructType).hasField(name, tp)
|
||||||
select named, ste, name, tp.pp()
|
select defined, ste, name, tp.pp()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
| generic.go:40:6:40:16 | GenericMap2 | GenericMap2 |
|
| generic.go:40:6:40:16 | GenericMap2 | GenericMap2 |
|
||||||
| generic.go:41:6:41:19 | GenericChannel | GenericChannel |
|
| generic.go:41:6:41:19 | GenericChannel | GenericChannel |
|
||||||
| generic.go:42:6:42:14 | MyMapType | MyMapType |
|
| generic.go:42:6:42:14 | MyMapType | MyMapType |
|
||||||
| generic.go:43:6:43:17 | GenericNamed | GenericNamed |
|
| generic.go:43:6:43:19 | GenericDefined | GenericDefined |
|
||||||
| generic.go:44:6:44:16 | MyFuncType1 | MyFuncType1 |
|
| generic.go:44:6:44:16 | MyFuncType1 | MyFuncType1 |
|
||||||
| generic.go:45:6:45:16 | MyFuncType2 | MyFuncType2 |
|
| generic.go:45:6:45:16 | MyFuncType2 | MyFuncType2 |
|
||||||
| generic.go:47:6:47:16 | MyInterface | MyInterface |
|
| generic.go:47:6:47:16 | MyInterface | MyInterface |
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ func G(Afs2 aliasesS2) int {
|
|||||||
return Afs2.x
|
return Afs2.x
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a named type, not an alias
|
// This is a defined type, not an alias
|
||||||
type S3 struct{ x int }
|
type S3 struct{ x int }
|
||||||
|
|
||||||
// This is a type alias
|
// This is a type alias
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ type GenericMap1[V any] map[string]V
|
|||||||
type GenericMap2[K comparable, V any] map[K]V
|
type GenericMap2[K comparable, V any] map[K]V
|
||||||
type GenericChannel[T comparable] chan<- T
|
type GenericChannel[T comparable] chan<- T
|
||||||
type MyMapType map[string]int
|
type MyMapType map[string]int
|
||||||
type GenericNamed[T comparable] MyMapType
|
type GenericDefined[T comparable] MyMapType
|
||||||
type MyFuncType1[T any] func(T)
|
type MyFuncType1[T any] func(T)
|
||||||
type MyFuncType2[T1 any, T2 any] func(T1) T2
|
type MyFuncType2[T1 any, T2 any] func(T1) T2
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ type MyInterface[U comparable] interface {
|
|||||||
dummy14() GenericMap1[U]
|
dummy14() GenericMap1[U]
|
||||||
dummy15() GenericMap2[U, U]
|
dummy15() GenericMap2[U, U]
|
||||||
dummy17() GenericChannel[U]
|
dummy17() GenericChannel[U]
|
||||||
dummy18() GenericNamed[U]
|
dummy18() GenericDefined[U]
|
||||||
dummy19() MyFuncType1[U]
|
dummy19() MyFuncType1[U]
|
||||||
dummy20() MyFuncType2[U, U]
|
dummy20() MyFuncType2[U, U]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ query predicate passingPositiveTests(string res, string expectation, InlineTest
|
|||||||
exists(Twirp::ProtobufMessageType n | t.inType(n))
|
exists(Twirp::ProtobufMessageType n | t.inType(n))
|
||||||
or
|
or
|
||||||
expectation = "serviceInterface" and
|
expectation = "serviceInterface" and
|
||||||
exists(Twirp::ServiceInterfaceType n | t.inType(n.getNamedType()))
|
exists(Twirp::ServiceInterfaceType n | t.inType(n.getDefinedType()))
|
||||||
or
|
or
|
||||||
expectation = "serviceClient" and
|
expectation = "serviceClient" and
|
||||||
exists(Twirp::ServiceClientType n | t.inType(n))
|
exists(Twirp::ServiceClientType n | t.inType(n))
|
||||||
@@ -90,7 +90,7 @@ query predicate failingPositiveTests(string res, string expectation, InlineTest
|
|||||||
not exists(Twirp::ProtobufMessageType n | t.inType(n))
|
not exists(Twirp::ProtobufMessageType n | t.inType(n))
|
||||||
or
|
or
|
||||||
expectation = "serviceInterface" and
|
expectation = "serviceInterface" and
|
||||||
not exists(Twirp::ServiceInterfaceType n | t.inType(n.getNamedType()))
|
not exists(Twirp::ServiceInterfaceType n | t.inType(n.getDefinedType()))
|
||||||
or
|
or
|
||||||
expectation = "serviceClient" and
|
expectation = "serviceClient" and
|
||||||
not exists(Twirp::ServiceClientType n | t.inType(n))
|
not exists(Twirp::ServiceClientType n | t.inType(n))
|
||||||
|
|||||||
Reference in New Issue
Block a user