Jtest logo




Contents  Previous  Next  Index

Working With Node Sets


About Node Sets

When creating complex rules, you may want to create conditions that depend on specific attributes or relationships between multiple nodes. For example, if you have multiple nodes in a rule condition, you may want to specify exactly where Jtest starts and stops counting the number of "hits" (instances where the specified conditions are met). Or, you may want a rule to check if the total number of "hits" in two different sets of nodes is greater than 0. In such cases, you would create a rule that includes one or more set components.

Set components are a category of components that represent sets of nodes. These components include collectors and set operators. Collectors let you restrict a node or node set's quantity. Set operators let you specify a relationship between two or more set components (for example, they could be used to create a rule that checks that the total number of hits in two rule conditions is less than 1).

Using Set Operators to Specify Relationships Between Set Components

You can use set operators to create rule segments that collect the number of hits of a specific relationship between two set components. For example, you could use set operators to create a rule segment that collects the number of hits of the pattern of nodes that are in either set component A, or in set component B.

Set operators are rule elements that indicate two things:

  • Which two set components you want to represent a relationship between.
  • What type of relationship you want to establish between the two associated set components.

Because set operators establish relationships between set components, they must be connected to one set component (the set component that the set operator is attached to) and reference another set component (the "operand" of the set operator; i.e., the other set component that this set operator works with). Set operators can be used to establish four types of relationships:

  • a union of two set components
  • an intersection of two set components
  • an exclusive-or relationship between two set components
  • a difference between two set components

A union is the set of nodes that are:

  • in the attached collector, or
  • in the operand, or
  • in both the attached collector and the operand.

For example, if A represents a set component that contains nodes xx, yy, and zz, and B represents a set component that contains nodes ww, xx, and yy, a union between A and B would match xx, yy, zz, and ww.

An intersection is the set of nodes that are in both the attached set component and the operand. For example, if A represents a set component that contains nodes xx, yy, and zz, and B represents a set component that contains nodes ww, xx, and yy, an intersection between A and B would match xx and yy.

A difference is the set of nodes that are either:

  • In the attached set component (the "left" side) but not in the operand (the "right" side), or
  • In the operand (the "right" side), but not in the attached set component (the "left" side).

Thus, a right - left difference represents the nodes in the operand, but not the set operator, while a left - right difference represents the nodes that are in the set operator, but not in the operand. For example, if A represents a set component that contains nodes xx, yy, and zz, and B represents a set component that contains nodes ww, xx, and yy, an A-B difference between A and B would match zz, while a B-A difference would match ww.

An XOR (exclusive-or) relationship is the set of nodes that are in either the attached set component or the operand, but not the nodes that are in both. For example, if A represents a set component that contains nodes xx, yy, and zz, and B represents a set component that contains nodes ww, xx, and yy, a XOR between A and B would match zz and ww.

To establish such relationships between two set components (X and Y), you would:

  1. Attach a set operator to one set component (X) by right-clicking it and choosing Set Operator> <desired relation> from the shortcut menu that opens.
  2. Attach a label to the other set component (Y).
  3. Specify that you want Y to be the set operator's operand by selecting Y's label as the set component's operand value.

One common reason that you might use set operators is to create a rule that restricts the number of "hits" for a union, intersection, difference, or XOR node set.

The following image is the implementation of "Unused local variable". Please note the following features of this rule:

  1. The first collector, labelled A, will collect local variables that are used in non-declaration statements.
  2. The second collector will collect local variables that are declared in the method.
  3. "IsDecl" represents "Is this declaration?" If it's set to true, it returns true for declaration statements and if it's set to false, it returns true for non-declaration statement.
  4. The Difference set operator is used to find the difference of the two node sets.
  5. The Count node with $$>0 checks if the Difference set has at least one item. If it has at least one item, Jtest will report an error.

To create a rule that counts and restricts the total number of hits that occur for a specific type of relationship between two node sets:

  1. Create a rule condition that contains a set component (such as a collector).
  2. Label the set component by right-clicking it, then choosing Add Label> <label name> from the shortcut menu that opens. Once you have done this, you can make this component an operand of a set operator.
  3. Create another rule condition that contains a set component.
  4. Right-click the newly-added set component, then choose Create Set Operator> <desired type of relationship> from the shortcut menu that opens. A set operator will then be attached to this set component.
  5. Indicate the operand of this set operator by right-clicking the circle on the top right of the set operator and choosing the label of the first set component from the shortcut menu.
  6. Restrict the number of "hits" allowed for the specified relationship by right-clicking the set operator, choosing Count from the shortcut menu, then (if necessary) modifying the value included in the count node.

