--------------------------------------------------------------------------------
--  Copyright (c) 2011-2012 Sierra Wireless.
--  All rights reserved. This program and the accompanying materials
--  are made available under the terms of the Eclipse Public License v1.0
--  which accompanies this distribution, and is available at
--  http://www.eclipse.org/legal/epl-v10.html
-- 
--  Contributors:
--      Simon BERNARD <sbernard@sierrawireless.com>
--          - initial API and implementation and initial documentation
--------------------------------------------------------------------------------
-{ extension ('match', ...) }

local Q = require 'metalua.treequery'

local internalmodel = require 'models.internalmodel'
local apimodel = require 'models.apimodel'
local apimodelbuilder = require 'models.apimodelbuilder'

local M = {}

-- Analyzes an AST and returns two tables
-- * `locals`, which associates `Id{ } nodes which create a local variable
--   to a list of the `Id{ } occurrence nodes of that variable;
-- * `globals` which associates variable names to occurrences of
--   global variables having that name.
function bindings(ast)
  local locals, globals = { }, { }
  local function f(id, ...)
    local name = id[1]
    if Q.is_binder(id, ...) then
      local binder = ... -- parent is the binder
      locals[binder] = locals[binder] or { }
      locals[binder][name]={ }
    else
      local _, binder = Q.get_binder(id, ...)
      if binder then -- this is a local
        table.insert(locals[binder][name], id)  
     else
        local g = globals[name]
        if g then table.insert(g, id) else globals[name]={id} end
      end
    end
  end
  Q(ast) :filter('Id') :foreach(f)
  return locals, globals
end

-- --------------------------------------

