@@ -656,6 +656,7 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain
656656 * Normalize the `n`'th parameter of `f` by replacing template names
657657 * with `class:N` (where `N` is the index of the template).
658658 */
659+ pragma [ nomagic]
659660private string getTypeNameWithoutClassTemplates ( Function f , int n , int remaining ) {
660661 // If there is a declaring type then we start by expanding the function templates
661662 exists ( Class template |
@@ -727,6 +728,7 @@ private string getSignatureWithoutClassTemplateNames(
727728 * - The `remaining` number of template arguments in `partiallyNormalizedSignature`
728729 * with their index in `nameArgs`.
729730 */
731+ pragma [ nomagic]
730732private string getSignatureWithoutFunctionTemplateNames (
731733 string partiallyNormalizedSignature , string typeArgs , string nameArgs , int remaining
732734) {
@@ -770,6 +772,7 @@ private string getSignatureWithoutFunctionTemplateNames(
770772 * ```
771773 * In this case, `normalizedSignature` will be `"(const func:0 &,int,class:1,class:0 *)"`.
772774 */
775+ pragma [ nomagic]
773776private predicate elementSpecWithArguments (
774777 string signature , string type , string name , string normalizedSignature , string typeArgs ,
775778 string nameArgs
@@ -789,6 +792,35 @@ private string getSignatureParameterName(string signature, string type, string n
789792 )
790793}
791794
795+ /**
796+ * Gets a `Function` identified by the `(namespace, type, name)` components.
797+ *
798+ * If `subtypes` is `true` then the result may be an override of the function
799+ * identified by the components.
800+ */
801+ pragma [ nomagic]
802+ private Function getFunction ( string namespace , string type , boolean subtypes , string name ) {
803+ elementSpec ( namespace , type , subtypes , name , _, _) and
804+ (
805+ funcHasQualifiedName ( result , namespace , name ) and
806+ subtypes = false and
807+ type = ""
808+ or
809+ exists ( Class namedClass , Class classWithMethod |
810+ hasClassAndName ( classWithMethod , result , name ) and
811+ classHasQualifiedName ( namedClass , namespace , type )
812+ |
813+ // member declared in the named type or a subtype of it
814+ subtypes = true and
815+ classWithMethod = namedClass .getADerivedClass * ( )
816+ or
817+ // member declared directly in the named type
818+ subtypes = false and
819+ classWithMethod = namedClass
820+ )
821+ )
822+ }
823+
792824/**
793825 * Holds if the suffix containing the entries in `signature` starting at entry
794826 * `i` matches the suffix containing the parameters of `func` starting at entry `i`.
@@ -812,13 +844,17 @@ private string getSignatureParameterName(string signature, string type, string n
812844 * is `func:n` then the signature name is compared with the `n`'th name
813845 * in `name`.
814846 */
815- private predicate signatureMatches ( Function func , string signature , string type , string name , int i ) {
847+ pragma [ nomagic]
848+ private predicate signatureMatches (
849+ Function func , string namespace , string signature , string type , string name , int i
850+ ) {
851+ func = getFunction ( namespace , type , _, name ) and
816852 exists ( string s |
817853 s = getSignatureParameterName ( signature , type , name , i ) and
818854 s = getParameterTypeName ( func , i )
819855 ) and
820856 if exists ( getParameterTypeName ( func , i + 1 ) )
821- then signatureMatches ( func , signature , type , name , i + 1 )
857+ then signatureMatches ( func , namespace , signature , type , name , i + 1 )
822858 else i = count ( signature .indexOf ( "," ) )
823859}
824860
@@ -833,7 +869,7 @@ module ExternalFlowDebug {
833869 *
834870 * Exposed for testing purposes.
835871 */
836- predicate signatureMatches_debug = signatureMatches / 5 ;
872+ predicate signatureMatches_debug = signatureMatches / 6 ;
837873
838874 /**
839875 * INTERNAL: Do not use.
@@ -883,6 +919,7 @@ private predicate parseParens(string s, string betweenParens) { s = "(" + betwee
883919 * - `signatureWithoutParens` equals `signature`, but with the surrounding
884920 * parentheses removed.
885921 */
922+ pragma [ nomagic]
886923private predicate elementSpecWithArguments0 (
887924 string signature , string type , string name , string signatureWithoutParens , string typeArgs ,
888925 string nameArgs
@@ -909,7 +946,7 @@ private predicate elementSpecMatchesSignature(
909946) {
910947 elementSpec ( namespace , pragma [ only_bind_into ] ( type ) , subtypes , pragma [ only_bind_into ] ( name ) ,
911948 pragma [ only_bind_into ] ( signature ) , _) and
912- signatureMatches ( func , signature , type , name , 0 )
949+ signatureMatches ( func , namespace , signature , type , name , 0 )
913950}
914951
915952/**
@@ -953,7 +990,7 @@ private predicate funcHasQualifiedName(Function func, string namespace, string n
953990 * Holds if `namedClass` is in namespace `namespace` and has
954991 * name `type` (excluding any template parameters).
955992 */
956- bindingset [ type, namespace ]
993+ bindingset [ type]
957994pragma [ inline_late]
958995private predicate classHasQualifiedName ( Class namedClass , string namespace , string type ) {
959996 exists ( string typeWithoutArgs |
@@ -969,17 +1006,14 @@ private predicate classHasQualifiedName(Class namedClass, string namespace, stri
9691006 * are also returned.
9701007 * 3. The element has name `name`
9711008 * 4. If `signature` is non-empty, then the element has a list of parameter types described by `signature`.
972- *
973- * NOTE: `namespace` is currently not used (since we don't properly extract modules yet).
9741009 */
9751010pragma [ nomagic]
9761011private Element interpretElement0 (
9771012 string namespace , string type , boolean subtypes , string name , string signature
9781013) {
1014+ result = getFunction ( namespace , type , subtypes , name ) and
9791015 (
9801016 // Non-member functions
981- funcHasQualifiedName ( result , namespace , name ) and
982- subtypes = false and
9831017 type = "" and
9841018 (
9851019 elementSpecMatchesSignature ( result , namespace , type , subtypes , name , signature )
@@ -989,52 +1023,36 @@ private Element interpretElement0(
9891023 )
9901024 or
9911025 // Member functions
992- exists ( Class namedClass , Class classWithMethod |
993- hasClassAndName ( classWithMethod , result , name ) and
994- classHasQualifiedName ( namedClass , namespace , type )
995- |
996- (
997- elementSpecMatchesSignature ( result , namespace , type , subtypes , name , signature )
998- or
999- signature = "" and
1000- elementSpec ( namespace , type , subtypes , name , "" , _)
1001- ) and
1002- (
1003- // member declared in the named type or a subtype of it
1004- subtypes = true and
1005- classWithMethod = namedClass .getADerivedClass * ( )
1006- or
1007- // member declared directly in the named type
1008- subtypes = false and
1009- classWithMethod = namedClass
1010- )
1011- )
1026+ elementSpecMatchesSignature ( result , namespace , type , subtypes , name , signature )
10121027 or
1013- elementSpec ( namespace , type , subtypes , name , signature , _) and
1014- // Member variables
10151028 signature = "" and
1016- exists ( Class namedClass , Class classWithMember , MemberVariable member |
1017- member .getName ( ) = name and
1018- member = classWithMember .getAMember ( ) and
1019- namedClass .hasQualifiedName ( namespace , type ) and
1020- result = member
1021- |
1022- // field declared in the named type or a subtype of it (or an extension of any)
1023- subtypes = true and
1024- classWithMember = namedClass .getADerivedClass * ( )
1025- or
1026- // field declared directly in the named type (or an extension of it)
1027- subtypes = false and
1028- classWithMember = namedClass
1029- )
1029+ elementSpec ( namespace , type , subtypes , name , signature , _)
1030+ )
1031+ or
1032+ // Member variables
1033+ elementSpec ( namespace , type , subtypes , name , signature , _) and
1034+ signature = "" and
1035+ exists ( Class namedClass , Class classWithMember , MemberVariable member |
1036+ member .getName ( ) = name and
1037+ member = classWithMember .getAMember ( ) and
1038+ namedClass .hasQualifiedName ( namespace , type ) and
1039+ result = member
1040+ |
1041+ // field declared in the named type or a subtype of it (or an extension of any)
1042+ subtypes = true and
1043+ classWithMember = namedClass .getADerivedClass * ( )
10301044 or
1031- // Global or namespace variables
1032- elementSpec ( namespace , type , subtypes , name , signature , _) and
1033- signature = "" and
1034- type = "" and
1045+ // field declared directly in the named type (or an extension of it)
10351046 subtypes = false and
1036- result = any ( GlobalOrNamespaceVariable v | v . hasQualifiedName ( namespace , name ) )
1047+ classWithMember = namedClass
10371048 )
1049+ or
1050+ // Global or namespace variables
1051+ elementSpec ( namespace , type , subtypes , name , signature , _) and
1052+ signature = "" and
1053+ type = "" and
1054+ subtypes = false and
1055+ result = any ( GlobalOrNamespaceVariable v | v .hasQualifiedName ( namespace , name ) )
10381056}
10391057
10401058cached
0 commit comments