Metric Function Decorators

The API provides two mechanisms for defining and reporting metrics.

  • Define a metric function with a particular granularity and instruct CodeSonar to automatically apply the function to all elements of the corresponding type and report the resulting metric values.
  • Define a metric class with a particular granularity, then create a visitor that computes and reports values of that metric.

Functionality for the first of these mechanisms is provided by the metric function decorators in this section. The metric decorator you use will depend on the metric granularity.

Metric Granularity Metric Function Decorator Alternative, if you will compute and report in a visitor
project project_metricclass_function() project_metricclass_manager.create()
compunit compunit_metricclass_function() compunit_metricclass_manager.create()
sfile sfile_metricclass_function() sfile_metricclass_manager.create()
procedure procedure_metricclass_function() procedure_metricclass_manager.create()

Each decorator is overloaded four ways.

decorator arguments new metric class tag, description, flags
(none) Tag and description will both be set to the name of the decorated function. Note that this means class creation will fail if the function name is not a suitable tag (that is, it is longer than 15 characters, starts with a character other than [a-zA-Z], or contains a character other than [a-zA-Z][0-9] _-). Flags will be set to metricclass_flags.AUTO.
str Tag and description will both be set to the specified string. Flags will be set to metricclass_flags.AUTO.
str, str Tag will be set to the first string, description to the second. Flags will be set to metricclass_flags.AUTO.
str, str, metricclass_flags Tag will be set to the first string, description to the second, metric class flags will be set as specified. Note that one of the flags must be metricclass_flags.AUTO in order for the class to be computed automatically.

To define a new automatically-computed metric class:

  1. Identify the granularity G of the metric: project, compunit, sfile, or procedure.
  2. Define a function that computes your metric: it must take one argument of type G and return a floating point number.
  3. Apply the appropriate metric function decorator to the function.

For more information about metrics in CodeSonar, see the Metrics manual page.

Example

The following plug-in defines four automatically computed, project-granularity metric classes. Each class computes the same metric, but their tags and descriptions vary as described in the comments.

import cs

# tag and description will both have name of decorated function
@cs.project_metricclass_function
def num_compunits(p):
    return len(p.compunits_vector())

# tag and description will both be 'NCU', default flags value used
@cs.project_metricclass_function('NCU')
def num_compunits2(p):
    return len(p.compunits_vector())

# tag and description specified separately, default flags value used
@cs.project_metricclass_function(
    'NCUdesc',
    'Num Compunits With Description')
def num_compunits3(p):
    return len(p.compunits_vector())

# tag, description, and flags all specified separately
@cs.project_metricclass_function(
    'NCUflag',
    'Num Compunits With Description&Flag',
    cs.metricclass_flags.AUTO)
def num_compunits4(p):
    return len(p.compunits_vector())

Metric Decorators

@cs.project_metricclass_function([tag = name of decorated function[, desc = tag value[, flags = metricclass_flags.AUTO]]])

Create a new project_metricclass whose computation function is the decorated function.

Parameters:
  • tag (str) –

    (optional) A short name (tag) that will, in combination with the granularity, uniquely identify this metric class. The tag must:

    • Start with a character matching [a-zA-Z]
    • Only contain characters matching [a-zA-Z][0-9] _-
    • Have length <= 15 characters

    If you do not specify a tag, the name of the decorated function must conform to these requirements.

  • desc (str) –

    (optional) A human-readable description of the metric. When a metric shows up in a user interface, this is what is displayed. The description must:

    • Only contain characters matching [a-zA-Z][0-9] _-
    • Have length <= 35 characters
  • flags (metricclass_flags) – (optional) metricclass_flags characterizing the new metric class. Note that one of the flags must be metricclass_flags.AUTO in order for the class to be computed automatically.

CodeSonar will create a new automatically-computed project_metricclass whose properties are as follows.

metric class property set to
computation function the decorated function
tag (short name) the first argument to the decorator, if any, otherwise the name of the decorated function
description (human-readable name) the second argument to the decorator, if any, otherwise the same value as the tag
flags the third argument to the decorator, if any, otherwise metricclass_flags.AUTO.
# tag and description will both have name of decorated function
@cs.project_metricclass_function
def num_compunits(p):
   return len(p.compunits_vector())
# tag and description will both be 'NCU', default flags value used
@cs.project_metricclass_function('NCU')
def num_compunits2(p):
    return len(p.compunits_vector())
# tag and description specified separately, default flags value used
@cs.project_metricclass_function(
    'NCUdesc',
    'Num Compunits With Description')
def num_compunits3(p):
    return len(p.compunits_vector())
@cs.project_metricclass_function(
    'NCUflag',
    'Num Compunits With Description&Flag',
    cs.metricclass_flags.AUTO | cs.metricclass_flags.POST_ANALYSIS)
def num_compunits4(p):
    return len(p.compunits_vector())
@cs.compunit_metricclass_function([tag = name of decorated function[, desc = tag value[, flags = metricclass_flags.AUTO]]])

Create a new compunit_metricclass whose computation function is the decorated function.

Parameters:
  • tag (str) –

    (optional) A short name (tag) that will, in combination with the granularity, uniquely identify this metric class. The tag must:

    • Start with a character matching [a-zA-Z]
    • Only contain characters matching [a-zA-Z][0-9] _-
    • Have length <= 15 characters

    If you do not specify a tag, the name of the decorated function must conform to these requirements.

  • desc (str) –

    (optional) A human-readable description of the metric. When a metric shows up in a user interface, this is what is displayed. The description must:

    • Only contain characters matching [a-zA-Z][0-9] _-
    • Have length <= 35 characters
  • flags (metricclass_flags) – (optional) metricclass_flags characterizing the new metric class. Note that one of the flags must be metricclass_flags.AUTO in order for the class to be computed automatically.

