@@ -567,7 +567,7 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati
567567 override predicate isPrivate ( ) { Predicate .super .isPrivate ( ) }
568568
569569 /** Holds if this classless predicate is a signature predicate with no body. */
570- predicate isSignature ( ) { not exists ( this .getBody ( ) ) }
570+ override predicate isSignature ( ) { not exists ( this .getBody ( ) ) }
571571
572572 override QLDoc getQLDoc ( ) {
573573 result = any ( TopLevel m ) .getQLDocFor ( this )
@@ -836,6 +836,12 @@ class Module extends TModule, ModuleDeclaration {
836836 toMock ( result ) = mod .asRight ( ) .getMember ( i )
837837 }
838838
839+ pragma [ nomagic]
840+ Declaration getDeclaration ( string name ) {
841+ result = this .getAMember ( ) and
842+ name = result .getName ( )
843+ }
844+
839845 QLDoc getQLDocFor ( AstNode m ) {
840846 exists ( int i | result = this .getMember ( i ) and m = this .getMember ( i + 1 ) )
841847 }
@@ -885,6 +891,33 @@ class ModuleMember extends TModuleMember, AstNode {
885891 predicate isFinal ( ) { this .hasAnnotation ( "final" ) }
886892}
887893
894+ private newtype TDeclarationKind =
895+ TClassKind ( ) or
896+ TModuleKind ( ) or
897+ TPredicateKind ( int arity ) { arity = any ( Predicate p ) .getArity ( ) }
898+
899+ private TDeclarationKind getDeclarationKind ( Declaration d ) {
900+ d instanceof Class and result = TClassKind ( )
901+ or
902+ d instanceof Module and result = TModuleKind ( )
903+ or
904+ d = any ( Predicate p | result = TPredicateKind ( p .getArity ( ) ) )
905+ }
906+
907+ /** Holds if module `m` must implement signature declaration `d` with name `name` and kind `kind`. */
908+ pragma [ nomagic]
909+ private predicate mustImplement ( Module m , string name , TDeclarationKind kind , Declaration d ) {
910+ d = m .getImplements ( _) .getResolvedType ( ) .getDeclaration ( ) .( Module ) .getAMember ( ) and
911+ name = d .getName ( ) and
912+ kind = getDeclarationKind ( d )
913+ }
914+
915+ pragma [ nomagic]
916+ private Declaration getDeclaration ( Module m , string name , TDeclarationKind kind ) {
917+ result = m .getDeclaration ( name ) and
918+ kind = getDeclarationKind ( result )
919+ }
920+
888921/** A declaration. E.g. a class, type, predicate, newtype... */
889922class Declaration extends TDeclaration , AstNode {
890923 /** Gets the name of this declaration. */
@@ -899,6 +932,16 @@ class Declaration extends TDeclaration, AstNode {
899932 or
900933 result = any ( Class c ) .getQLDocFor ( this )
901934 }
935+
936+ predicate isSignature ( ) { this .hasAnnotation ( "signature" ) }
937+
938+ /** Holds if this declaration implements `other`. */
939+ predicate implements ( Declaration other ) {
940+ exists ( Module m , string name , TDeclarationKind kind |
941+ this = getDeclaration ( m , name , kind ) and
942+ mustImplement ( m , name , kind , other )
943+ )
944+ }
902945}
903946
904947/** An entity that can be declared in a module. */
0 commit comments