Skip to content

Understanding kuniri's output

Rodrigo Siqueira de Melo edited this page Feb 10, 2016 · 7 revisions

Kuniri has its own output pattern applied to xml. Here, we explain the basic format, and introduce all kinds of information which kuniri can extract the from source code.

Files included in the program

A common resource for many programming languages are the ability to include other files in your program. kuniri is able to extract this kind of information, and put it in a data structure called "externRequirementData". See below a basic example:

See this ruby code:

...
require_relative 'attribute_state'
require 'libxml'
...

It will be translated to:

<externRequirementData name="attribute_state"/>
<externRequirementData name="libxml"/>

Remember, kuniri was designed to be a generic parser. It means, the xml output will be the same for any kind of language which kuniri can handle. For example:

...
#include <attribute_state.h>
#include <libxml.h>
...

translated to:

<externRequirementData name="attribute_state"/>
<externRequirementData name="libxml"/>

As you can see, the output will be the same.

Summary:

Node name Parameters Description
externRequirementData name Included file name

Modules

Kuniri, can extract modules. See the example below:

...
module 'Languages'
...

Translated to:

<moduleData name="Languages"/>

Summary:

Node name Parameters Description
moduleData name Module's name

Comments

kuniri is able to extract comments, associated with classes, methods, constructors, attributes, and global functions. See the example below:

...
# This class is able to...
class Xpto
end
...

Translated to:

<classData name="Xpto" visibility="public">
    <commentData text="This class is able to..."/>
</classData>

Python example:

...
# This class is able to...
class Xpto
    """
    This class is able to...
    """
...

translated to:

<classData name="Xpto" visibility="public">
    <commentData text="This class is able to..."/>
</classData>

Obs: At this moment, we only have ruby parser. However, as you can see in the xml output above the final result must be the same for anylanguage.

Summary:

Node name Parameters Description
commentData text Text comment

Classes

Classes it is another common feature provided for many languages. Consequently, kuniri is able to extract this kind of information too. See the example below:

...
class Xpto
end
...

translated to:

<classData name="Xpto" visibility="public">
</classData>

Inside classData we can have another kind of tags. Basically, it can has:

  • Inheritance
  • Attributes
  • Constructors
  • Methods

Summary:

Node name Parameters Description
classData name Class name

Attributes

Attributes are always found inside classes, and it keeps the information about class attributes. See:

...
class Xpto
  attr_read :path
end
...

translated to:

...
<classData name="Xpto" visibility="public">
  <attributeData name="path" visibility="public"/>
</classData>
...

Summary:

Node name Parameters Description
attributeData name Attribute name
visibility Attribute visibility

Constructors

A constructor can be found inside classes, the general behaviour is really similar to method and functions. The only difference is the way as the name is assigned. See:

...
class Xpto
  def initialize
  end
end
...

Translated to:

...
<classData name="Xpto" visibility="public">
  <constructorData name="initialize" visibility="public">
  </constructorData>
</classData>
...

You can find inside constructor this kind of data:

  • Comments
  • Parameters
  • Conditionals
  • Repetitions

See the example below with a constructor with more elements:

...
  def initialize(pLine)
    commentLine = []
      if pLine =~ /^=begin(.*?)/
        @flagMultipleLineComment = true
      elsif pLine =~ /^=end/
        @flagMultipleLineComment = false
      end
      unless @flagMultipleLineComment == true || pLine =~ /#(.*)/
        return pLine.split(/;/)
      end
      commentLine << pLine
  end
...

Translated to:

...
<constructorData name="initialize" visibility="public">
  <commentData text="Puts every statement in a single line
            @param pLine Line of the file to be analysed."/>
  <parameterData name="pLine"/>
  <if expression="pLine =~ /^=begin(.*?)/" level="0"/>
  <elsif expression="pLine =~ /^=end/" level="0"/>
  <unless expression="@flagMultipleLineComment == true || pLine =~ /#(.*)/" level="0"/>
</constructorData>
...

Summary:

Node name Parameters Description
constructorData name Constructor name
visibility Constructor visibility

Methods

Essentially a method follows the same behaviour of constructors in the final output, for more details read carefully the section about constructors. See the simple code below to understand how the method are translated:

...
  def handle_semicolon(pLine)
    commentLine = []
      if pLine =~ /^=begin(.*?)/
        @flagMultipleLineComment = true
      elsif pLine =~ /^=end/
        @flagMultipleLineComment = false
      end
      unless @flagMultipleLineComment == true || pLine =~ /#(.*)/
        return pLine.split(/;/)
      end
      commentLine << pLine
  end
...

Translated to:

...
<methodData name="handle_semicolon" visibility="public">
  <commentData text="Puts every statement in a single line
            @param pLine Line of the file to be analysed."/>
  <parameterData name="pLine"/>
  <if expression="pLine =~ /^=begin(.*?)/" level="0"/>
  <elsif expression="pLine =~ /^=end/" level="0"/>
  <unless expression="@flagMultipleLineComment == true || pLine =~ /#(.*)/" level="0"/>
</methodData>
...

Summary:

Node name Parameters Description
methodData name Method name
visibility Method visibility

Functions

Function follows the same behaviour of constructors in the final output, for more details read carefully the section about constructors.

Summary:

Node name Parameters Description
functionData name Function name
visibility By default, always 'global'

Conditionals and Repetition

Conditionals and repetitions, working together or alone. It is really common to find a combination of repetitions and loops in a block of code, and Kuniri handle this kind of situation with a level concept.

The idea behind "level concept" applied to loops and conditionals, it enumerates the nested elements from 0 to the last nested level. See the example below:

def mixCoditionalAndRepetition

  for level0 in 8..19 do
    if level1 > 10
      x = 20
      while level2 do
        k = 222
        unless level3
          until level4 < 20 do
            puts "this is the end"
          end
        end
      end
    end
  end

end

It will be translated to:

<functionData name="mixCoditionalAndRepetition" visibility="public">
  <for expression="level0 in 8..19" level="0"/>
  <if expression="level1 &gt; 10" level="1"/>
  <while expression="level2" level="2"/>
  <unless expression="level3" level="3"/>
  <until expression="level4 &lt; 20" level="4"/>
</functionData>

Notice the first level in a conditional or repetition is 0. If we have nested elements, the level is increased.