CodeSonar will create a new automatically-computed compunit_metricclass whose properties are as follows.

metric class property set to
computation function the decorated function
tag (short name) the first argument to the decorator, if any, otherwise the name of the decorated function
description (human-readable name) the second argument to the decorator, if any, otherwise the same value as the tag
flags the third argument to the decorator, if any, otherwise metricclass_flags.AUTO.
# tag and description will both have name of decorated function
# Note that "num_buildwarnings" has 17 characters and therefore is not
# a suitable tag, so we use a shorter name for the decorated function here.
@cs.compunit_metricclass_function
def num_bws(c):
    return c.warning_count()
# tag and description will both be 'NBW', default flags value used
@cs.compunit_metricclass_function('NBW')
def num_buildwarnings2(c):
    return c.warning_count()
# tag and description specified separately, default flags value used
@cs.compunit_metricclass_function(
    'NBWdesc',
    'Num Build Warnings With Description')
def num_buildwarnings3(c):
    return c.warning_count()
# tag, description, and flags all specified separately
@cs.compunit_metricclass_function(
    'NBWflag',
    'Num Build Warnings With Description&Flag',
    cs.metricclass_flags.AUTO | cs.metricclass_flags.POST_ANALYSIS)
def num_buildwarnings4(c):
    return c.warning_count()
@cs.sfile_metricclass_function([tag = name of decorated function[, desc = tag value[, flags = metricclass_flags.AUTO]]])

Create a new sfile_metricclass whose computation function is the decorated function.

Parameters:
  • tag (str) –

    (optional) A short name (tag) that will, in combination with the granularity, uniquely identify this metric class. The tag must:

    • Start with a character matching [a-zA-Z]
    • Only contain characters matching [a-zA-Z][0-9] _-
    • Have length <= 15 characters

    If you do not specify a tag, the name of the decorated function must conform to these requirements.

  • desc (str) –

    (optional) A human-readable description of the metric. When a metric shows up in a user interface, this is what is displayed. The description must:

    • Only contain characters matching [a-zA-Z][0-9] _-
    • Have length <= 35 characters
  • flags (metricclass_flags) – (optional) metricclass_flags characterizing the new metric class. Note that one of the flags must be metricclass_flags.AUTO in order for the class to be computed automatically.

CodeSonar will create a new automatically-computed sfile_metricclass whose properties are as follows.

metric class property set to
computation function the decorated function
tag (short name) the first argument to the decorator, if any, otherwise the name of the decorated function
description (human-readable name) the second argument to the decorator, if any, otherwise the same value as the tag
flags the third argument to the decorator, if any, otherwise metricclass_flags.AUTO.
# tag and description will both have name of decorated function
@cs.sfile_metricclass_function
def num_instances(s):
    return len(list(s.instances()))
# tag and description will both be 'NI', default flags value used
@cs.sfile_metricclass_function('NI')
def num_instances2(s):
    return len(list(s.instances()))
# tag and description specified separately, default flags value used
@cs.sfile_metricclass_function(
    'NIdesc',
    'Num Instances With Description')
def num_instances3(s):
    return len(list(s.instances()))
# tag, description, and flags all specified separately
@cs.sfile_metricclass_function(
    'NIflag',
    'Num Instances With Description&Flag',
    cs.metricclass_flags.AUTO | cs.metricclass_flags.POST_ANALYSIS)
def num_instances4(s):
    return len(list(s.instances()))
@cs.procedure_metricclass_function([tag = name of decorated function[, desc = tag value[, flags = metricclass_flags.AUTO]]])

Create a new procedure_metricclass whose computation function is the decorated function.

Parameters:
  • tag (str) –

    (optional) A short name (tag) that will, in combination with the granularity, uniquely identify this metric class. The tag must:

    • Start with a character matching [a-zA-Z]
    • Only contain characters matching [a-zA-Z][0-9] _-
    • Have length <= 15 characters

    If you do not specify a tag, the name of the decorated function must conform to these requirements.

  • desc (str) –

    (optional) A human-readable description of the metric. When a metric shows up in a user interface, this is what is displayed. The description must:

    • Only contain characters matching [a-zA-Z][0-9] _-
    • Have length <= 35 characters
  • flags (metricclass_flags) – (optional) metricclass_flags characterizing the new metric class. Note that one of the flags must be metricclass_flags.AUTO in order for the class to be computed automatically.

CodeSonar will create a new automatically-computed procedure_metricclass whose properties are as follows.

metric class property set to
computation function the decorated function
tag (short name) the first argument to the decorator, if any, otherwise the name of the decorated function
description (human-readable name) the second argument to the decorator, if any, otherwise the same value as the tag
flags the third argument to the decorator, if any, otherwise metricclass_flags.AUTO.
# tag and description will both have name of decorated function
@cs.procedure_metricclass_function
def num_callsites(p):
    return p.call_sites_count()
# tag and description will both be 'NCS', default flags value used
@cs.procedure_metricclass_function('NCS')
def num_callsites2(p):
    return p.call_sites_count()
# tag and description specified separately, default flags value used
@cs.procedure_metricclass_function(
    'NCSdesc',
    'Num Call Sites With Description')
def num_callsites3(p):
    return p.call_sites_count()
# tag, description, and flags all specified separately
@cs.procedure_metricclass_function(
    'NCSflag',
    'Num Call Sites With Description&Flag',
    cs.metricclass_flags.AUTO | cs.metricclass_flags.POST_ANALYSIS)
def num_callsites4(p):
    return p.call_sites_count()