Table of Contents

Analysis Predicates API

  • Written in Prolog to analyze Java :-)
  • This API is still instable.

Prolog Coding Conventions

  • each defined predicate is documented, especially the intended use-cases and meaning.
  • local predicates have a trailing '__'
  • asserted facts begin with 'cached_'
  • words of a predicate are seperated by an '_' , no camel cases.
  • variable names are written using camelcase
  • if variables names need to emphasize that they contain an ID, they end on “ID” (not “Id”)
  • we intend to name predicates so that they could be read as infix operators (e.g. “subtype(A,B)” = “A is subtype of B”).

Basic Predicates

caching

clear_query_cache/1

/*
* clear_query_cache(?Definition)
*
* retracts query facts, this is called via java for cleanup
*
*/

internal_type/1

/**
* internal_type(?TypeID)
* succeeds if TypeID is an ID of an internal cached type
*/

internal_package/1,

/**
* internal_package(?PackageID)
* succeeds if PackageID is an ID of an internal cached package
*/

fill_cache_of_internal_objects/0

/**
* fill_cache_of_internal_objects/0
* generate caching for all internal objects (package, types,..) for faster lookup
*/

constants

access/1

/**
* access(?Accessor)
*
* indicates if the given string is valid as access for classes, methods or fields
*
*/

field_modifier/1

/**
*   field_modifier(?Modifier)
*   possible field modifiers: static, final, transient, volatile
*/

modifier/1

/**
* modifier(?Modifier)
*
* indicates if the given string is valid as modifier:
*  static,final,strctfp, abstract, synchronized, transient,native,volatile
*/

lower_access/2

/**
* lower_access(+Access1, +Access2)
*
* < Relationship for visibility.
* (private < package < protected < public)
*/

classes

can_access_class/2

/**
* can_access_class(+ClassID, +AccessedClassID)
*
* checks if accessed class is visible/accessible for the other class
*/

can_access_field/2

/**
* can_access_field(+ClassID, +FieldID)
*
* checks if class can access field (if field is visible for class)
*/

can_access_method/2

/**
* can_access_method(+ClassID, +MethodID)
*
* Returns true if class can access method, else false.
*/

class_access/2

/**
* class_access(+ClassID, ?Access)
*
* gets the access (private, package, protected, public) of the class,
* or checks if the given access is correct for the given class.
*/

class_modifier/2

/**
* class_modifier(+ClassID, ?Modifier)
*
* gets the modifier (static, final, strictfp, abstract) of the class,
* or checks if the given modifier is correct for the given class.
*/

find_package/2

/**
* find_package(+Type, ?Package)
*
* finds the package to which class belongs
*/

implements_interface/2

/**
* implements_interface(?ClassID, ?InterfaceID)
*
* Checks if class (also interface is possible) implements (direct or indirect) the given interface.
*/

innerclass_of/3

/**
* innerclass_of(+InnerClassID, +EnclClassID, transitive)
*
* succeeds iff Arg1 is an inner class of Arg2
*          if it is contained directly Arg3 is atom 'direct'
*          else    Arg3 is atom 'indirect'
*/

same_package/2

/**
* same_package(+FirstClassID, +SecondClassID)
*
* checks if both classes are contained in the same package
*/

real_subtype/2

/** real_subtype(?SubClass,?SuperClass)
    true iff SubClass is a transitive subtype of SuperClass, and both are not equal
*/

classification - fields

constant/1

/**
 * constant(+FieldID)
 *
 * checks if a field is a constant, e.g. final static
 */

classification - methods

constructor/1

/**
 * constructor(+MethodID)
 *
 * checks if a method is a class initializer, object initializer or a
 * constructor.
 */

getter_method/1

/**
 * getter_method(+MethodID)
 *
 * This predicate will be true, if the Method
 * with the ID "MethodID" is a getter-Method
 */

getter_method/2

/**
 * getter_method(+MethodID, -Attribute)
 *
 * This predicate will be true, if the Method
 * with the ID "MethodID" is a getter-Method and Attribute will be the FieldID used by the getter
 */

method_is_extern/1

/**	method_is_extern(+MethodID)
	succeeds iff Method corresponding to MethodID is contained in an extern class
*/

