Codebase list lua-ldoc / 4bc48da
modules returning a single function are supported, see tests/styles/func.lua. Parameters may have subfields, see tests/styles/subparams.lua steve donovan 11 years ago
8 changed file(s) with 208 addition(s) and 89 deletion(s). Raw diff Collapse all Expand all
492492 return ret
493493 end
494494
495 local build_arg_list, split_iden -- forward declaration
496
495497
496498 function Item:finish()
497499 local tags = self.tags
537539 self.modifiers.field = self.modifiers.param
538540 end
539541 end
540 local names, comments = List(), List()
542 local param_names, comments = List(), List()
541543 if params then
542544 for line in params:iter() do
543 local name, comment = line :match('%s*([%w_%.:]+)(.*)')
545 local name, comment = line:match('%s*([%w_%.:]+)(.*)')
544546 if not name then
545547 self:error("bad param name format '"..line.."'. Are you missing a parameter name?")
546548 end
547 names:append(name)
549 param_names:append(name)
548550 comments:append(comment)
549551 end
550552 end
551553 self.modifiers['return'] = self.modifiers['return'] or List()
552554 self.modifiers[field] = self.modifiers[field] or List()
553 -- not all arguments may be commented: we use the formal arguments
554 -- if available as the authoritative list, and warn if there's an inconsistency.
555 if self.formal_args then
556 local fargs = self.formal_args
557 if not self.ret and fargs.return_comment then
558 local retc = fargs.return_comment
559 local type,rest = retc:match '([^:]+):(.*)'
560 if type then
561 self.modifiers['return']:append{type=type}
562 retc = rest
563 end
564 self.ret = List{retc}
565 end
566 if #fargs ~= 0 then
567 local pnames, pcomments = names, comments
568 names, comments = List(),List()
555 -- we use the formal arguments (if available) as the authoritative list.
556 -- If there are both params and formal args, then they must match;
557 -- (A formal argument of ... may match any number of params at the end, however.)
558 -- If there are formal args and no params, we see if the args have any suitable comments.
559 -- Params may have subfields.
560 local fargs, formal = self.formal_args
561 if fargs then
562 if #param_names == 0 then
563 --docs may be embedded in argument comments; in either case, use formal arg names
564 formal = List()
565 if fargs.return_comment then
566 local retc = self:parse_argument_comment(fargs.return_comment,'return')
567 self.ret = List{retc}
568 end
569 for i, name in ipairs(fargs) do
570 formal:append(name)
571 comments:append(self:parse_argument_comment(fargs.comments[name],self.parameter))
572 end
573 elseif #fargs > 0 then
569574 local varargs = fargs[#fargs] == '...'
570 for i,name in ipairs(fargs) do
571 if params then -- explicit set of param tags
572 if pnames[i] ~= name and not varargs then
573 if pnames[i] then
574 self:warning("param and formal argument name mismatch: "..quote(name).." "..quote(pnames[i]))
575 else
576 self:warning("undocumented formal argument: "..quote(name))
575 if varargs then table.remove(fargs) end
576 local k = 0
577 for _,pname in ipairs(param_names) do
578 local _,field = split_iden(pname)
579 if not field then
580 k = k + 1
581 if k > #fargs then
582 if not varargs then
583 self:warning("extra param with no formal argument: "..quote(pname))
577584 end
578 elseif varargs then
579 name = pnames[i]
585 elseif pname ~= fargs[k] then
586 self:warning("param and formal argument name mismatch: "..quote(pname).." "..quote(fargs[k]))
580587 end
581588 end
582 names:append(name)
583 local comment = pcomments[i]
584 if not comment then
585 -- ldoc allows comments in the formal arg list to be used, if they aren't specified with @param
586 -- Further, these comments may start with a type followed by a colon, and are then equivalent
587 -- to a @tparam
588 comment = fargs.comments[name]
589 if comment then
590 comment = comment:gsub('^%-+%s*','')
591 local type,rest = comment:match '([^:]+):(.*)'
592 if type then
593 self.modifiers[field]:append {type = type}
594 comment = rest
595 end
596 end
597 end
598 comments:append (comment or '')
599 end
600 -- A formal argument of ... may match any number of params, however.
601 if #pnames > #fargs then
602 for i = #fargs+1,#pnames do
603 if not varargs then
604 self:warning("extra param with no formal argument: "..quote(pnames[i]))
605 else
606 names:append(pnames[i])
607 comments:append(pcomments[i] or '')
589 end
590 if k < #fargs then
591 for i = k+1,#fargs do
592 if fargs[i] ~= '...' then
593 self:warning("undocumented formal argument: "..quote(fargs[i]))
608594 end
609595 end
610596 end
614600 -- the comments are associated with each parameter by
615601 -- adding name-value pairs to the params list (this is
616602 -- also done for any associated modifiers)
617 self.params = names
603 -- (At this point we patch up any subparameter references)
618604 local pmods = self.modifiers[field]
619 for i,name in ipairs(self.params) do
620 self.params[name] = comments[i]
605 local params, fields = List()
606 local original_names = formal and formal or param_names
607 local names = List()
608 self.subparams = {}
609 for i,name in ipairs(original_names) do
610 local pname,field = split_iden(name)
611 if field then
612 if not fields then
613 fields = List()
614 self.subparams[pname] = fields
615 end
616 fields:append(name)
617 else
618 names:append(name)
619 params:append(name)
620 fields = nil
621 end
622
623 params[name] = comments[i]
621624 if pmods then
622625 pmods[name] = pmods[i]
623626 end
624627 end
625
626 -- build up the string representation of the argument list,
627 -- using any opt and optchain modifiers if present.
628 -- For instance, '(a [, b])' if b is marked as optional
629 -- with @param[opt] b
630 local buffer, npending = { }, 0
631 local function acc(x) table.insert(buffer, x) end
632 for i = 1, #names do
633 local m = pmods and pmods[i]
634 if m then
635 if not m.optchain then
636 acc ((']'):rep(npending))
637 npending=0
638 end
639 if m.opt or m.optchain then acc(' ['); npending=npending+1 end
640 end
641 if i>1 then acc (', ') end
642 acc(names[i])
643 end
644 acc ((']'):rep(npending))
645 self.args = '('..table.concat(buffer)..')'
646 end
628 self.params = params
629 self.args = build_arg_list (names,pmods)
630 end
631 end
632
633 -- ldoc allows comments in the formal arg list to be used, if they aren't specified with @param
634 -- Further, these comments may start with a type followed by a colon, and are then equivalent
635 -- to a @tparam
636 function Item:parse_argument_comment (comment,field)
637 if comment then
638 comment = comment:gsub('^%-+%s*','')
639 local type,rest = comment:match '([^:]+):(.*)'
640 if type then
641 self.modifiers[field]:append {type = type}
642 comment = rest
643 end
644 end
645 return comment or ''
646 end
647
648 function split_iden (name)
649 if name == '...' then return name end
650 local pname,field = name:match('(.-)%.(.+)')
651 if not pname then
652 return name
653 else
654 return pname,field
655 end
656 end
657
658 function build_arg_list (names,pmods)
659 -- build up the string representation of the argument list,
660 -- using any opt and optchain modifiers if present.
661 -- For instance, '(a [, b])' if b is marked as optional
662 -- with @param[opt] b
663 local buffer, npending = { }, 0
664 local function acc(x) table.insert(buffer, x) end
665 for i = 1, #names do
666 local m = pmods and pmods[i]
667 if m then
668 if not m.optchain then
669 acc ((']'):rep(npending))
670 npending=0
671 end
672 if m.opt or m.optchain then acc(' ['); npending=npending+1 end
673 end
674 if i>1 then acc (', ') end
675 acc(names[i])
676 end
677 acc ((']'):rep(npending))
678 return '('..table.concat(buffer)..')'
647679 end
648680
649681 function Item:type_of_param(p)
656688 function Item:type_of_ret(idx)
657689 local rparam = self.modifiers['return'][idx]
658690 return rparam and rparam.type or ''
691 end
692
693 function Item:subparam(p)
694 if self.subparams[p] then
695 return self.subparams[p],p
696 else
697 return {p},nil
698 end
699 end
700
701 function Item:display_name_of(p)
702 local pname,field = split_iden(p)
703 if field then
704 return field
705 else
706 return pname
707 end
659708 end
660709
661710
673722 end
674723
675724 Module.warning, Module.error = Item.warning, Item.error
725
726
727 -------- Resolving References -----------------
676728
677729 function Module:hunt_for_reference (packmod, modules)
678730 local mod_ref
156156 # if show_parms and item.params and #item.params > 0 then
157157 <h3>$(module.kinds:type_of(item).subnames):</h3>
158158 <ul>
159 # for p in iter(item.params) do
160 <li><span class="parameter">$(p)</span>
161 # local tp = ldoc.typename(item:type_of_param(p))
162 # if tp ~= '' then
163 <span class="types">$(tp)</span>
164 # end
165 $(M(item.params[p],item))</li>
159 # for parm in iter(item.params) do
160 # local param,sublist = item:subparam(parm)
161 # if sublist then
162 <li><span class="parameter">$(sublist)</span>$(M(item.params[sublist],item))
163 <ul>
164 # end
165 # for p in iter(param) do
166 # local name,tp = item:display_name_of(p), ldoc.typename(item:type_of_param(p))
167 <li><span class="parameter">$(name)</span>
168 # if tp ~= '' then
169 <span class="types">$(tp)</span>
170 # end
171 $(M(item.params[p],item))</li>
172 # end
173 # if sublist then
174 </li></ul>
175 # end
166176 # end -- for
167177 </ul>
168178 # end -- if params
127127 end))
128128 end
129129
130 function ldoc.is_list (t)
131 return type(t) == 'table' and t.append
132 end
133
130134 function ldoc.typename (tp)
131135 if not tp or tp == '' then return '' end
132136 local optional
169173 ldoc.output = args.output
170174 ldoc.ipairs = ipairs
171175 ldoc.pairs = pairs
176 ldoc.print = print
172177
173178 -- in single mode there is one module and the 'index' is the
174179 -- documentation for that module.
252252 end
253253 if item_follows or comment:find '@' or comment:find ': ' then
254254 tags = extract_tags(comment,args)
255 -- explicitly named @module (which is recommended)
255256 if doc.project_level(tags.class) then
256257 module_found = tags.name
258 -- might be a module returning a single function!
259 if tags.param or tags['return'] then
260 local parms, ret, summ = tags.param, tags['return'],tags.summary
261 tags.param = nil
262 tags['return'] = nil
263 tags.summary = nil
264 add_module(tags,tags.name,false)
265 tags = {
266 summary = summ,
267 name = 'returns...',
268 class = 'function',
269 ['return'] = ret,
270 param = parms
271 }
272 end
257273 end
258274 doc.expand_annotation_item(tags,current_item)
259275 -- if the item has an explicit name or defined meaning
77 -- @copyright InfoReich 2013
88
99 --- a function with typed args.
10 -- Note the the standard tparam aliases
10 -- Note the the standard tparam aliases, and how the 'opt' and 'optchain'
11 -- modifiers may also be used. If the Lua function has varargs, then
12 -- you may document an indefinite number of extra arguments!
1113 -- @string name person's name
1214 -- @int age
15 -- @string[opt] calender optional calendar
16 -- @int[optchain] offset optional offset
1317 -- @treturn string
14 function one (name,age)
18 function one (name,age,...)
1519 end
1620
1721
0 ------------
1 -- Get length of string.
2 -- A (silly) module which returns a single function
3 --
4 -- @module func
5 -- @string some text
6 -- @param opts multibyte encoding options
7 -- @string opts.charset encoding used
8 -- @bool opts.strict be very pedantic
9 -- @bool verbose tell the world about everything
10 -- @return its length
11 return function(s,opts,verbose)
12 return #s
13 end
14
0 ------------
1 -- Parameters may have named subfields, if they are tables.
2 --
3 -- @module subparams
4 module(...)
5
6 -------
7 -- A function with subfield arguments.
8 -- @param s string
9 -- @param opts multibyte encoding options
10 -- @param opts.charset string
11 -- @param opts.strict bool
12 -- @param verbose bool
13 -- @return its length
14 function with_options (s,opts,verbose)
15 end
16
00 ------------
1 -- Classic Lua 5.1 module,
1 -- Classic Lua 5.1 module.
22 -- Description here
33 ----
44