--------------------------------------------------------------------------------
--  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 {identifier, min, max, body}
    | `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 