methods_refer_to_same_field/3

/** methods_refer_to_same_field(+ClassId,+MethodA,+MethodB) /3
	succeeds iff both methods (Arg2,Arg3) use the same field in Arg1
*/

normal_method/1

/** normal_method(+Method) /1
 *	succeeds iff Method is no trivial getter method, super constructor and constructor.
*/

setter_method/1

/**
 * setter_method(+Method)
 *
 * Method is a Method with one parameter, return type void,
 * and its name starts with "set".
 */

setter_method/2

/**
 * setter_method(+MethodID, -Attribute)
 *
 * This predicate will be true, if the Method
 * with the ID "MethodID" is a setter-Method and Attribute is the FieldID  used by the setter
 */

super_constructor/1

/**
 * super_constructor(+MethodID)
 *
 * checks if a method is the super constructor
 *
 */

is_test_method/1

/**
 * is_test_method(+MethodID)
 *
 * True, if MethodID
 *   - begins with "test"
 *   - isSubtype the TestCase-Class
 *   - has no return values (void)
 */

trivial_getter_method/1

/**
 *	trivial_getter_method(+MethodID)
 *
 *	This predicate will be true, if the method with the ID "MethodID" is a
 *  trivial getter-Method.
 *
 *  example (for field "int x;"):
 *
 *  public int getX() {
 *    return x;
 *  }
 */

trivial_setter_method/1

/**
 *	trivial_setter_method(+Method)
 *
 *	This predicate will be true, if the method with the ID "Method" is a
 *  trivial getter-Method.
 *
 *  example (for field "int x;"):
 *
 *  public void setX(int x) {
 *    this.x = x;
 *  }
 */

internal_method/1

/**
*  internal_method(?MethodID)
*  succeeds iff method with ID Arg1 is in an internal type
*/

classification - packages

extended_package/1

/**
 * extended_package(?Package)
 *
 * succeeds for packages that containt external as well as internal types
 */

external_package/1

/**
 * external_package(?Package)
 *
 * Suceeds if all the types in the package are external.
 * Thus, empty packages are external.
 */

classification - types

anonymous_class/1

/**
*  anonymous_class(+Class)
*  succeeds iff Class is an anonymous class.
*/

class_object/1

/**
*  class_object(+Class)
*  succeeds iff Class is in Package java.lang
*/

external_type/1

/**
* external_type(+Type)
* succeeds iff Type is extern
*/

real_class/1

/** real_class(+ClassID)
*   succeeds iff ClassID is not an interface
*/

is_interface/1

/** is_interface(+ClassID)
*   succeeds iff ClassID is not an interface
*/

is_named/1

/**
*  is_named(+Type)
*  succeeds iff Type is not anonymous
*/

java_exception/1

/**
* java_exception(?ClassID)
*
* Checks if class is an exception class.
*/

named_internal_type/1

/**
*  named_internal_type(+Class) /1
*  succeeds iff Class is a named internal Type
*/

test_class/1

/**
 * test_class(?ClassID)
 *
 * succeeds for all jUnit 3 test classes
 */

containment - filesystem

compilationunit_is_in_sourcefolder/2

/**
*  compilationunit_is_in_sourcefolder(+CompilationUnit, -SourceFolder)
*  succeeds iff Arg2 is the sourcefolder in which Arg1 is
*/

sourcefolder_contains_compilationunit/2

/**
*  sourcefolder_contains_compilationunit(+SourceFolder, ?CompilationUnit)
*  succeeds if Arg1 is contained in sourcefolder with Arg2
*/

sourcefolder_contains_type/2

/**
* sourcefolder_contains_type(+SourceFolder, ?Type)
* succeeds iff sourcefolder Arg1 containes type with ID Arg2
*/

type_is_in_sourcefolder/2

/**
*  type_is_in_sourcefolder(+Type, -SourceFolder)
*  succeeds if type with ID Arg1 is contained in sourcefolder Arg2
*/

containment - in

compilationunit_contains_type/2

/**
*  compilationunit_contains_type(+CompilationUnit, ?Type)
*  succeeds iff Arg1 contains a type with ID Arg2
*/

method_contains_localclass/2

/**
* method_contains_localclass(+Method, ?LocalClass)
* succeeds if method with ID Arg1 contains a local class with ID Arg2
*/

