Changes between Version 2 and Version 3 of SemanticQuery


Ignore:
Timestamp:
Feb 20, 2012, 8:24:53 AM (13 years ago)
Author:
manualwiki
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • SemanticQuery

    v2 v3  
    143143TODO: table - statistics 
    144144 
    145  
    146  
     145== Examples == 
     146 
     147=== Basic queries === 
     148As you can read in the introduction, in this language we build difficult queries from lot of very simple queries. Here are some examples for simple ones: 
     149 
     150{{{ 
     151@fun.refs 
     152}}} 
     153Returns a list of expressions which call the pointed function. 
     154 
     155{{{ 
     156@file.funs.calls 
     157}}} 
     158Returns all function calls from current module group by the module's own functions. 
     159 
     160{{{ 
     161@file.funs[arity==3] 
     162}}} 
     163Returns all functions which have 3 arguments. 
     164 
     165=== Advanced queries === 
     166Let's see some useful queries: 
     167 
     168{{{ 
     169@file.funs.vars[name=="Expl"] 
     170}}} 
     171Returns all functions which have a variable named "Expl". It useful when we want to know which functions use variables with same name. 
     172 
     173{{{ 
     174mods[name=="io"].funs[name==format].refs 
     175}}} 
     176Returns all io:format calls, this query is very useful when you have finished your software, and you want to find all debug messages. 
     177 
     178{{{ 
     179@expr.origin 
     180}}} 
     181For 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]. 
     182 
     183{{{ 
     184@fun.refs.origin 
     185}}} 
     186Returns information about the function gets its return value from where and how its calculated. 
     187 
     188=== Checking coding convensions === 
     189 
     190In !RefactorErl, [wiki:MetricQuery 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. 
     191 
     192Usually 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. 
     193 
     194''' Rule1. A module should not contain more then 400 lines.''' 
     195 
     196When 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: 
     197{{{ 
     198modules[line_of_code > 400] 
     199}}} 
     200In the result we will find our too long modules. 
     201 
     202''' Rule2. A function should not contain more then 15 to 20 lines.''' 
     203 
     204When 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: 
     205{{{ 
     206modules.funs[line_of_code > 20] 
     207}}} 
     208 
     209''' Rule3. Use at most two level of nesting, do not write deeply nested code.''' It is achieved by dividing the code into shorter functions. 
     210 
     211With 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. 
     212{{{ 
     213@file.funs[max_depth_of_cases > 2] 
     214}}} 
     215 
     216If 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. 
     217{{{ 
     218@file.max_depth_of_cases 
     219}}} 
     220 
     221At least, let's filter modules containing functions with too deeply nested cases. 
     222{{{ 
     223mods[max_depth_of_cases > 2] 
     224}}} 
     225 
     226''' Rule4. Use no more than 80 characters on a line.''' 
     227 
     228We can filter all of the functions, which contains lines with more than 80 characters with the following query: 
     229{{{ 
     230mods.funs[max_length_of_line > 80] 
     231}}} 
     232 
     233''' Rule5. Use space after commas.''' 
     234 
     235We 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. 
     236 
     237Filter functions containing at least one case when whitespace misses after 
     238a comma: 
     239{{{ 
     240mods.funs[no_space_after_comma > 0] 
     241}}} 
     242 
     243''' Rule6. Every recursive function should tail recursive.''' 
     244 
     245Tail 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: 
     246{{{ 
     247mods.funs[is_tail_recursive == non_tail_rec] 
     248}}} 
     249 
     250 
     251