@@ -363,6 +363,42 @@ Specific::InvokeNode getInvocationFromPath(string package, string type, AccessPa
363363 result = getInvocationFromPath ( package , type , path , path .getNumToken ( ) )
364364}
365365
366+ /**
367+ * Holds if `name` is a valid name for an access path token in the identifying access path.
368+ */
369+ bindingset [ name]
370+ predicate isValidTokenNameInIdentifyingAccessPath ( string name ) {
371+ name = [ "Argument" , "Parameter" , "ReturnValue" , "WithArity" ]
372+ or
373+ Specific:: isExtraValidTokenNameInIdentifyingAccessPath ( name )
374+ }
375+
376+ /**
377+ * Holds if `name` is a valid name for an access path token with no arguments, occuring
378+ * in an identifying access path.
379+ */
380+ bindingset [ name]
381+ predicate isValidNoArgumentTokenInIdentifyingAccessPath ( string name ) {
382+ name = "ReturnValue"
383+ or
384+ Specific:: isExtraValidNoArgumentTokenInIdentifyingAccessPath ( name )
385+ }
386+
387+ /**
388+ * Holds if `argument` is a valid argument to an access path token with the given `name`, occurring
389+ * in an identifying access path.
390+ */
391+ bindingset [ name, argument]
392+ predicate isValidTokenArgumentInIdentifyingAccessPath ( string name , string argument ) {
393+ name = [ "Argument" , "Parameter" ] and
394+ argument .regexpMatch ( "(N-|-)?\\d+(\\.\\.(N-|-)?\\d+)?" )
395+ or
396+ name = "WithArity" and
397+ argument .regexpMatch ( "\\d+(\\.\\.\\d+)?" )
398+ or
399+ Specific:: isExtraValidTokenArgumentInIdentifyingAccessPath ( name , argument )
400+ }
401+
366402/**
367403 * Module providing access to the imported models in terms of API graph nodes.
368404 */
@@ -441,5 +477,27 @@ module ModelOutput {
441477 "CSV " + kind + " row should have " + expectedArity + " columns but has " + actualArity +
442478 ": " + row
443479 )
480+ or
481+ // Check names and arguments of access path tokens
482+ exists ( AccessPath path , AccessPathToken token |
483+ isRelevantFullPath ( _, _, path ) and
484+ token = path .getToken ( _)
485+ |
486+ not isValidTokenNameInIdentifyingAccessPath ( token .getName ( ) ) and
487+ result = "Invalid token name '" + token .getName ( ) + "' in access path: " + path
488+ or
489+ isValidTokenNameInIdentifyingAccessPath ( token .getName ( ) ) and
490+ exists ( string argument |
491+ argument = token .getAnArgument ( ) and
492+ not isValidTokenArgumentInIdentifyingAccessPath ( token .getName ( ) , argument ) and
493+ result =
494+ "Invalid argument '" + argument + "' in token '" + token + "' in access path: " + path
495+ )
496+ or
497+ isValidTokenNameInIdentifyingAccessPath ( token .getName ( ) ) and
498+ token .getNumArgument ( ) = 0 and
499+ not isValidNoArgumentTokenInIdentifyingAccessPath ( token .getName ( ) ) and
500+ result = "Invalid token '" + token + "' is missing its arguments, in access path: " + path
501+ )
444502 }
445503}
0 commit comments