method_contains_parameter/2

/**
* method_contains_parameter(+Method, ?Parameter)
*  succeeds if a given method with ID Arg1 has a parameter with ID Arg2
*/

method_contains_call/2

/**
* method_contains_call(+Method, ?Call)
*  succeeds if a given method with ID Arg1 has a call with ID Arg2
*/

package_contains_compilationunit/2

/**
* package_contains_compilationunit(+Package, ?CompilationUnit)
* succeeds iff package with ID Arg1 contains a compilation unit with ID Arg2
*/

package_contains_type/2

/**
*  package_contains_type(+Package, ?Type)
*  succeeds iff package with ID Arg1 contains a type with ID Arg2
*/

type_contains_field/2

/**
*  type_contains_field(+Type, ?Field)
*  succeeds iff type with ID Arg1 contains a field with ID Arg2
*/

type_contains_method/2

/**
*  type_contains_method(+Type, ?Method)
*  succeeds iff type with ID Arg1 contains a method with ID Arg2
*/

type_contains_type/2

/**
*  type_contains_type(+OuterType, ?InnerType)
*  succeeds iff type with ID Arg1 contains a inner type with ID Arg2
*/

type_contains_type_transitive/2

/**
*  type_contains_type(+OuterType, ?InnerType)
*  succeeds iff type with ID Arg1 contains a inner type with ID Arg2,  search is done transitive.
*/

containment - out

compilationunit_is_in_package/2

/**
*  compilationunit_is_in_package(+CompilationUnit, ?Package)
*  succeeds iff CompilationUnit has a package with ID Package
*/

field_is_in_type/2

/**
*   field_is_in_type(+Field, ?Type)
*   succeeds if Field is a field in type with ID Type
*/

localclass_is_in_method/2

/**
*  localclass_is_in_method(+LocalClass, -Method)
*  succeeds if Arg1 is a local class defined in method Arg2
*/

method_is_in_type/2

/**
* method_is_in_type(+Method, ?Type)
* succeeds iff method with ID Arg1  has parent Arg2
*/

type_is_in_compilationunit/2

/**
* type_is_in_compilationunit(+Type, ?CompilationUnit)
* succeeds iff class with ID Arg1  is in compilation unit Arg2
*/

type_is_in_package/2

/**
* type_is_in_package(+Type, ?Package)
* succeeds iff type with ID Arg1  is in package Arg2
*/

type_is_in_type/2

/**
*  type_is_in_type(+InnerType, ?OuterType)
*  succeeds iff Arg1 is the inner type in type Arg2
*/

type_is_in_type_transitive/2

/**
*  type_is_in_type_transitive(+InnerType, ?OuterType)
*  succeeds iff Arg1 is the inner type in type Arg2, transitive
*/

fields

field_access/2

/**
* field_access(+FieldID, ?Access)
*
* checks if field access equals given access.
* Can also be used to get field access
*/

field_modifier/2

/**
* field_modifier(+FieldID, ?Modifier)
* succeeds if Arg2 is a valid modifier for field Arg1
*/

field_read_access/1

/**
* field_read_access(+GetFieldID)
*
* indicates if a field access (getFieldT) is read access.
*/

field_write_access/1

/**
* field_write_access(?GetFieldID)
*
* indicates if a field access (getFieldT) is write access.
*/

field_type/2

/**
* field_type_name(?FieldID, ?TypeName)
*
* Maps a field and its field type name (eg. int).
*/

field_is_pseudo_final/1

/**
* field_is_pseudo_final(+FieldID)
* succeeds if field with FieldID is "final":
*                    it is initialized but nowhere assigned,
*                 or it is not initialized and exactly once assigned
*/

field_is_inherited/1

/**
* field_is_inherited(+FieldID)
*
* Returns true if given field is inherited from a super class of its owner class, else false.
* If no FieldID is given, the ID of an inherited field will be returned.
*/

field_is_initialized/1

/**
* field_is_initialized(?FieldID)
* succeeds if Arg1 is an ID of a field which has been initialized
*/

identifier

declared_identifier/2

/**
 * declared_identifier(+Declaration, ?Identifier)
 * succeeds iff Arg1 is the ID of the name Arg2,
 *     Arg1 can be package,type,method, param, field, local
 */

