Changes between Initial Version and Version 1 of SemanticQuery/Examples


Ignore:
Timestamp:
Mar 14, 2012, 1:28:02 PM (13 years ago)
Author:
manualwiki
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • SemanticQuery/Examples

    v1 v1  
     1= Query Examples = 
     2 
     3== Basic queries == 
     4In this language we can build difficult queries from lot of very simple queries. Here are some examples for simple ones: 
     5 
     6{{{ 
     7@fun.refs 
     8}}} 
     9Returns a list of expressions which call the pointed function. 
     10 
     11{{{ 
     12@file.funs.calls 
     13}}} 
     14Returns all function calls from current module group by the module's own functions. 
     15 
     16{{{ 
     17@file.funs[arity==3] 
     18}}} 
     19Returns all functions which have 3 arguments. 
     20 
     21== Advanced queries == 
     22Let's see some useful queries: 
     23 
     24{{{ 
     25@file.funs.vars[name=="Expl"] 
     26}}} 
     27Returns all functions which have a variable named "Expl". It useful when we want to know which functions use variables with same name. 
     28 
     29{{{ 
     30mods[name=="io"].funs[name==format].refs 
     31}}} 
     32Returns all io:format calls, this query is very useful when you have finished your software, and you want to find all debug messages. 
     33 
     34{{{ 
     35@expr.origin 
     36}}} 
     37For example we stand in a variable, and run this query, we get information about the variable gets its value from where. This functionality uses [wiki:DataFlow data-flow analysis]. 
     38 
     39{{{ 
     40@fun.refs.origin 
     41}}} 
     42Returns information about the function gets its return value from where and how its calculated. 
     43 
     44== Checking coding convensions == 
     45 
     46In !RefactorErl, [MetricQuery#Definedmetrics metrics] can be applied to modules or to functions. Modules are equivalent to {{{file}}} entities in the semantic query language, and functions are equivalent to {{{function}}} entities. We can say that a metric is a kind of property belongs to a {{{file}}} or {{{function}}} entity, so we can simply add the proper metrics to the properties of entities. 
     47 
     48Usually we have some coding conventions applied to our modules or functions. With our extended semantic query language we can check these conventions, and filter improper modules or functions. Hereinafter we present some design rules and some metrics to check these rules. 
     49 
     50''' Rule1. A module should not contain more then 400 lines.''' 
     51 
     52When we would like to filter modules containing more than 400 effective lines of code, we have to load our modules to !RefactorErl system, and enter the following query: 
     53{{{ 
     54mods[line_of_code > 400] 
     55}}} 
     56In the result we will find our too long modules. 
     57 
     58''' Rule2. A function should not contain more then 15 to 20 lines.''' 
     59 
     60When we would like to check, which functions do not fulfil this convention in our modules loaded into the !RefactorErl database, we use the following query: 
     61{{{ 
     62mods.funs[line_of_code > 20] 
     63}}} 
     64 
     65''' Rule3. Use at most two level of nesting, do not write deeply nested code.''' It is achieved by dividing the code into shorter functions. 
     66 
     67With one of our metrics we can count the nesting level of case expressions, so we can filter functions with more than two maximum depth of cases. In this example, we would like to get the result just from our actual module. 
     68{{{ 
     69@file.funs[max_depth_of_cases > 2] 
     70}}} 
     71 
     72If we just would like to know, whether all of the functions fulfil this convention or not, we can simply query the maximum nesting level of cases in the whole module. If this value is more than two, there is at least one function containing deeply nested cases. 
     73{{{ 
     74@file.max_depth_of_cases 
     75}}} 
     76 
     77At least, let's filter modules containing functions with too deeply nested cases. 
     78{{{ 
     79mods[max_depth_of_cases > 2] 
     80}}} 
     81 
     82''' Rule4. Use no more than 80 characters on a line.''' 
     83 
     84We can filter all of the functions, which contains lines with more than 80 characters with the following query: 
     85{{{ 
     86mods.funs[max_length_of_line > 80] 
     87}}} 
     88 
     89''' Rule5. Use space after commas.''' 
     90 
     91We have a metric which returns with the number of cases when we do not fulfil this convention. When a modul or a function breaks this rule, the result of the metric will be more, then 0. 
     92 
     93Filter functions containing at least one case when whitespace misses after 
     94a comma: 
     95{{{ 
     96mods.funs[no_space_after_comma > 0] 
     97}}} 
     98 
     99''' Rule6. Every recursive function should tail recursive.''' 
     100 
     101Tail recursion means that we have no recursive call (either direct or indirect) in our function, just in the last expression. Filter functions that recursive, but not tail recursive: 
     102{{{ 
     103mods.funs[is_tail_recursive == non_tail_rec] 
     104}}}