-- ----------------------------------------------------------
-- return the comment linked before to this node
-- ----------------------------------------------------------
local function getlinkedcommentbefore(node)
  local function _getlinkedcomment(node,line)
    if node and node.lineinfo and node.lineinfo.first.line == line then
      -- get the last comment before (the nearest of code)
      local comments = node.lineinfo.first.comments
      local comment = comments and  comments[#comments]
      if comment  and comment.lineinfo.last.line == line-1 then
        -- ignore the comment if there are code before on the same line
        if node.lineinfo.first.facing and (node.lineinfo.first.facing.line ~= comment.lineinfo.first.line) then
          return comment
        end
      else
        return _getlinkedcomment(node.parent,line)
      end
    end
    return nil  
  end
  
  if node.lineinfo and node.lineinfo.first.line then
    return _getlinkedcomment(node,node.lineinfo.first.line)
  else
    return nil
  end
end

-- ----------------------------------------------------------
-- return the comment linked after to this node
-- ----------------------------------------------------------
local function getlinkedcommentafter(node)
  local function _getlinkedcomment(node,line)
    if node and node.lineinfo and node.lineinfo.last.line == line then
      -- get the first comment after (the nearest of code)
      local comments = node.lineinfo.last.comments
      local comment = comments and  comments[1] 
      if comment  and comment.lineinfo.first.line == line then
        return comment
      else
        return _getlinkedcomment(node.parent,line)
      end
    end
    return nil  
  end
  
  if node.lineinfo and node.lineinfo.last.line then
    return _getlinkedcomment(node,node.lineinfo.last.line)
  else
    return nil
  end
end

-- ----------------------------------------------------------
-- return true if this node is a block for the internal representation
-- ----------------------------------------------------------
local supported_b = {
  Function = true,
  Do       = true,
  While    = true,
  Fornum   = true,
  Forin    = true,
  Repeat   = true,
}
local function supportedblock(node, parent)
  return supported_b[ node.tag ] or
    (parent and parent.tag == "If" and node.tag == nil)
end

-- ----------------------------------------------------------
-- create a block from the  metalua node
-- ----------------------------------------------------------
local function createblock(block, parent)
  local _block =  internalmodel._block()
  match block with
    | `Function{param, body}
    | `Do{...}
    | `Fornum {...}
    | `Forin {identifiers, exprs, body}
    | `Repeat {body, expr} ->
        _block.sourcerange.min = block.lineinfo.first.offset
        _block.sourcerange.max = block.lineinfo.last.offset
    | `While {expr, body} ->
        _block.sourcerange.min = body.lineinfo.first.facing.offset
        _block.sourcerange.max = body.lineinfo.last.facing.offset
    | _ ->
        if parent and parent.tag == "If" and block.tag == nil then
          _block.sourcerange.min = block.lineinfo.first.facing.offset
          _block.sourcerange.max = block.lineinfo.last.facing.offset
        end
  end
  return _block
end

-- ----------------------------------------------------------
-- return true if this node is a expression in the internal representation
-- ----------------------------------------------------------
local supported_e = {
  Index  = true,
  Id     = true,
  Call   = true,
  Invoke = true
}
local function supportedexpr(node)
  return supported_e[ node.tag ]
end

local idto_block = {} -- cache from metalua id to internal model block 
local idto_identifier = {} -- cache from  metalua id to internal model indentifier
local expreto_expression = {} -- cache from  metalua expression to internal model expression

-- ----------------------------------------------------------
-- create an expression from a metalua node
-- ----------------------------------------------------------
local function createexpr(expr,_block)
  local _expr = nil 
  
  match expr with
    | `Id { name } ->
        -- we store the block which hold this node 
        -- to be able to define  
        idto_block[expr]= _block
  
        -- if expr has not line info, it means expr has no representation in the code
        -- so we don't need it.
        if not expr.lineinfo then  return nil end
        
        -- create identifier
        local _identifier = internalmodel._identifier()
        idto_identifier[expr]= _identifier
        _expr =  _identifier
    | `Index { innerexpr, rightpart } ->
        if not expr.lineinfo then  return nil end
        -- create index
        local _expression = createexpr(innerexpr,_block)
        if _expression then
          if rightpart and rightpart.tag=='String' then
            _expr =  internalmodel._index(_expression,rightpart[1])
          else
            _expr = internalmodel._index(_expression,nil)
          end
        end
    | `Call{innerexpr, ...} ->
        if not expr.lineinfo then  return nil end
        -- create call 
        local _expression = createexpr(innerexpr,_block)
        if _expression then _expr =  internalmodel._call(_expression) end
    | `Invoke{innerexpr,`String{functionname},...} ->
        if not expr.lineinfo then  return nil end
        -- create invoke
        local _expression = createexpr(innerexpr,_block)
        if _expression then _expr = internalmodel._invoke(functionname,_expression) end
    | _ ->
  end
  
  if _expr then
    _expr.sourcerange.min = expr.lineinfo.first.offset 
    _expr.sourcerange.max = expr.lineinfo.last.offset

    expreto_expression[expr] = _expr
  end
  
  return _expr
end

-- ----------------------------------------------------------
-- create block and expression node
-- ----------------------------------------------------------
local function createtreestructure(ast)
  -- create internal content 
  local _internalcontent = internalmodel._internalcontent()

  -- create root block
  local _block = internalmodel._block()
  local _blocks = { _block }
  _block.sourcerange.min = ast.lineinfo.first.facing.offset
  -- TODO remove the math.max when we support partial AST
  _block.sourcerange.max = math.max(ast.lineinfo.last.facing.offset, 10000)

  _internalcontent.content = _block
  
  -- visitor function (down)
  local function down (node,parent)
    if supportedblock(node,parent) then
      -- create the block
      local _block = createblock(node,parent)
      -- add it to parent block
      table.insert(_blocks[#_blocks].content, _block) 
      -- enqueue the last block to know the "current" block
      table.insert(_blocks,_block)
    elseif supportedexpr(node) then
      -- we handle expression only if it was not already do
      if not  expreto_expression[node] then
        -- create expr
        local _expression = createexpr(node,_blocks[#_blocks])
        -- add it to parent block
        if _expression then
          table.insert(_blocks[#_blocks].content, _expression)
        end  
      end
    end
  end
  
  -- visitor function (up)
  local function up (node, parent)
    if supportedblock(node,parent) then
      -- dequeue the last block to know the "current" block
      table.remove(_blocks,#_blocks)
    end    
  end
 
  -- visit ast and build internal model  
  Q(ast):foreach(down,up)
      
  return _internalcontent
end

local getitem

-- ----------------------------------------------------------
-- create the type from the node and position
-- ----------------------------------------------------------
local function createtype(node,position,comment2apiobj,file)
  -- create module type ref
  match node with
    | `Call{ `Id "require", `String {modulename}} ->
        return apimodel._moduletyperef(modulename,position)
    | `Function {params, body} ->
        -- create the functiontypedef from code
        local _functiontypedef = apimodel._functiontypedef()
        for _, p in ipairs(params) do
          -- create parameters
          local paramname
          if p.tag=="Dots" then
            paramname = "..."
          else
            paramname = p[1]
          end
          local _param = apimodel._parameter(paramname)
          table.insert(_functiontypedef.params,_param)
        end
        _functiontypedef.name = "___" -- no name for inline type
        
        return apimodel._inlinetyperef(_functiontypedef)
    | `String {value} ->
        local typeref = apimodel._primitivetyperef("string")
        return typeref
    | `Number {value} ->
        local typeref = apimodel._primitivetyperef("number")
        return typeref
    | `True | `False ->
        local typeref = apimodel._primitivetyperef("boolean")
         return typeref
    | `Table {...} ->
        -- create recordtypedef  from code
        local _recordtypedef = apimodel._recordtypedef("table")
        -- for each element of the table
        for i=1,select("#", ...) do
              local pair = select(i, ...)
              -- if this is a pair we create a new item in the type
          if pair.tag == "Pair" then
            -- create an item
            local _item = getitem(pair,nil, comment2apiobj,file)
            if _item then
              _recordtypedef:addfield(_item)
            end
          end
        end        
        return apimodel._inlinetyperef(_recordtypedef)
    | _ ->
  end
  -- if node is an expression supported
  local supportedexpr = expreto_expression[node]
  if supportedexpr then
    -- create expression type ref
    return apimodel._exprtyperef(supportedexpr,position)
  end
  
end

local function completeapidoctype(apidoctype,itemname,init,file,comment2apiobj)
  if not apidoctype.name then
    apidoctype.name = itemname
    file:mergetype(apidoctype)
  end
  
  -- create type from code
  local typeref = createtype(init,1,comment2apiobj,file)
  if typeref and typeref.tag == "inlinetyperef" 
    and typeref.def.tag == "recordtypedef" then
    
    -- set the name
    typeref.def.name = apidoctype.name
    
    -- merge the type with priority to documentation except for source range
    file:mergetype(typeref.def,false,true)
  end
end

local function completeapidocitem (apidocitem, itemname, init, file, binder, comment2apiobj)
  -- manage the case item has no name
  if not apidocitem.name then 
    apidocitem.name = itemname
    
    -- if item has no name this means it could not be attach to a parent
    if apidocitem.scope then 
      apimodelbuilder.additemtoparent(file,apidocitem,apidocitem.scope,apidocitem.sourcerange.min,apidocitem.sourcerange.max)
      apidocitem.scope = nil
    end
  end        

  -- for function try to merge definition
  local apitype = apidocitem:resolvetype(file)
  if apitype and apitype.tag == "functiontypedef" then
    local codetype = createtype(init,1,comment2apiobj,file)
    if codetype and codetype.tag =="inlinetyperef" then
      codetype.def.name = apitype.name
      file:mergetype(codetype.def)
    end
  end
  
  -- manage the case item has no type
  if not apidocitem.type then
    -- extract typing from comment
    local type, desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file)
    
    if type then
      apidocitem.type = type
    else
      -- if not found extracttype from code 
      apidocitem.type = createtype(init,1,comment2apiobj,file)
    end
    
    local apitype = apidocitem:resolvetype(file)
    if apitype and apitype.tag == "functiontypedef" and apidocitem.metadata then
      apitype.metadata = apidocitem.metadata
    end
  end
end

-- ----------------------------------------------------------
-- create or get the item finding in the binder with the given itemname
-- return also the ast node corresponding to this item  
-- ----------------------------------------------------------
getitem = function (binder, itemname, comment2apiobj, file)
   
   -- local function to create item 
  local function createitem(itemname, astnode, itemtype, description)
    local _item = apimodel._item(itemname)
    if description then _item.description = description end
    _item.type = itemtype
    if astnode and astnode.lineinfo then 
      _item.sourcerange.min = astnode.lineinfo.first.offset 
      _item.sourcerange.max = astnode.lineinfo.last.offset 
    end
    return _item, astnode
  end
  
  -- try to match binder with known patter of item declaration    
  match binder with
    | `Pair  {string, init}
    | `Set   { {`Index { right , string}}, {init,...}} if string and string.tag =="String" ->
      -- Pair and set is for searching field from type ..
      -- if the itemname is given this mean we search for a local or a global not a field type.
      if not itemname then
        local itemname = string[1]
      
        -- check for luadoc typing
        local commentbefore = getlinkedcommentbefore(binder)
        local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment
        if apiobj then
          if apiobj.tag=="item" then
            if not apiobj.name or apiobj.name == itemname then
              -- use code to complete api information if it's necessary
              completeapidocitem(apiobj, itemname, init,file,binder,comment2apiobj)
              -- for item use code source range rather than doc source range
              if string and string.lineinfo then
                apiobj.sourcerange.min =  string.lineinfo.first.offset
                apiobj.sourcerange.max = string.lineinfo.last.offset
              end              
              return apiobj, string          
            end
          elseif apiobj.tag=="recordtypedef" then
            -- use code to complete api information if it's necessary
            completeapidoctype(apiobj, itemname, init,file,comment2apiobj)
            return createitem(itemname, string, apimodel._internaltyperef(apiobj.name), nil)
          end
          
          -- if the apiobj could not be associated to the current obj, 
          -- we do not use the documentation neither
          commentbefore = nil
        end
                
        -- else we use code to extract the type and description
        -- check for "local" typing
          local type, desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file)
          local desc = desc or (commentbefore and commentbefore[1])
        if type then
          return createitem(itemname, string, type, desc ) 
        else
          -- if no "local typing" extract type from code
          return createitem(itemname, string, createtype(init,1,comment2apiobj,file), desc)
        end
      end
  | `Set {ids, inits} 
  | `Local {ids, inits} ->
      -- if this is a single local var declaration
      -- we check if there are a comment block linked and try to extract the type
      if #ids == 1 then
        local currentid, currentinit = ids[1],inits[1]
        -- ignore non Ids node
        if currentid.tag ~= 'Id' or currentid[1] ~= itemname then return nil end

          -- check for luadoc typing
        local commentbefore = getlinkedcommentbefore(binder)
        local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment
        if apiobj then
          if apiobj.tag=="item" then
            -- use code to complete api information if it's necessary
            if not apiobj.name or apiobj.name == itemname then 
              completeapidocitem(apiobj, itemname, currentinit,file,binder,comment2apiobj)
              -- if this is a global var or if is has no parent
              -- we do not create a new item
              if not apiobj.parent or apiobj.parent == file  then
                -- for item use code source range rather than doc source range
                if currentid and currentid.lineinfo then
                  apiobj.sourcerange.min = currentid.lineinfo.first.offset
                  apiobj.sourcerange.max = currentid.lineinfo.last.offset
                end  
                return apiobj, currentid
              else
                return createitem(itemname, currentid, apiobj.type, nil)
              end          
            end
          elseif apiobj.tag=="recordtypedef" then
            -- use code to complete api information if it's necessary
            completeapidoctype(apiobj, itemname, currentinit,file,comment2apiobj)
            return createitem(itemname, currentid, apimodel._internaltyperef(apiobj.name), nil)
          end

          -- if the apiobj could not be associated to the current obj, 
          -- we do not use the documentation neither
          commentbefore = nil
        end
                
        -- else we use code to extract the type and description
        -- check for "local" typing
        local type,desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file)
          desc = desc or (commentbefore and commentbefore[1])
        if type then 
          return createitem(itemname, currentid, type, desc) 
        else
          -- if no "local typing" extract type from code
          return createitem(itemname, currentid, createtype(currentinit,1,comment2apiobj,file), desc)
        end
      end
      -- else we use code to extract the type      
      local init,returnposition = nil,1
      for i,id in ipairs(ids) do
        -- calculate the current return position
        if init and (init.tag == "Call" or init.tag == "Invoke") then
          -- if previous init was a call or an invoke
          -- we increment the returnposition
          returnposition= returnposition+1
        else
          -- if init is not a function call
          -- we change the init used to determine the type 
          init = inits[i]                  
        end
        
        -- get the name of the current id
        local idname = id[1] 
        
        -- if this is the good id
        if itemname == idname then
          -- create type from init node and return position
          return createitem (itemname, id, createtype(init,returnposition,comment2apiobj,file),nil)
        end
      end
  | `Function {params, body} ->
      for i,id in ipairs(params) do
        -- get the name of the current id
        local idname = id[1]
        -- if this is the good id
        if itemname == idname then
          -- extract param's type  from luadocumentation
          local obj = comment2apiobj[getlinkedcommentbefore(binder)]
          if obj and obj.tag=="item" then
            local typedef = obj:resolvetype(file)
            if typedef and typedef.tag =="functiontypedef" then 
              for j, param in ipairs(typedef.params) do
                if i==j then
                  if i ==1 and itemname == "self"  and param.type == nil 
                    and obj.parent and obj.parent.tag == "recordtypedef" and obj.parent.name then
                    param.type = apimodel._internaltyperef(obj.parent.name)
                  end
                  -- TODO perhaps we must clone the typeref
                  return createitem(itemname,id, param.type,param.description)
                end
              end
            end
          end              
          return createitem(itemname,id)
        end
      end
  | `Forin {ids, expr, body} ->
      for i,id in ipairs(ids) do
        -- get the name of the current id
        local idname = id[1]
        -- if this is the good id
        if itemname == idname then
          -- return data : we can not guess the type for now
          return createitem(itemname,id)
        end
      end  
  | `Fornum {id, ...} ->
      -- get the name of the current id
      local idname = id[1]
      -- if this is the good id
      if itemname == idname then
        -- return data : we can not guess the type for now
        return createitem(itemname,id)
      end          
  | `Localrec {{id}, {func}} ->
      -- get the name of the current id
      local idname = id[1]
      -- if this is the good id
      if itemname == idname then
        -- check for luadoc typing
        local commentbefore = getlinkedcommentbefore(binder)
        local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment
        if apiobj then
          if apiobj.tag=="item" then
            if not apiobj.name or apiobj.name == itemname then
              -- use code to complete api information if it's necessary
              completeapidocitem(apiobj, itemname, func,file,binder,comment2apiobj)
              return createitem(itemname,id,apiobj.type,nil)
            end
          end
      
          -- if the apiobj could not be associated to the current obj, 
          -- we do not use the documentation neither
          commentbefore = nil
        end
          
        -- else we use code to extract the type and description
        -- check for "local" typing
        local type,desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file)
          desc = desc or (commentbefore and commentbefore[1])
          if type then 
          return createitem(itemname, id, type, desc) 
        else
          -- if no "local typing" extract type from code
          return createitem(itemname, id, createtype(func,1,comment2apiobj,file), desc)
        end
      end            
  | _ ->
  end
end

-- ----------------------------------------------------------
-- Search from Id node to Set node to find field of type.
--
-- Lua code : table.field1.field2 = 12
-- looks like that in metalua :  
--      `Set{ 
--            `Index { `Index { `Id "table", `String "field1" },
--                     `String "field2"},
--            `Number "12"} 
-- ----------------------------------------------------------
local function searchtypefield(node,_currentitem,comment2apiobj,file)
  
  -- we are just interested : 
  -- by item which is field of recordtypedef
  -- by ast node which are Index
  if _currentitem then
    local type = _currentitem:resolvetype(file)
    if type and type.tag == "recordtypedef" then
      if node and node.tag == "Index" then
        local rightpart = node[2]
        local _newcurrentitem = type.fields[rightpart[1]]
        
        if _newcurrentitem then
          -- if this index represent a known field of the type we continue to search 
          searchtypefield (node.parent,_newcurrentitem,comment2apiobj,file)
        else
          -- if not, this is perhaps a new field, but
          -- to be a new field this index must be include in a Set
          if node.parent and node.parent.tag =="Set" then
            -- in this case we create the new item ans add it to the type
            local set = node.parent
            local item, string = getitem(set,nil, comment2apiobj,file)
            -- add this item to the type, only if it has no parent and if this type does not contain already this field
            if item and not item.parent and string and not type.fields[string[1]]  then
              type:addfield(item)
            end                    
          end
        end        
      end
    end  
  end
end 

-- ----------------------------------------------------------
-- create local vars, global vars and linked it with theirs occurences
-- ----------------------------------------------------------
local function createvardefinitions(_internalcontent,ast,file,comment2apiobj)
  -- use bindings to get locals and globals definition
  local locals, globals = bindings( ast )
  
  -- create locals var
  for binder, namesAndOccurrences in pairs(locals) do
    for name, occurrences in pairs(namesAndOccurrences) do
      -- get item, id 
      local _item, id = getitem(binder, name,comment2apiobj,file)
      if id then
        -- add definition as occurence
        -- we consider the identifier in the binder as an occurence
        local _identifierdef = idto_identifier[id]
        if _identifierdef then
          table.insert(_item.occurrences, _identifierdef)
          _identifierdef.definition = _item
        end
          
        -- add occurences
        for _,occurrence in ipairs(occurrences) do
          searchtypefield(occurrence.parent, _item,comment2apiobj,file)
          local _identifier = idto_identifier[occurrence]
          if _identifier then
            table.insert(_item.occurrences, _identifier)
            _identifier.definition = _item 
          end 
        end
      
        -- add item to block
        local _block = idto_block[id]
        table.insert(_block.localvars,{item=_item,scope = {min=0,max=0}})
      end  
    end
  end
  
  -- create globals var
  for name, occurrences in pairs( globals ) do
    
    -- get or create definition
    local _item = file.globalvars[name]
    local binder = occurrences[1].parent
    if not _item then
      -- global declaration is only if the first occurence in left part of a 'Set'
      if binder and binder.tag == "Set" then
         _item = getitem(binder, name,comment2apiobj,file)
      end
      
      -- if we find and item this is a global var declaration
      if _item then
        file:addglobalvar(_item)
      else
        -- else it is an unknown global var
        _item = apimodel._item(name)
        local _firstoccurrence = idto_identifier[occurrences[1]]
        if _firstoccurrence then
          _item.sourcerange.min = _firstoccurrence.sourcerange.min
          _item.sourcerange.max = _firstoccurrence.sourcerange.max
        end
        table.insert(_internalcontent.unknownglobalvars,_item)
      end
    else
      -- if the global var definition already exists, we just try to it 
      if binder then
        match binder with
          | `Set {ids, inits} ->
              -- manage case only if there are 1 element in the Set
              if #ids == 1 then
                local currentid, currentinit = ids[1],inits[1]
                -- ignore non Ids node and bad name
                if currentid.tag == 'Id' and currentid[1] == name then
                  completeapidocitem(_item, name, currentinit,file,binder,comment2apiobj)
                  
                  if currentid and currentid.lineinfo then
                    _item.sourcerange.min = currentid.lineinfo.first.offset
                    _item.sourcerange.max = currentid.lineinfo.last.offset
                  end
                end
              end
          | _ ->
        end
      end
    end

    -- add occurences
    for _,occurence in ipairs(occurrences) do
      local _identifier = idto_identifier[occurence]
      searchtypefield(occurence.parent, _item,comment2apiobj,file)
      if _identifier then
        table.insert(_item.occurrences, _identifier)
        _identifier.definition = _item 
      end 
    end
  end
end

-- ----------------------------------------------------------
-- add parent to all ast node
-- ----------------------------------------------------------
local function addparents(ast)
  -- visitor function (down)
  local function down (node,parent)
    node.parent = parent
  end

  -- visit ast and build internal model  
  Q(ast):foreach(down,up)
end

-- ----------------------------------------------------------
-- try to detect a module declaration from code
-- ----------------------------------------------------------
local function searchmodule(ast,file,comment2apiobj,modulename)
  -- if the last statement is a return
  if ast then
    local laststatement = ast[#ast]
    if laststatement and laststatement.tag == "Return" then
      -- and if the first expression returned is an identifier.
      local firstexpr = laststatement[1]
      if firstexpr and firstexpr.tag == "Id" then
        -- get identifier in internal model
        local _identifier = idto_identifier [firstexpr]
        -- the definition should be an inline type
        if      _identifier 
            and _identifier.definition 
          and _identifier.definition.type 
          and _identifier.definition.type.tag == "inlinetyperef"
          and _identifier.definition.type.def.tag == "recordtypedef" then
          
          --set modulename if needed
          if not file.name then file.name = modulename end
          
          -- create or merge type
          local _type = _identifier.definition.type.def
          _type.name = modulename
          
          -- if file (module) has no documentation add item documentation to it
          -- else add it to the type.
          if not file.description or file.description == "" then
            file.description = _identifier.definition.description
          else
            _type.description = _identifier.definition.description
          end
          _identifier.definition.description = ""
          if not file.shortdescription or file.shortdescription == ""  then
            file.shortdescription = _identifier.definition.shortdescription
          else
            _type.shortdescription = _identifier.definition.shortdescription
          end
          _identifier.definition.shortdescription = ""
          
          _type.sourcerange.min = _identifier.definition.sourcerange.min
          _type.sourcerange.max = _identifier.definition.sourcerange.max
          
          -- merge the type with priority to documentation except for source range
          file:mergetype(_type,false,true)
          
          -- create return if needed
          if not file.returns[1] then
            file.returns[1] = apimodel._return()
            file.returns[1].types = { apimodel._internaltyperef(modulename) }
          end
            
          -- change the type of the identifier
          _identifier.definition.type = apimodel._internaltyperef(modulename)
        end
      end  
    end
  end
end

-- ----------------------------------------------------------
-- create the internalcontent from an ast metalua
-- ---------------------------------------------------------- 
function M.createinternalcontent (ast,file,comment2apiobj,modulename)
  -- init cache
  idto_block = {}  
  idto_identifier = {} 
  expreto_expression = {}
  comment2apiobj = comment2apiobj or {}
  file = file or apimodel._file()
    
  -- execute code safely to be sure to clean cache correctly
  local internalcontent  
  local ok, errmsg = pcall(function ()   
    -- add parent to all node 
    addparents(ast)
    
    -- create block and expression node
    internalcontent = createtreestructure(ast)
    
    -- create Local vars, global vars and linked occurences (Items)
    createvardefinitions(internalcontent,ast,file,comment2apiobj)
    
    -- try to dectect module information from code 
    local moduletyperef = file:moduletyperef()
    if moduletyperef and moduletyperef.tag == "internaltyperef" then
      modulename  = moduletyperef.typename or modulename
    end
    if modulename then
      searchmodule(ast,file,comment2apiobj,modulename)
    end
  end)
  
  -- clean cache
  idto_block = {}  
  idto_identifier = {} 
  expreto_expression = {}
  
  -- if not ok raise an error
  if not ok then error (errmsg) end 
  
  return internalcontent
end

return M 