splitAtomAtDots/2

        
/**
 * splitAtomAtDots(+AtomWithDots, -ListOfLowerCaseAtoms )
 *
 * Arg1 is an atom containing dots (".").
 * Arg2 is a list of the subatoms of Arg1 separated by dots. 
 * All elements of Arg2 are in lower case. 
 * Example: Arg1 = 'BLA.bLub.FOo'
 *   yields Arg2 = [bla, blub, foo].
 */

identifier_built_of_terms/2

 
/**
 * identifier_built_of_terms(+Identifier, ?Termlist)
 *
 * Arg1 is an atom in CamelCase spelling or containing  
 *      punctuation symbols (such as "." or "_").
 * Arg2 is a list of atoms in lower-case spelling. Each 
 *      atom in the list corresponds to a portion of Arg1
 *      up to (but excluding) the next capital letter or 
 *      punctuation symbol. The order of atoms in the list
 *      is the same as the order in Arg1. 
 * Example: Arg1 = 'thisIsAMix_of_CAMELCase.withPunctuation' yields
 * Arg2 = [this, is, a, mix, of, camel, case, with, punctuation]  
 */

referenced_identifier/2

/**
 * referenced_identifier(+Expression, ?Identifier)
 * succeeds if Arg1 is the ID of the references identifier Arg2
 */

math

count/3

/**
 * count(+ArgumentName, +PredicateCall, -Count)
 *
 * binds the length of a list resulting from a findall with ArgumentName
 * and PredicateCall to Count.
 */

divide/3

/**
 * divide(+Divident, +Divisor, ?Quotient)
 * succeeds if divisor is not equal zero and quotient is the normal division of divident/divisor
 */

divide/4

/**
 * divide(+Divident,+Divisor,?Quotient,+Default)
 * if divisor is zero, succeeds if Quotient is Default
 * else normal division is used.
 */

maxall/3

/**
 * maxall(+List,+PredicateCall, -Max)
 *
 * Calculates the maximum of a predicate, evaluated to argument
 */

minall/3

/**
 * minall(+List, +Predicate, -Max)
 *
 * Calculates the minimum of a predicate, evaluated to argument
 */

percentage/3

/**
*  percentage(+Part, +Total, -Result)
*  succeeds if Result is the percentage  of Part/Total * 100
*/

sumall/2

/**
*  sumall(+List,-Sum)
*  succeeds if Arg2 is the sum of the elements in List Arg1, uses swi-prolog
*/

methods

declared_in_interface/1

/**
* declared_in_interface(?MethodID)
*
* Checks if method is declared in an interface which is implemented by its class.
*/

equal_parameters/2

/**
* equal_parameters(+ParameterIDs1, +ParameterIDs2)
*
* Checks that type and name of the parameters are equal (same order is required).
*/

equal_parameter_types/2

/**
 * equal_parameter_types(+ParameterIDs1,+ParameterIDs2)
 *
 * Checks that the types of the parameters are equal (same order is required).
 */

equal_parameters_subset/2

/**
* equal_parameters_subset(+ParameterIDs1, +ParameterIDs2)
*
* Checks that the types and names of the parameters are equal.
* ParameterIDs2 is allowed to contain more parameters than ParameterIDs1.
*/

is_implementing/1

/**
 * is_implementing(+MethodId)
 *
 * checks if the method implements some abstract definition
 */

method_access/2

/**
* method_access(+MethodID, ?Access)
*
* Checks if method access equals given access.
* Can also be used to get method access.
*/

method_calls_method/2

/**
 * method_calls_method(+CallingMethodId, ?CalledMethodId)
 *
 * Tests whether the CalledMethod is called by CallingMethod.
 *
 * ASSUMES: CallingMethodId and CalledMethodId are Ids of some methods.
 */

method_calls_method_transitive/2

/**
 * method_calls_method(+CallingMethodId, ?CalledMethodId)
 *
 * Tests whether the CalledMethod is called by CallingMethod, transitive.
 *
 * ASSUMES: CallingMethodId and CalledMethodId are Ids of some methods.
 */

method_is_called_by_test/1

