PageRenderTime 26ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/co/compiler/dox/__init.lua

http://github.com/libcoral/coral
Lua | 178 lines | 176 code | 1 blank | 1 comment | 2 complexity | 99435c4d3725deb0e571956f76013a2a MD5 | raw file
  1. local wordSubstitutions = {
  2. ["Type"] = "%Type",
  3. ["Interface"] = "%Interface",
  4. ["Component"] = "%Component",
  5. ["Service"] = "%Service",
  6. }
  7. local function wordFilter( word )
  8. -- escape @annotation.names so they're not interpretted as Doxygen commands
  9. if word:sub( 1, 1 ) == '@' then
  10. return '\\' .. word
  11. end
  12. return wordSubstitutions[word]
  13. end
  14. local coICppBlock = co.Type "co.ICppBlock"
  15. local coIDocumentation = co.Type "co.IDocumentation"
  16. local function getDoc( t, memberName )
  17. local doc = assert( t[coIDocumentation] )
  18. if memberName then
  19. return doc:getDocFor( memberName )
  20. else
  21. return doc.value
  22. end
  23. end
  24. local function addDoc( writer, t, memberName )
  25. local text = getDoc( t, memberName )
  26. if text == "" then
  27. writer( "//! Not documented.\n" )
  28. else
  29. -- filter the text, escaping common words that could be turned into links
  30. text = text:gsub( "(%p?[%w]+)", wordFilter )
  31. -- generate a \brief with the following criteria: if the first line contains a dot,
  32. -- the brief is up to the last dot in the first line. Otherwise, the brief is up to
  33. -- the first dot in the text.
  34. local line = text:match( "([^\n]+\n?)" )
  35. local brief = line:match( "(.+%.)" )
  36. if not brief then
  37. brief = text:match( "^(.-%.)%s" ) or text
  38. end
  39. local details = text:sub( #brief + 1 )
  40. writer( "/*!\n\t\\brief ", brief )
  41. if details ~= "" then
  42. writer( "\n\n\t", details )
  43. end
  44. writer( "\n */\n" )
  45. end
  46. end
  47. local write = {}
  48. function write.TK_ENUM( writer, t )
  49. writer( "enum ", t.name, "\n{\n" )
  50. for i, id in ipairs( t.identifiers ) do
  51. addDoc( writer, t, id )
  52. writer( "\t", id, ",\n" )
  53. end
  54. writer( "};\n" )
  55. end
  56. function write.TK_EXCEPTION( writer, t )
  57. writer( "exception ", t.name, " : co::Exception {};\n" )
  58. end
  59. function write.TK_STRUCT( writer, t )
  60. writer( "struct ", t.name, "\n{\n//! \\name Fields\n//@{\n" )
  61. for i, a in ipairs( t.fields ) do
  62. addDoc( writer, t, a.name )
  63. writer( "\t", a.type.docName, " ", a.name, ";\n" )
  64. end
  65. writer( "//@}\n};\n" )
  66. end
  67. local function writeFieldsAndMethods( writer, t )
  68. writer( "//! \\name Fields\n//@{\n" )
  69. for i, a in ipairs( t.fields ) do
  70. addDoc( writer, t, a.name )
  71. writer( "\t", a.isReadOnly and "readonly " or "", a.type.docName, " ", a.name, ";\n" )
  72. end
  73. writer( "//@}\n//! \\name Methods\n//@{\n" )
  74. for i, m in ipairs( t.methods ) do
  75. addDoc( writer, t, m.name )
  76. local ret = m.returnType
  77. writer( "\t", ret and ret.docName or "void", " ", m.name, "(" )
  78. if #m.parameters > 0 then
  79. writer( " " )
  80. for i, p in ipairs( m.parameters ) do
  81. if i > 1 then writer ", " end
  82. writer( p.isIn and "in" or "", p.isOut and "out" or "", " ", p.type.docName, " ", p.name )
  83. end
  84. writer( " " )
  85. end
  86. writer( ")" )
  87. if #m.exceptions > 0 then
  88. writer( "\n\t\t\tthrows " )
  89. for i, e in ipairs( m.exceptions ) do
  90. if i > 1 then writer ", " end
  91. writer( e.docName )
  92. end
  93. end
  94. writer( ";\n" )
  95. end
  96. writer( "//@}\n" )
  97. end
  98. function write.TK_NATIVECLASS( writer, t )
  99. writer( "value class ", t.name, "\n{\n" )
  100. writeFieldsAndMethods( writer, t )
  101. writer( "};\n" )
  102. end
  103. function write.TK_INTERFACE( writer, t )
  104. writer( "interface class ", t.name )
  105. if t.baseType then
  106. writer( " : ", t.baseType.docName )
  107. end
  108. writer( "\n{\n" )
  109. writeFieldsAndMethods( writer, t )
  110. local cppBlock = t[coICppBlock]
  111. if cppBlock then
  112. writer( "\n//! \\name Methods only available in C++\n//@{\n", cppBlock.value, "\n//@}\n" )
  113. end
  114. writer( "};\n" )
  115. end
  116. function write.TK_COMPONENT( writer, t )
  117. writer( "ref class ", t.name, " : co::IObject\n{\n" )
  118. writer( "\t//! \\name Facets\n\t//@{\n\n" )
  119. for i, itf in ipairs( t.facets ) do
  120. addDoc( writer, t, itf.name )
  121. writer( "\t", itf.type.docName, " ", itf.name, ";\n" )
  122. end
  123. writer( "\n\t//@}\n\t//! \\name Receptacles\n\t//@{\n\n" )
  124. for i, itf in ipairs( t.receptacles ) do
  125. addDoc( writer, t, itf.name )
  126. writer( "\t", itf.type.docName, " ", itf.name, ";\n" )
  127. end
  128. writer( "\n\t//@}\n};\n" )
  129. end
  130. local typeGroupName = {
  131. TK_ENUM = "enums",
  132. TK_EXCEPTION = "exceptions",
  133. TK_STRUCT = "structs",
  134. TK_NATIVECLASS = "nativeclasses",
  135. TK_INTERFACE = "interfaces",
  136. TK_COMPONENT = "components",
  137. }
  138. local function template( writer, c, t )
  139. writer( [[
  140. /*!
  141. \file
  142. <b>[]], typeGroupName[t.kind], [[]</b> ]], getDoc( t ), '\n', [[
  143. */
  144. ]] )
  145. c.utils.openNamespaces( writer, t.namespace.fullName )
  146. writer( "\n" )
  147. addDoc( writer, t )
  148. writer( [[/*!
  149. \ingroup coral_]], typeGroupName[t.kind], "\n", [[
  150. \nosubgrouping
  151. */
  152. ]] )
  153. assert( write[t.kind] )( writer, t )
  154. writer( "\n" )
  155. c.utils.closeNamespaces( writer, t.namespace.fullName )
  156. end
  157. return template