blob: dda4f9d4a62e01648d9fe558732da7ed8008d79b [file] [log] [blame]
--------------------------------------------------------------------------------
-- 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
--------------------------------------------------------------------------------
local M = {}
--------------------------------------------------------------------------------
-- API MODEL
--------------------------------------------------------------------------------
function M._file()
local file = {
-- FIELDS
tag = "file",
name = nil, -- string
shortdescription = "", -- string
description = "", -- string
types = {}, -- map from typename to type
globalvars = {}, -- map from varname to item
returns = {}, -- list of return
-- FUNCTIONS
addtype = function (self,type)
self.types[type.name] = type
type.parent = self
end,
mergetype = function (self,newtype,erase,erasesourcerangefield)
local currenttype = self.types[newtype.name]
if currenttype then
-- merge recordtypedef
if currenttype.tag =="recordtypedef" and newtype.tag == "recordtypedef" then
-- merge fields
for fieldname ,field in pairs( newtype.fields) do
local currentfield = currenttype.fields[fieldname]
if erase or not currentfield then
currenttype:addfield(field)
elseif erasesourcerangefield then
if field.sourcerange.min and field.sourcerange.max then
currentfield.sourcerange.min = field.sourcerange.min
currentfield.sourcerange.max = field.sourcerange.max
end
end
end
-- merge descriptions and source ranges
if erase then
if newtype.description or newtype.description == "" then currenttype.description = newtype.description end
if newtype.shortdescription or newtype.shortdescription == "" then currenttype.shortdescription = newtype.shortdescription end
if newtype.sourcerange.min and newtype.sourcerange.max then
currenttype.sourcerange.min = newtype.sourcerange.min
currenttype.sourcerange.max = newtype.sourcerange.max
end
end
-- merge functiontypedef
elseif currenttype.tag == "functiontypedef" and newtype.tag == "functiontypedef" then
-- merge params
for i, param1 in ipairs(newtype.params) do
local missing = true
for j, param2 in ipairs(currenttype.params) do
if param1.name == param2.name then
missing = false
break
end
end
if missing then
table.insert(currenttype.params,param1)
end
end
-- merge descriptions and source ranges
if erase then
if newtype.description or newtype.description == "" then currenttype.description = newtype.description end
if newtype.shortdescription or newtype.shortdescription == "" then currenttype.shortdescription = newtype.shortdescription end
if newtype.sourcerange.min and newtype.sourcerange.max then
currenttype.sourcerange.min = newtype.sourcerange.min
currenttype.sourcerange.max = newtype.sourcerange.max
end
end
end
else
self:addtype(newtype)
end
end,
addglobalvar = function (self,item)
self.globalvars[item.name] = item
item.parent = self
end,
moduletyperef = function (self)
if self and self.returns[1] and self.returns[1].types[1] then
local typeref = self.returns[1].types[1]
return typeref
end
end
}
return file
end
function M._recordtypedef(name)
local recordtype = {
-- FIELDS
tag = "recordtypedef",
name = name, -- string (mandatory)
shortdescription = "", -- string
description = "", -- string
fields = {}, -- map from fieldname to field
sourcerange = {min=0,max=0},
supertype = nil, -- supertype of the type def (inheritance), should be a recordtypedef ref
defaultkeytyperef = nil, -- the default typeref of key
defaultvaluetyperef = nil, -- the default typeref of value
structurekind = nil, -- kind of structure of the type: could be nil, "map" or "list"
structuredescription = nil, -- description of the structure
call = nil, -- typeref to the function use as __call on the type.
-- FUNCTIONS
addfield = function (self,field)
self.fields[field.name] = field
field.parent = self
end,
getcalldef = function( self)
if self.call and self.call.tag == 'internaltyperef' then
if self.parent and self.parent.tag == 'file' then
local file = self.parent
return file.types[self.call.typename]
end
end
end
}
return recordtype
end
function M._functiontypedef(name)
return {
tag = "functiontypedef",
name = name, -- string (mandatory)
shortdescription = "", -- string
description = "", -- string
params = {}, -- list of parameter
returns = {} -- list of return
}
end
function M._parameter(name)
return {
tag = "parameter",
name = name, -- string (mandatory)
description = "", -- string
type = nil -- typeref (external or internal or primitive typeref)
}
end
function M._item(name)
return {
-- FIELDS
tag = "item",
name = name, -- string (mandatory)
shortdescription = "", -- string
description = "", -- string
type = nil, -- typeref (external or internal or primitive typeref)
occurrences = {}, -- list of identifier (see internalmodel)
sourcerange = {min=0, max=0},
-- This is A TRICK
-- This value is ALWAYS nil, except for internal purposes (short references).
external = nil,
-- FUNCTIONS
addoccurence = function (self,occ)
table.insert(self.occurrences,occ)
occ.definition = self
end,
resolvetype = function (self,file)
if self and self.type then
if self.type.tag =="internaltyperef" then
-- if file is not given try to retrieve it.
if not file then
if self.parent and self.parent.tag == 'recordtypedef' then
file = self.parent.parent
elseif self.parent.tag == 'file' then
file = self.parent
end
end
if file then return file.types[self.type.typename] end
elseif self.type.tag =="inlinetyperef" then
return self.type.def
end
end
end
}
end
function M._externaltypref(modulename, typename)
return {
tag = "externaltyperef",
modulename = modulename, -- string
typename = typename -- string
}
end
function M._internaltyperef(typename)
return {
tag = "internaltyperef",
typename = typename -- string
}
end
function M._primitivetyperef(typename)
return {
tag = "primitivetyperef",
typename = typename -- string
}
end
function M._moduletyperef(modulename,returnposition)
return {
tag = "moduletyperef",
modulename = modulename, -- string
returnposition = returnposition -- number
}
end
function M._exprtyperef(expression,returnposition)
return {
tag = "exprtyperef",
expression = expression, -- expression (see internal model)
returnposition = returnposition -- number
}
end
function M._inlinetyperef(definition)
return {
tag = "inlinetyperef",
def = definition, -- expression (see internal model)
}
end
function M._return(description)
return {
tag = "return",
description = description or "", -- string
types = {} -- list of typref (external or internal or primitive typeref)
}
end
return M