/**
 * method_is_called_by_test(+MethodId)
 *
 * Checks if a method is called by a test case.
 */

method_is_inherited/1

/**
* method_is_inherited(MethodID)
*
* Returns true if given method is inherited from a superclass of its owner class, else false.
* Checks if Method overrides a method from a superclass.
* If no MethodID is given, the ID of an inherited method will be returned.
*/

method_is_reimplemented/1

/*
* method_is_reimplemented(+MethodID)
*
* Returns true if given method is reimplemented in a sub class of its owner class, else false.
* Checks if Method is overridden by a subclass method.
* If no method ID is given, a ID of a overridden method will be returned.
*/

method_is_overriding/1

/**
* method_is_overriding(+MethodId)
*
* checks if the method overrides some other method.
*/

method_modifier/2

/*
* method_modifier(+MethodID, ?Modifier)
*
* gets the modifiers of given method or
* checks if given modifier belongs to specified method.
*/

number_of_statements_in_a_method/2

/**
* number_of_statements_in_a_method(+MethodID,-NumberOfStatements)
*	succeeds if Arg2 is the number of all statements in method with ID Arg1
*/

overrides/2

/**
* overrides(?MethodID, ?SuperMethodID)
*
* Returns true if Method overrides SuperMethod, else false.
* Method is overriding method, SuperMethod is overridden method.
* If no IDs are given, a pair of overriding and overriden method IDs will be returned.
*/

overrides/3

/**
* overrides(?MethodID, -SuperType, ?SuperMethodID)
*
* Returns true if Method overrides SuperMethod in SuperType, else false.
* Method is overriding method, SuperMethod is overridden method.
*/

parameter_difference/3

/**
* parameter_difference(+List1, +List2, -List3)
*
* Computes the difference of List1 and List2.
* Lis3 is List1\List2.
*/

parameter_names/2

/**
* parameter_names(?MethodID, ?ParameterNames)
*
* Maps method id with belonging parameter ids.
* Gets parameter names for given method id or
* gets method for given parameter names.
*/

parameter_type/2

/**
* parameter_type(?ParameterID, ?TypeTerm)
*
* Maps parameter id and TypeTerm.
* Gets matching parameter id and TypeTerm (eg. type(basic, int, 0)).
*/

parameter_type_name/2

/**
* parameter_type_name(?ParameterID, ?TypeName)
*
* Maps parameter id and parameter type name (eg. String).
*/

parameter_types/2

/**
* parameter_types(+Parameters,-ListOfParameterTypes)
* succeeds if Arg1 is the list representing the types from the parameter IDs in Arg1
*/

referenced_parameter/2

/**
* referenced_parameter(+MethodID, +ParameterIDOrName)
*
* Checks if the given parameter is used by method.
*/

return_type/2

/**
* return_type(+MethodID, -ReturnType)
* Returns the return type (TypeTerm) of given method
*/

return_type_id/2

/**
* return_type_id(?MethodID, ?ReturnType)
*
* Return the return type id og given method
*/

return_type_name/2

/**
* return_type_name(?MethodID, ?ReturnType)
*
* Returns the return type (name) of given method
*/

same_signature/2

/*
* same_signature(+MethodID, +AnotherMethodID)
*
* Returns true if both methods have the same name, the same number of parameters and the same
* parameter types (same order).
* If no MethodID is given, the IDs of two methods with the same signature will be returned.
*/

throws_exception/2

/**
* throws_exception(+MethodID, ?ExceptionID)
*
* indicates if method throws given exception or
* returns exception thrown by method.
*/

misc

array_name/3

/**
* array_name(?TypeName, ?Dim, ?ArrayName)
*
* Gets the array name (eg. String[]) for given type (eg. String) and dimension or
* gets the type and the dimension for given array name.
*/

bound/1

/**
* bound(+Variables)
*
* Same as nonvar, but can also process list (each element is tested).
* prints a message if unbound variable is found
*/

default_value/2

/**
* default_value(+TypeTerm, -Value)
*
* Gets the default value for given TypeTerm (eg. default_value(type(basic, boolean, 0), false)).
*/

equal_trees/2

/**
* equal_trees(+OriginalRoot, +CopyRoot)
*
* Checks if both trees have the same structure (all attributes except ids must be identical).
*/

