2020-01-24 18:39:58 +01:00
|
|
|
# This file describes custom XPath functions per language
|
|
|
|
# This is rendered using _includes/custom/xpath_fun_doc.html
|
|
|
|
|
2019-04-05 14:13:39 +02:00
|
|
|
aliases:
|
|
|
|
- &qname_param
|
|
|
|
name: javaQualifiedName
|
|
|
|
type: "xs:string"
|
2019-04-07 18:00:02 +02:00
|
|
|
description: "The qualified name of a Java class, possibly with pairs of brackets to indicate an array type.
|
2019-04-05 14:13:39 +02:00
|
|
|
Can also be a primitive type name."
|
2022-03-20 13:09:48 +01:00
|
|
|
- &node_param
|
|
|
|
name: element
|
|
|
|
type: "xs:element"
|
|
|
|
description: "Any element node"
|
2019-04-05 14:13:39 +02:00
|
|
|
- &needs_typenode "The context node must be a {% jdoc jast::TypeNode %}"
|
2022-03-22 19:44:00 +01:00
|
|
|
- &coord_fun_note |
|
|
|
|
The function is not context-dependent, but takes a node as its first parameter.
|
2022-03-22 19:34:13 +01:00
|
|
|
- &needs_node_ctx "The requires the context node to be an element"
|
2019-04-05 14:13:39 +02:00
|
|
|
|
2019-03-06 01:29:53 +01:00
|
|
|
langs:
|
2022-03-22 19:46:21 +01:00
|
|
|
- name: "All languages"
|
2021-08-22 14:31:18 +02:00
|
|
|
ns: "pmd"
|
2022-03-22 19:46:21 +01:00
|
|
|
header: "Functions available to all languages are in the namespace `pmd`."
|
2021-08-22 14:31:18 +02:00
|
|
|
funs:
|
|
|
|
- name: fileName
|
|
|
|
returnType: "xs:string"
|
2022-03-20 13:09:48 +01:00
|
|
|
shortDescription: "Returns the simple name of the current file"
|
2022-03-22 19:34:13 +01:00
|
|
|
description: |
|
|
|
|
Returns the current simple file name, without path but including the extension.
|
|
|
|
This can be used to write rules that check file naming conventions.
|
2022-03-20 13:09:48 +01:00
|
|
|
|
2022-03-22 19:34:13 +01:00
|
|
|
since: 6.38.0
|
|
|
|
notes: *needs_node_ctx
|
2021-08-22 14:31:18 +02:00
|
|
|
examples:
|
|
|
|
- code: "//b[pmd:fileName() = 'Foo.xml']"
|
|
|
|
outcome: "Matches any `<b>` tags in files called `Foo.xml`."
|
|
|
|
|
2022-03-22 19:44:00 +01:00
|
|
|
- name: startLine
|
2022-03-20 13:09:48 +01:00
|
|
|
returnType: "xs:int"
|
|
|
|
parameters:
|
|
|
|
- *node_param
|
2022-03-22 19:44:00 +01:00
|
|
|
shortDescription: "Returns the start line of the given node"
|
2022-03-22 19:34:13 +01:00
|
|
|
description: |
|
|
|
|
Returns the line where the node starts in the source file.
|
|
|
|
Line numbers are 1-based.
|
2022-03-20 13:09:48 +01:00
|
|
|
|
2022-03-22 19:34:13 +01:00
|
|
|
since: 6.44.0
|
2022-03-22 19:44:00 +01:00
|
|
|
notes: *coord_fun_note
|
2022-03-20 13:09:48 +01:00
|
|
|
examples:
|
2022-03-22 19:44:00 +01:00
|
|
|
- code: "//b[pmd:startLine(.) > 5]"
|
2022-03-20 13:09:48 +01:00
|
|
|
outcome: "Matches any `<b>` node which starts after the fifth line."
|
|
|
|
|
|
|
|
- name: endLine
|
|
|
|
returnType: "xs:int"
|
|
|
|
parameters:
|
|
|
|
- *node_param
|
|
|
|
shortDescription: "Returns the end line of the given node"
|
2022-03-22 19:34:13 +01:00
|
|
|
description: |
|
|
|
|
Returns the line where the node ends in the source file.
|
|
|
|
Line numbers are 1-based.
|
2022-03-20 13:09:48 +01:00
|
|
|
|
2022-03-22 19:34:13 +01:00
|
|
|
since: 6.44.0
|
2022-03-22 19:44:00 +01:00
|
|
|
notes: *coord_fun_note
|
2022-03-20 13:09:48 +01:00
|
|
|
examples:
|
2022-03-22 19:44:00 +01:00
|
|
|
- code: "//b[pmd:endLine(.) == pmd:startLine(.)]"
|
2022-03-20 13:09:48 +01:00
|
|
|
outcome: "Matches any `<b>` node which doesn't span more than one line."
|
|
|
|
|
2022-03-22 19:44:00 +01:00
|
|
|
- name: startColumn
|
|
|
|
returnType: "xs:int"
|
|
|
|
parameters:
|
|
|
|
- *node_param
|
|
|
|
shortDescription: "Returns the start column of the given node (inclusive)"
|
|
|
|
description: |
|
|
|
|
Returns the column number where the node starts in the source file.
|
|
|
|
Column numbers are 1-based. The start column is inclusive.
|
|
|
|
|
|
|
|
since: 6.44.0
|
|
|
|
notes: *coord_fun_note
|
|
|
|
examples:
|
|
|
|
- code: "//b[pmd:startColumn(.) = 1]"
|
|
|
|
outcome: "Matches any `<b>` node which starts on the first column of a line"
|
|
|
|
|
|
|
|
- name: endColumn
|
|
|
|
returnType: "xs:int"
|
|
|
|
parameters:
|
|
|
|
- *node_param
|
|
|
|
shortDescription: "Returns the end column of the given node (exclusive)"
|
|
|
|
description: |
|
|
|
|
Returns the column number where the node ends in the source file.
|
|
|
|
Column numbers are 1-based. The end column is exclusive.
|
|
|
|
|
|
|
|
since: 6.44.0
|
|
|
|
notes: *coord_fun_note
|
|
|
|
examples:
|
|
|
|
- code: "//b[pmd:startLine(.) = pmd:endLine(.) and pmd:endColumn(.) - pmd:startColumn(.) = 1]"
|
|
|
|
outcome: "Matches any `<b>` node which spans exactly one character"
|
2021-08-22 14:31:18 +02:00
|
|
|
|
2019-03-06 01:29:53 +01:00
|
|
|
- name: "Java"
|
|
|
|
ns: "pmd-java"
|
|
|
|
funs:
|
2020-11-13 14:33:25 +01:00
|
|
|
- name: nodeIs
|
|
|
|
returnType: "xs:boolean"
|
|
|
|
shortDescription: "Tests the runtime type of the node instance"
|
|
|
|
description: "Returns true if the runtime type of the AST node is a subtype of the given class.
|
|
|
|
Contrary to typeIs, this tests the type of the AST node.
|
|
|
|
For example, the AST node for a literal (e.g. `5d`) has type ASTNumericLiteral,
|
|
|
|
and this function will ignore the static type of the expression (double)"
|
|
|
|
parameters:
|
|
|
|
- name: nodeClassName
|
|
|
|
type: "xs:string"
|
|
|
|
description: "Simple name of a class or interface in package {% jdoc_package :jast %}, without the 'AST' prefix"
|
|
|
|
examples:
|
|
|
|
- code: '//*[pmd-java:nodeIs("Expression")]'
|
|
|
|
outcome: "Matches all nodes that implement {% jdoc jast::ASTExpression %}"
|
|
|
|
- code: '//*[pmd-java:nodeIs("AnyTypeDeclaration")]'
|
|
|
|
outcome: "Matches all nodes that implement {% jdoc jast::ASTAnyTypeDeclaration %}"
|
|
|
|
- code: '//*[pmd-java:nodeIs("Foo")]'
|
|
|
|
outcome: "Runtime error, there's no class ASTFoo in the package"
|
|
|
|
|
2019-03-06 01:29:53 +01:00
|
|
|
- name: typeIs
|
|
|
|
returnType: "xs:boolean"
|
2019-04-05 14:13:39 +02:00
|
|
|
shortDescription: "Tests a node's static type"
|
2019-04-07 18:00:02 +02:00
|
|
|
description: "Returns true if the context node's static Java type is a subtype of the given type.
|
|
|
|
This tests for the resolved type of the Java construct, not the type of the AST node.
|
2020-11-13 14:33:25 +01:00
|
|
|
For example, the AST node for a literal (e.g. `5d`) has type ASTNumericLiteral, however this
|
2019-04-07 18:00:02 +02:00
|
|
|
function will compare the type of the literal (eg here, `double`) against the argument."
|
2019-04-05 14:13:39 +02:00
|
|
|
notes: *needs_typenode
|
2019-03-06 01:29:53 +01:00
|
|
|
parameters:
|
2019-04-05 14:13:39 +02:00
|
|
|
- *qname_param
|
2019-04-07 18:00:02 +02:00
|
|
|
examples:
|
|
|
|
- code: '//FormalParameter[pmd-java:typeIs("java.lang.String[]")]'
|
|
|
|
outcome: "Matches formal parameters of type `String[]` (including vararg parameters)"
|
|
|
|
- code: '//VariableDeclaratorId[pmd-java:typeIs("java.lang.List")]'
|
|
|
|
outcome: "Matches variable declarators of type `List` or any of its subtypes (including e.g. `ArrayList`)"
|
|
|
|
|
2019-03-06 01:29:53 +01:00
|
|
|
- name: typeIsExactly
|
|
|
|
returnType: "xs:boolean"
|
2019-04-05 14:13:39 +02:00
|
|
|
shortDescription: "Tests a node's static type, ignoring subtypes"
|
2019-03-06 01:29:53 +01:00
|
|
|
description: "Returns true if the context node's static type is exactly the given type.
|
|
|
|
In particular, returns false if the context node's type is
|
|
|
|
a subtype of the given type."
|
2019-04-05 14:13:39 +02:00
|
|
|
notes: *needs_typenode
|
|
|
|
parameters:
|
|
|
|
- *qname_param
|
2019-04-07 18:00:02 +02:00
|
|
|
examples:
|
|
|
|
- code: '//VariableDeclaratorId[pmd-java:typeIsExactly("java.lang.List")]'
|
|
|
|
outcome: "Matches variable declarators of type `List` (but not e.g. `ArrayList`)"
|
|
|
|
|
2019-03-06 01:29:53 +01:00
|
|
|
|
|
|
|
- name: metric
|
|
|
|
returnType: "xs:decimal?"
|
2019-04-05 14:13:39 +02:00
|
|
|
shortDescription: "Computes and returns the value of a metric"
|
2020-12-10 21:54:53 +01:00
|
|
|
description:
|
|
|
|
Returns the value of the metric as evaluated on the context node.
|
|
|
|
If the metric cannot be computed on that node, returns an empty sequence
|
|
|
|
(which is falsy).
|
|
|
|
|
2019-03-06 01:29:53 +01:00
|
|
|
parameters:
|
|
|
|
- name: "metricKey"
|
2019-03-06 02:22:36 +01:00
|
|
|
type: "xs:string"
|
2020-12-10 21:54:53 +01:00
|
|
|
description: "The name of a metric in {% jdoc jmx::JavaMetrics %} (or an alias thereof)."
|
|
|
|
examples:
|
|
|
|
- code: "//ClassOrInterfaceDeclaration[metric('NCSS') > 200]"
|
|
|
|
outcome: ""
|
|
|
|
- code: "//MethodDeclaration[metric('CYCLO') > 10 and metric('NCSS') > 20]"
|
|
|
|
outcome: ""
|
|
|
|
- code: "//TypeParameter[metric('idontexist') > 50]"
|
|
|
|
outcome: "Error: no such metric"
|
2020-11-13 14:33:25 +01:00
|
|
|
|
|
|
|
- name: hasAnnotation
|
|
|
|
returnType: "xs:boolean"
|
|
|
|
shortDescription: "Tests whether an annotation is present on the node"
|
|
|
|
description: "Returns true if the node has an annotation with the given qualified name"
|
|
|
|
notes: "The context node must be an {% jdoc jast::Annotatable %}, otherwise this returns false"
|
|
|
|
parameters:
|
|
|
|
- name: annotationClassName
|
|
|
|
type: "xs:string"
|
|
|
|
description: "Canonical name of an annotation type"
|
|
|
|
examples:
|
|
|
|
- code: '//MethodDeclaration[pmd-java:hasAnnotation("java.lang.Override")]'
|
|
|
|
outcome: "Matches all method declarations that are annotated with @Override"
|
|
|
|
|
|
|
|
- name: modifiers
|
|
|
|
returnType: "xs:string*"
|
|
|
|
shortDescription: "Produce the effective modifiers of a node"
|
|
|
|
description: >-
|
|
|
|
Returns a sequence of the effective modifiers of a node as strings.
|
|
|
|
This is documented on {% jdoc jast::ASTModifierList#getEffectiveModifiers() %}.
|
|
|
|
|
|
|
|
notes: "The context node must be an {% jdoc jast::AccessNode %}, otherwise this returns an empty sequence"
|
|
|
|
parameters:
|
|
|
|
examples:
|
|
|
|
- code: '//MethodDeclaration[pmd-java:modifiers() = "native"]'
|
|
|
|
outcome: "Matches native method declarations"
|
|
|
|
- code: '//MethodDeclaration[pmd-java:modifiers() = ("native", "static")]'
|
|
|
|
outcome: >-
|
|
|
|
Matches method declarations that have a 'native' OR a 'static' modifier.
|
|
|
|
This may be counter-intuitive.
|
|
|
|
- code: '//MethodDeclaration[pmd-java:modifiers() = "public"]'
|
|
|
|
outcome: >-
|
|
|
|
Matches method declarations that have a 'public' modifier, explicit or implicit.
|
|
|
|
For example, this would match methods in interfaces, which implicitly have the
|
|
|
|
modifier. Use the `explicitModifiers` function if you don't want the implicit part.
|
|
|
|
Also note that `@Visibility = 'public'` is a better use of the API, in this particular
|
|
|
|
instance.
|
|
|
|
|
|
|
|
- name: explicitModifiers
|
|
|
|
returnType: "xs:string*"
|
|
|
|
shortDescription: "Produce the explicit modifiers of a node"
|
|
|
|
description: >-
|
|
|
|
Returns a sequence of the explicit modifiers of a node as strings.
|
|
|
|
This is documented on {% jdoc jast::ASTModifierList#getExplicitModifiers() %}.
|
|
|
|
|
|
|
|
notes: "The context node must be an {% jdoc jast::AccessNode %}, otherwise this returns an empty sequence"
|
|
|
|
parameters:
|
|
|
|
examples:
|
|
|
|
- code: '//MethodDeclaration[pmd-java:explicitModifiers() = "public"]'
|
|
|
|
outcome: "Matches method declarations that have an explicit 'public' modifier."
|
|
|
|
|
|
|
|
- name: matchesSig
|
|
|
|
returnType: "xs:boolean"
|
|
|
|
shortDescription: "Matches the signature called by a method or constructor call"
|
|
|
|
description: >-
|
|
|
|
Uses an {% jdoc java::lang.java.types.TypeTestUtil.InvocationMatcher %} to test
|
|
|
|
the method signature called by the context node. The format of the parameter is
|
|
|
|
described on that class.
|
|
|
|
|
|
|
|
notes: "The context node must be an {% jdoc jast::InvocationNode %}, otherwise this returns false"
|
|
|
|
parameters:
|
|
|
|
- name: "sig"
|
|
|
|
type: "xs:string"
|
|
|
|
description: "A signature, in the format described on {% jdoc java::lang.java.types.TypeTestUtil.InvocationMatcher %}"
|
|
|
|
examples:
|
|
|
|
- code: '//MethodCall[pmd-java:matchesSig("_#equals(java.lang.Object)")]'
|
|
|
|
outcome: "Matches calls to the method `equals` on any receiver type"
|
|
|
|
- code: '//MethodCall[pmd-java:matchesSig("java.lang.Enum#equals(java.lang.Object)")]'
|
|
|
|
outcome: "Matches calls to the method `equals` on receiver that is a subtype of Enum"
|
|
|
|
- code: '//MethodCall[pmd-java:matchesSig("java.lang.String#toString()")]'
|
|
|
|
outcome: "Matches calls to the method `toString` on String receivers"
|
|
|
|
- code: '//MethodCall[pmd-java:matchesSig("_#_(int,int)")]'
|
|
|
|
outcome: "Matches calls to any method with 2 `int` parameters (!= argument)"
|
|
|
|
- code: '//ConstructorCall[pmd-java:matchesSig("java.util.ArrayList#new(int)")]'
|
|
|
|
outcome: "Matches constructors calls of ArrayList with a single int parameter"
|