Once you have added an output arrow to your rule and specified rule properties, your rule will be complete.

Customizing Counts With Collectors, Counts, and Trigger Points

About Trigger Points

RuleWizard's Collector and Count commands let you create a rule condition that restricts a node or node set's quantity. To create such a rule condition, you would first create a collector, then right-click the collector and choose Count. The collector keeps track of the number of times that the specified pattern is found; Count places a condition on what number of instances constitutes a rule violation. When a rule that restricts a node's quantity is enforced, the number of instances of the pattern are collected in the collector, the count is checked, and a violation is reported if the count falls within the parameters specified in the rule.

By specifying when Jtest should empty the collector, you can determine precisely how the count is determined. This is done through the use of "trigger points." Trigger points determine the node at which Jtest starts and stops counting the number of instances that occur. The correct trigger point number to use is determined by counting back from the node to which the collector is attached, to the node at which you want the collector emptied and a violation reported (if the specified pattern is found).

For example, consider the following example:

In this example, a trigger point of 1 indicates to empty the collector after each member function is searched. (The Member Function node is one node "back" from the a=b node to which the collector and trigger point are attached). When enforced, this rule would, for each class, look for a member function in the class' body, then look in that member function for expressions in the form "a=b". The number of expressions that met this criteria would be placed in the collector, the count would be checked, and a violation would be reported if the count were zero. When another member function was parsed, the collector would then be emptied, and this process would be repeated for that member function.

If you changed the trigger point to 2, Jtest would look at all member functions and count the number of matching expressions in all member functions before emptying the collector. (The collector accumulates all values found from the Class node (2 nodes back from the node to which the trigger point and collector are attached), and the collector is not emptied until it a new class is parsed).

If you had a trigger point of 3 (the highest possible value in this example), Jtest would empty the collector only after the entire file was searched. (The collector accumulates all values found from the file node (2 actual and one applied node (the file is an applied node) back from the node to which the trigger point and collector are attached), and the collector is not emptied until a new file is parsed).

Creating a Trigger Point

When you create a collector, it is assigned a number 1 trigger point by default. To change the trigger point value, right-click the trigger point number and choose the desired value from the shortcut menu that opens.

Guidelines for using trigger points:

  • To get the maximum value for a particular trigger point, count the number of nodes from the node with the attached collector to the top node of the rule, then add 1.
  • You cannot place a trigger point on a node for which a direct check is performed.
  • You cannot add an output arrow between the collector and the node/applied node that the trigger point number points to. For example, in the above rule you could place an output arrow at the Class node when you have a trigger point of 1 or 2, but for trigger point 3 you would need to attach the output arrow to the collector (rather than to the Class node).

Determining the Output Type of a Set Component

If you place an output arrow on a set component, you will be asked to determine when the output "fires" (reports that the pattern has been violated). The available output options for set components are:

  • Hits Output: Fires on each "hit", or each node contained in the set. This type of output arrow is placed below the center of the set operator that it is attached to. When you choose this type of output, the violation output can contain fields of nodes contained in the set operator. For example, if you have a collector that contains variables in Java or C++ and you select a Hits Output, you can use an output message such as "Initialize all variables in constructor. Variable $name is not initialized." (When this rule is actually violated, the $name variable will be replaced with the name of the uninitialized variable).
  • Trigger Output: Fires once for the set when the set is triggered at the trigger point. This type of output arrow is placed below the left side of the set operator that it is attached to, or below the trigger point number. When you choose this type of output, the violation output can contain properties of the collector, but not properties of nodes contained in the set operator. Currently, the only variable you can use here is $count.

If your rule includes a collector, you can have your output include the number of "hits" that the collector has accumulated. To do this, enter COUNT(A) (where A is the label of the collector whose count you want reported) in the appropriate output message.

You can also have your output message list the items that a collector has accumulated. To do this, enter LIST(A) (where A is the label of the collector whose "list" you want reported) in the appropriate output message.

These two variables (COUNT and LIST) are called set references.


Contents  Previous  Next  Index

ParaSoft logo
(888) 305-0041 info@parasoft.com Copyright © 1996-2001 ParaSoft