type_term_nqn/2

/**
* type_term_nqn(?TypeTerm, ?TypeName)
*
* Maps TypeTerm (eg. type(basic, int, 1)) and (unqualified) type name (eg. int[]).
*/

lower_or_equal_access/2

/**
* lower_or_equal_access(+Access1, +Access2)
*
* <= Relationship for visibility.
* (private < package < protected < public)
*/

greater_or_equal_access/2

						
/**
* greater_or_equal_access(+Access1, +Access2)
*
* >= Relationship for visibility.
* (private < package < protected < public)
*/

statements

statement/3

						
/**
* statement(+StatementId, ?ParentId, ?EnclosingId)
* generic access to statements with parent and enclosing nodes
* no blockT, nopT
*/

statements_in_method/2

/**
 * statements_in_method(+MethodID, -Statements)
 *
 * Succeeds iff the Statements are part of the method with MethodID
 */

controlflow_affecting_statements/2

/**
 * controlflow_affecting_statements(+MethodID, -StatementID)
 *
 * Succeeds if the Statement is a statements that can affect the contrloflow
 * and is within the method with MethodID
 */

is_controlflow_affecting/1

/**
 * is_controlflow_affecting(+StatementID)
 *
 * Succeeds if the Statement with StatementID is a controlflow affecting statement
 */

structures

inheritance/2

/**
*  inheritance(+ClassId,?SuperClassId)
*  succeeds iff Arg1 inherited by Arg2, and Arg1 is not an interface, extern or anonymous
*/

implements/2

/**
*  implements(+ClassId,?SuperClassId)
*  succeeds iff Arg1 implements Arg2, and Arg1 is not an interface, extern or anonymous
*/

extends_recursive/2

/**
 * extends_recursive(?SubClass,?SuperClass)
 *
 * Tests whether SubClass extends a SuperClass are another class
 * which recursively extends SuperClass.
 */

extends_recursive/3

extends_recursive/4

extends_recursive_from_subclass/2

/**
 * extends_recursive_from_subclass(+SubClass,?SuperClass)
 */

extends_recursive_from_superclass/2

						
/**
 * extends_recursive_from_superclass(+SubClass,?SuperClass)
 */

util

find_source_location/4

/**
 * find_source_location(+PEF,-Filename,-Offset,-Length)
 *
 * Arg1 is the id of a class.
 * Arg2 is the absolute path of Arg1 relative to the workspace.
 * Arg3 is the starting point in file if the Arg1 is a class ID.
 * Arg4 is the length of the source portion representing the Arg1.
 *
 * @JIRA CV-257
 */

reduced_source_location/3

/**
* reduced_source_location(+PEF, -Offset, -Length)
*
*/

full_qualified_name_javaelement/2

/**
* full_qualified_name_javaelement(+Id,-Fqn)
* succeeds iff Arg2 is the full qualified name of Id Arg1
*/

parent_full_qualified_name_javaelement/2

/**
* parent_full_qualified_name_javaelement(+Id, -Fqn)
* see full_qualified_name_javaelement/2. if no fqn was found, the parent elements name is used.
*/

max_cycles/3

/**
  * max_cycles(+Set, ?DepType, ?MaxSortedCycles)
  *
  * arg1 is a list (set) of nodes in the examination graph
  * arg2 is the type of connection between the nodes
  * arg3 will be bound to lists of all nodes for each biggest strongly
  * connected part of the graph
*/

id_of_named_element/3

/**
* id_of_named_element(+FQNName,?Type,-ID) / 3
*  Succeeds if ID  can be resolved for specific FQNName and Type
*   Package,Class,Method, Field, Param, Parameter of a foreachT, Local
*/

lookup_specific_queryname/2

/* lookup_specific_queryname(-Type,-MetricName)
*  succeeds if Arg2 is a smells and metric name and Arg1 the corresponding type
*/

name_of_element/2

/**
 * name_of_element(+Id,?Name)
 * Succeeds iff Name is the corresponding Java name for Id.
 *
 */

where_is/2

/** where_is( +Head/Arity, -File) /2
 *  succeeds if File is the file in which the predicate with Head/Arity is defined
*/
Last modified: 2014/04/10 03:41
 
*