Changes between Initial Version and Version 1 of MetricQuery


Ignore:
Timestamp:
Feb 22, 2012, 1:08:52 PM (13 years ago)
Author:
manualwiki
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MetricQuery

    v1 v1  
     1= Metric Queries = 
     2A metric query language was designed to query some metric information about Erlang programs. 
     3 
     4== Defined metrics == 
     5===  module_sum === 
     6The domain of the query is a module. The sum of the chosen complexity structure metrics measured on the modules functions. The proper metrics adjusted in a list can be implemented in the desired number and order. 
     7===  line_of_code === 
     8The domain of the query is a module or a function. The number of the lines of part of the text, function, or module. The number of empty lines is not included in the sum. As the number of lines can be measured on more functions, or modules and the system is capable of returning the sum of these, the number of lines of the whole loaded program text can be enquired. 
     9===  char_of_code === 
     10The domain of the query is a module or a function. The number of characters in a program script. This metric is capable of measuring both the codes of functions and modules and with the help of aggregating functions we can enquire the total and average number of characters in a cluster, or in the whole source text. 
     11===  number_of_fun === 
     12The domain of the query is a module. This metric gives the number of functions implemented in the concrete module, but it does not contain the number of non-defined functions in the module. 
     13===  number_of_macros === 
     14The domain of the query is a module. This metric gives the number of defined macros in the concrete module, or modules. It is also possible to enquire the number of implemented macros in a module. 
     15===  number_of_records === 
     16The domain of the query is a module. This metric gives the number of defined records in a module. It is also possible to enquire the number of implemented records in a module. 
     17===  included_files === 
     18The domain of the query is a module. This metric gives the number of visible header files in a module. 
     19===  imported_modules === 
     20The domain of the query is a module. This metric gives the number of imported modules used in a concrete module. The metric does not contain the number of qualified calls (calls that have the following form: {{{module:function}}}). 
     21===  number_of_funpath === 
     22The domain of the query is a module. The total number of function paths in a module. The metric, besides the number of internal function links, also contains the number of external paths, or the number of paths that lead outward from the module. It is very similar to the metric called cohesion. 
     23===  function_calls_in === 
     24The domain of the query is a module. Gives the number of function calls into a module from other modules. It can not be implemented to measure a concrete function. For that we use the {{{calls_for/1}}} function. 
     25===  function_calls_out === 
     26The domain of the query is a module. Gives the number of every function call from a module towards other modules. It can not be implemented to measure a concrete function. For that we use the {{{calls_from/1}}} function. 
     27===  cohesion === 
     28The domain of the query is a module. The number of call-paths of functions that call each other. By call-path we mean that an {{{f1}}} function calls {{{f2}}} (e.g. {{{f1()->f2()}}}.). If {{{f2}}} also calls {{{f1}}}, then the two calls still count as one call-path. 
     29===  function_sum === 
     30The domain of the query is a function. The sum calculated from the functions complexity metrics that characterizes the complexity of the function. It can be calculated using various metrics together. We can define metrics that are necessary to calculate the metrics constituting the sum (with enumeration in the {{{referl_metrics}}} module). 
     31   ===  max_depth_of_calling === 
     32The domain of the query is a module or a function. The length of function call-chains, namely the chain with the maximum depth. The depth of calling in the following example is 3. 
     33{{{ 
     34... 
     35f([A|B], Acc) -> 
     36   Acc0 = exec(A, Acc), 
     37   f(B, Acc0); 
     38f([], Acc0)-> 
     39    Acc0. 
     40 
     41exec(A, Acc)-> 
     42   io:format("~w",[A]), 
     43   A + Acc. 
     44... 
     45}}} 
     46===  max_depth_of_cases ===  
     47The domain of the query is a module or a function. Gives the maximum of case control structures embedded in {{{case}}} of a concrete function (how deeply are the case control structures embedded). In case of a module it measures the same regarding all the functions in the module. Measuring does not break in {{{case}}} of {{{case}}} expressions, namely when the {{{case}}} is not embedded into a {{{case}}} structure. However, the following embedding does not increase the sum. 
     48{{{ 
     49... 
     50A = case B of 
     51        1 -> 2; 
     52        2 -> ok 
     53    end 
     54... 
     55}}} 
     56===  max_depth_of_structs === 
     57The domain of the query is a module or a function. Gives the maximum of structures embedded in function (how deeply are the {{{block}}}, {{{case}}}, {{{fun}}}, {{{if}}}, {{{receive}}}, {{{try}}} control structures embedded). In case of a module it measures the same regarding all the functions in the module. 
     58===  number_of_funclauses === 
     59The domain of the query is a module or a function. Gives the number of a functions clauses. Counts all distinct branches, but does not add the functions having the same name, but different arity, to the sum. The number of funclauses in the following example is 2. 
     60{{{ 
     61... 
     62f(Fun, [H|Tail])-> 
     63    Fun(H), 
     64    f(Tail); 
     65 
     66f(_, [])-> 
     67    ok. 
     68 
     69f(A, B)-> 
     70    A + B. 
     71... 
     72}}} 
     73===  branches_of_recursion === 
     74The domain of the query is a module or a function. Gives the number of a certain function's branches, how many times a function calls itself, and not the number of clauses it has besides definition. The branches of recursion in the following example is 2. 
     75{{{ 
     76quicksort([H|T]) -> 
     77    {Smaller_Ones,Larger_Ones} = split(H,T,{[],[]}), 
     78    lists:append( quicksort(Smaller_Ones), 
     79                  [H | quicksort(Larger_Ones)] 
     80                ); 
     81quicksort([]) -> []. 
     82 
     83split(Pivot, [H|T], {Acc_S, Acc_L}) -> 
     84    if Pivot > H -> New_Acc = { [H|Acc_S] , Acc_L }; 
     85       true      -> New_Acc = { Acc_S , [H|Acc_L] } 
     86    end, 
     87    split(Pivot,T,New_Acc); 
     88split(_,[],Acc) -> Acc. 
     89}}} 
     90===  calls_for_function === 
     91The domain of the query is a function. This metric gives the number of calls for a concrete function. It is not equivalent with the number of other functions calling the function, because all of these other functions can refer to the measured one more than once. 
     92===  calls_from_function === 
     93The domain of the query is a function. This metric gives the number of calls from a certain function, namely how many times does a function refer to another one (the result includes recursive calls as well). 
     94===  number_of_funexpr === 
     95The domain of the query is a module or a function. Gives the number of function expressions in a module. It does not measure the call of function expressions, only their initiation. In the next example the number of the funexpr is 1. 
     96{{{ 
     97... 
     98F = fun(A) -> A + 1 end, 
     99F(1), 
     100F2 = fun a/1, 
     101... 
     102}}} 
     103===  number_of_messpass === 
     104The domain of the query is a module or a function. In case of functions it measures the number of code snippets implementing messages from a function, while in case of modules it measures the total number of messages in all of the modules functions. 
     105===  fun_return_points === 
     106The domain of the query is a module or a function. The metric gives the number of the functions possible return points (or the functions of the given module). 
     107===  average_size === 
     108The domain of the query is a module or a function. The average value of the given complexity metrics (e.g. Average {{{branches of recursion} calculated from the functions of the given module). 
     109===  max_length_of_line === 
     110The domain of the query is a module or a function. It gives the length of the longest line of the given module or function. 
     111===  average_length_of_line === 
     112The domain of the query is a module or a function. It gives the average length of the lines within the given module or function. 
     113===  no_space_after_comma === 
     114The domain of the query is a module or a function.  It gives the number of cases when there are not any whitespaces after a comma or a semicolon in the given module's or function's text. 
     115===  is_tail_recursive === 
     116The domain of the query is a function. It returns with 1, if the given function is tail recursive; with 0, if it is recursive, but not tail recursive; and -1 if it is not a recursive function (direct and indirect recursions are also examined). If we use this metric from the semanctic query language, the result is converted to {{{tail_rec}}}, {{{non_tail_rec}}} or {{{non_rec}}} atom. 
     117===  mcCabe === 
     118!McCabe cyclomatic complexity metric. Available for modules and functions. We define it based on the control flow graph of the functions with the number of different execution paths of a function, namely the number of different outputs of the function. 
     119===  otp_used === 
     120Gives the number of OTP callback modules used in modules.  
     121 
     122== Aggregations, filters on query results == 
     123We can extend our queries with filters. A filter can be formatting and aggregating function or the definition of the structure of the result. 
     124 
     125The possible aggregation filters are listed below: 
     126* {{{max}}}: maximum on the result list 
     127* {{{tolist}}}: default return value of the query 
     128* {{{totext}}}: string format of the result 
     129* {{{fmaxname}}}: maximum with the name of the node 
     130* {{{avg}}}: average on the result list 
     131* {{{min}}}: minimum of the result list 
     132* {{{sum}}}: sum of the result list 
     133 
     134== Examples == 
     135 ===   Simple query  ===   
     136With the following query we count the number of functions of the 
     137modules given in the list. 
     138 
     139{{{ 
     140show number_of_fun for module ('a','b') 
     141}}} 
     142 
     143where 
     144* {{{number_of_fun}}} number of fun a function giving the number of functions 
     145* {{{module}}} module the type of node in the query, 
     146* {{{('a','b')}}} contains the names of modules in which we calculate the metrics. In case the type of the node was defined as function the list must contain the following elements: The name of the module, in which the function was defined, the name of the function and its arity. In this case the list can have more than one element. The next list {{{{'test','f',1}}}} defines a function which is defined in the {{{test}}} module. Its name is {{{f}}}, and its arity is {{{1}}}. 
     147 
     148 ===   Advanced query  ===   
     149In the next example we would like to define the number of recursive calls of two functions defined in the {{{a}}} module, the number of branches on which the particular function calls itself, and we sum up the two results with the help of the {{{sum}}} aggregating function. 
     150 
     151{{{ 
     152show branches_of_recursion for function ({'a','f',1},{'a','g',0}) sum 
     153 }}} 
     154 
     155At the end of queries we can place filters which filter the results that are received at the output, or which are aggregating functions which change the result of the query. 
     156 
     157 
     158== Using metric queries from different interfaces == 
     159 
     160TODO: links