├── README.md ├── annotate-0.2-1.rockspec ├── doc ├── .exclude └── readme.txt ├── src ├── annotate.lua └── annotate │ ├── check.lua │ ├── help.lua │ └── test.lua └── tests ├── annotate.check.test.lua ├── annotate.help.test.lua └── annotate.test.test.lua /README.md: -------------------------------------------------------------------------------- 1 | lua-annotate 2 | ============ 3 | 4 | A decorator for docstrings and type checking 5 | 6 | See [here](http://siffiejoe.github.io/lua-annotate/). 7 | 8 | -------------------------------------------------------------------------------- /annotate-0.2-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "annotate" 2 | version = "0.2-1" 3 | source = { 4 | url = "${SRCURL}", 5 | } 6 | description = { 7 | summary = "A decorator for docstrings and type checking", 8 | detailed = [[ 9 | This Lua module provides a decorator that allows to associate Lua 10 | values with docstrings. Plugins for typechecking using function 11 | signatures, interactive help, and simple unit testing are included. 12 | ]], 13 | homepage = "${HPURL}", 14 | license = "MIT" 15 | } 16 | dependencies = { 17 | "lua >= 5.1, < 5.3", 18 | "lpeg >= 0.6" 19 | } 20 | build = { 21 | type = "builtin", 22 | modules = { 23 | [ "annotate" ] = "src/annotate.lua", 24 | [ "annotate.check" ] = "src/annotate/check.lua", 25 | [ "annotate.help" ] = "src/annotate/help.lua", 26 | [ "annotate.test" ] = "src/annotate/test.lua", 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /doc/.exclude: -------------------------------------------------------------------------------- 1 | # exclude code blocks containing one of following strings from syntax 2 | # highlighting: 3 | mod.obj:method 4 | TOTAL: 5 | 6 | -------------------------------------------------------------------------------- /doc/readme.txt: -------------------------------------------------------------------------------- 1 | ![annotate Logo](annotate.png) 2 | 3 | # annotate -- Annotations and Docstrings for Lua Values # 4 | 5 | ## Introduction ## 6 | 7 | There are basically two ways for documenting code in a dynamically 8 | typed programming language like Lua: you can write static 9 | documentation like external readme files or comments that can be 10 | extracted by specialized documentation tools, or you can annotate Lua 11 | values with runtime information. The first approach enables you to 12 | extract useful information without running any code, a popular tool 13 | for this is [LDoc][1]. One well-known representative of the second 14 | approach is [Python][2] with its [docstrings][3]. One advantage of 15 | this approach is that you can easily process those runtime annotations 16 | and e.g. provide interactive help, or type checking. 17 | 18 | This module uses the ideas presented [here][4] and [here][5] to 19 | provide a basis for docstring handling in Lua, and flexible argument 20 | and return value checking for Lua functions. 21 | 22 | [1]: https://github.com/stevedonovan/LDoc/ 23 | [2]: http://www.python.org/ 24 | [3]: https://en.wikipedia.org/wiki/Docstring 25 | [4]: http://lua-users.org/wiki/DecoratorsAndDocstrings 26 | [5]: http://lua-users.org/wiki/LuaTypeChecking 27 | 28 | 29 | ## Basic Usage ## 30 | 31 | To add a docstring annotation to a Lua value (like e.g. a function) 32 | you use the `annotate` base module: 33 | 34 | $ cat > test1.lua 35 | -- loading the module returns a callable table 36 | local annotate = require( "annotate" ) 37 | 38 | -- annotated function definitions consist of a call to the 39 | -- annotate function concatenated to a normal (anonymous) 40 | -- function value 41 | local func = annotate[=[ 42 | The `func` function takes a number and a string and prints them to 43 | the standard output stream. 44 | ]=] .. 45 | function( a, b ) 46 | print( a, b ) 47 | end 48 | 49 | func( 1, "hello" ) 50 | ^D 51 | 52 | The `annotate` module itself doesn't do anything with the docstrings 53 | and Lua values, but hands both to modules like e.g. the 54 | `annotate.check` module: 55 | 56 | $ cat > test2.lua 57 | local annotate = require( "annotate" ) 58 | require( "annotate.check" ) -- we ignore the return value for now 59 | 60 | local func = annotate[=[ 61 | The `func` function takes a number and a string and prints them to 62 | the standard output stream. 63 | 64 | func( a, b ) 65 | a: number 66 | b: string 67 | ]=] .. 68 | function( a, b ) 69 | print( a, b ) 70 | end 71 | 72 | func( 1, "hello" ) 73 | func( 2, true ) --> line 17 74 | ^D 75 | 76 | When run, the above example will output: 77 | 78 | $ lua test2.lua 79 | 1 hello 80 | lua: func: string expected for argument no. 2 (got boolean). 81 | stack traceback: 82 | [C]: in function 'error' 83 | [compiled_arg_check]:48: in function 'argc' 84 | ../src/annotate/check.lua:842: in function 'func' 85 | test2.lua:17: in main chunk 86 | [C]: in ? 87 | 88 | 89 | ## The annotate Module ## 90 | 91 | By itself the `annotate` module does nothing except providing syntax 92 | for associating a docstring with a Lua value. It does so using a 93 | `__call` metamethod that takes a string and returns an object with a 94 | `__concat` metamethod. So the general usage looks like this: 95 | 96 | local annotate = require( "annotate" ) 97 | local annotated_v = annotate[[some string]] .. v 98 | 99 | What you put into the docstrings is your business, but I suggest 100 | [markdown][6], because it looks good as plain text, and you can 101 | convert it to many formats, e.g. using a converter like [pandoc][7]. 102 | There are also Lua libraries for converting markdown texts. 103 | 104 | [6]: http://daringfireball.net/projects/markdown/ 105 | [7]: http://johnmacfarlane.net/pandoc/ 106 | 107 | To actually do something with the annotations you need handler modules 108 | that get registered with the `annotate` module. For this the 109 | `annotate` module provides a `register` method: 110 | 111 | annotate:register( function( v, docstring ) ... end [, replace] ) 112 | 113 | There are two kinds of callback functions, those that wrap or replace 114 | the original value, and those that don't. For the former kind, the 115 | `replace` argument must evaluate to a true value. Those callbacks are 116 | called in the order of registration, and they must return the 117 | replacement value. The non-replacing kind of callback is called after 118 | all modifying callbacks are handled, but the order in which they are 119 | called is unspecified (and shouldn't matter anyway). Their return 120 | values are ignored. 121 | 122 | 123 | ## The annotate.check Module ## 124 | 125 | The `annotate.check` module registers itself with the `annotate` 126 | module when require'd (see above). For every function that gets 127 | annotated, it parses the given docstring and extracts argument and 128 | return type information from a special function signature in the 129 | docstring. It then replaces the original function with a type checking 130 | version. Various fields in the `annotate.check` module table can be 131 | used to fine-tune the type checking (see below). 132 | 133 | 134 | ### Function Signature Syntax ### 135 | 136 | The `annotate.check` module scans paragraphs (sequences of characters 137 | delimited by `\n\n`) in the docstring and takes the first that looks 138 | like a function signature as used in the [Lua reference manual][8]. 139 | A function signature starts with a name or function designator (module 140 | names + function name, delimited by `.`), followed by a parameter 141 | list in parentheses, an optional return value specification, and if 142 | necessary a mapping of parameter names to types. You can put Lua-style 143 | single line comments at all places where whitespace is allowed. 144 | 145 | [8]: http://www.lua.org/manual/5.2/manual.html#6.1 146 | 147 | 148 | * Function Designator: 149 | 150 | A function designator is either a function name (a Lua 151 | identifier), or a field (Lua identifier) in a table (also a Lua 152 | identifier), as usual separated by `.` for module functions or `:` 153 | for methods. The table itself can be a field in another module 154 | table, and so on. This is better shown by example, than explained. 155 | The following are valid function designators: 156 | 157 | * `func` 158 | * `mod.func` 159 | * `mod:func` 160 | * `mod1.mod2.func` 161 | * `mod1.mod2:func` 162 | * etc. 163 | 164 | * Parameter List: 165 | 166 | The parameter list is a sequence of names, optionally delimited by 167 | commas (`,`). Parts/or all of the parameter list can be enclosed 168 | in square brackets (`[]`) to denote optional parameters. Those 169 | optional parameter sublists can be nested as well. The last 170 | element of the parameter list can be the special vararg parameter 171 | `...`. The whole parameter list is enclosed in parentheses. The 172 | parameter names have to be mapped to type names in the parameter 173 | mapping section (see below), but for simple cases you can use the 174 | type names directly as parameter names, and omit the mapping. 175 | 176 | 177 | * Return Value Specification: 178 | 179 | If the function returns one or more values, you need one or more 180 | patterns for return value types. Each pattern is started by an 181 | arrow `=>` (you can use more than one `=`) and followed by a 182 | regular expression. Multiple patterns denote alternatives. 183 | 184 | The regular expressions are built from type names that are 185 | combined via the usual regular expression operators (listed in 186 | descending order of precedence): 187 | 188 | * a type name registered in the `types` sub-table (see below) 189 | 190 | * `(` pattern `)` 191 | 192 | for explicit grouping 193 | 194 | * pattern`*` or pattern`?` 195 | 196 | `*` means zero or more occurrences of the pattern, `?` means 197 | zero or one 198 | 199 | * pattern1 `/` pattern2 200 | 201 | an alternative, matches pattern1 _or_ pattern2 202 | 203 | * pattern1 `,` pattern2 204 | 205 | a sequence of two patterns, matches pattern1 _and then_ 206 | pattern2 207 | 208 | * Parameter Mapping: 209 | 210 | If the parameter list of the function has any parameter names in 211 | it, you need to map those names to actual types as defined in the 212 | `types` sub-table. This is done by specifying the parameter name, 213 | followed by a colon (`:`), followed by a type name or a list of 214 | alternative types delimited by `/` (no full regular expressions 215 | allowed here except for `...`). The special vararg parameter 216 | (`...`) can use full regular expressions as in the return value 217 | specifications (see above). Specifying a type for the implicit 218 | `self` parameter in methods is optional, the default is `object` 219 | which matches tables and userdata. 220 | 221 | 222 | #### Examples #### 223 | 224 | pcall( f [, arg1, ...] ) ==> boolean, any* 225 | f : function -- the function to call in protected mode 226 | arg1: any -- first argument to f 227 | ... : any* -- remaining arguments to f 228 | 229 | tonumber( any [, number] ) ==> nil/number 230 | 231 | table.concat( list [, sep [, i [, j]]] ) ==> string 232 | list: table -- an array of strings 233 | sep : string -- a separator, defaults to "" 234 | i : integer -- starting index, defaults to 1 235 | j : integer -- end index, defaults to #list 236 | 237 | table.insert( list, [pos,] value ) 238 | list : table -- an array 239 | pos : integer -- index where to insert (defaults to #list+1) 240 | value: any -- value to insert 241 | 242 | io.open( filename [, mode] ) 243 | ==> file -- on success 244 | ==> nil,string,number -- in case of error 245 | filename: string -- the name of the file 246 | mode : string -- flags similar to fopen(3) 247 | 248 | file:read( ... ) ==> (string/number/nil)* 249 | ...: (string/number)* -- format specifiers 250 | 251 | file:seek( [whence [, offset]] ) ==> number 252 | ==> nil, string 253 | self : file -- would default to `object` 254 | whence: string 255 | offset: number 256 | 257 | os.execute( [string] ) 258 | ==> boolean 259 | ==> boolean/nil, string, number 260 | 261 | mod.obj:method( [a [, b] [, c],] [d,] ... ) 262 | ==> boolean -- when successful 263 | ==> nil, string -- in case of error 264 | a: string/function -- a string or a function 265 | b: userdata -- a userdata 266 | -- don't break the paragraph! 267 | c: boolean -- a boolean flag 268 | d: number -- a number 269 | ...: ((table, string/number) / boolean)* 270 | 271 | 272 | ### Predefined Type Checking Functions ### 273 | 274 | The table `check.types` (where `check` is the result of the 275 | `require`-call) comes with some predefined type checking functions. 276 | Those predefined type checking functions only cover basic Lua 277 | data types, see below for how to add your own application specific 278 | checking functions. 279 | 280 | * `nil` 281 | 282 | Matches the nil type/value. 283 | 284 | * `boolean` 285 | 286 | Matches either `true` or `false`. 287 | 288 | * `number` 289 | 290 | Matches a Lua number. 291 | 292 | * `string` 293 | 294 | Matches a Lua string. 295 | 296 | * `table` 297 | 298 | Matches a Lua table. 299 | 300 | * `userdata` 301 | 302 | Matches a userdata (light and full). 303 | 304 | * `function` 305 | 306 | Matches a Lua function (but not a callable userdata or table). 307 | 308 | * `thread` 309 | 310 | Matches a Lua coroutine. 311 | 312 | * `any` 313 | 314 | Matches any one value (including nil). 315 | 316 | * `integer` 317 | 318 | Matches numbers without fractional part. 319 | 320 | * `object` 321 | 322 | Matches a Lua table or a userdata, but doesn't check for a 323 | metatable. 324 | 325 | * `true` 326 | 327 | Matches any Lua value except `nil` and `false` 328 | 329 | * `false` 330 | 331 | Matches only `nil` and `false`. 332 | 333 | Some optional type checkers are defined if the necessary modules and 334 | functions are available: 335 | 336 | * `file` 337 | 338 | Matches an opened file handle. Requires `io.type`. 339 | 340 | * `pattern` 341 | 342 | Matches an [LPeg][9] pattern. Requires `LPeg.type`. 343 | 344 | [9]: http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html 345 | 346 | 347 | ### Tuning the Type Checker ### 348 | 349 | Checking for basic Lua types already helps, but typically support for 350 | application specific data types is needed. To register a new type 351 | simply add the type checking function to the `types` sub-table. 352 | 353 | local annotate = require( "annotate" ) 354 | local check = require( "annotate.check" ) 355 | check.types.file = function( v ) 356 | return io.type( v ) == "file" 357 | end 358 | 359 | local func2 = annotate[=[ 360 | func2( [fh] ) 361 | fh: file -- a file handle 362 | ]=] .. 363 | function( out ) 364 | out = out or io.stdout 365 | out:write( "Hello World!\n" ) 366 | end 367 | 368 | You can disable type checking for the following function definitions 369 | by setting the `enabled` field to false. In that case the 370 | `annotate.check` module doesn't replace the original function. 371 | 372 | check.enabled = false 373 | 374 | Previously defined functions are unaffected by this change. 375 | 376 | You can selectively enable/disable type checking for arguments and 377 | return values using the `arguments` and `return_values` flags. Again, 378 | this only affects functions defined after this change. 379 | 380 | check.arguments = true 381 | check.return_values = false 382 | 383 | By default the type checking module throws an error for undefined type 384 | checkers, or if a docstring for a function does not have a function 385 | signature. You can change that by providing a custom error function: 386 | 387 | check.errorf = function( msg ) print( msg ) end -- print warning 388 | -- check.errorf = function() end -- ignore completely 389 | 390 | 391 | ## The annotate.help Module ## 392 | 393 | The `annotate.help` module registers itself with the `annotate` 394 | module when require'd to provide interactive help for all Lua values 395 | with an annotation. It can also wrap other help modules (like e.g. 396 | [ihelp][10]) to delegate help requests for values *not* having a 397 | docstring. Assuming `help` is the return value of the `require`-call: 398 | 399 | * `help( value )` 400 | 401 | Prints the annotation for the given value, or a short notice that 402 | no docstring could be found for that value. 403 | 404 | * `help:search( pattern )` or `help.search( pattern )` 405 | 406 | Prints all annotations that match the given pattern, or a short 407 | notice that no matching docstring could be found. If `highlighter` 408 | is a function value, it is used in a `string.gsub` call to replace 409 | all occurrences of the pattern with a highlighted value. 410 | 411 | * `help:wrap( func [, out] )` or `help.wrap( func [, out] )` 412 | 413 | Returns a closure that first looks for an annotation for a given 414 | value and prints it if it exists (optionally using a custom `out` 415 | function), or falls back to the supplied `func` function. 416 | 417 | * `help:lookup( value )` or `help.lookup( value )` 418 | 419 | Tries to find a docstring for the given value and returns it. 420 | Returns `nil` if no docstring can be found. 421 | 422 | * `help:iterate() or help.iterate()` 423 | 424 | Returns a for-loop iterator that iterates over all values and 425 | their docstrings. 426 | 427 | [10]: https://github.com/dlaurie/lua-ihelp/ 428 | 429 | If the argument to the `help` module (or to the `lookup` function) is 430 | a string, `annotate.help` tries to require the string (and suitable 431 | substrings) looking for a Lua value with an annotation using the 432 | string as a path. 433 | 434 | 435 | ## The annotate.test Module ## 436 | 437 | The `annotate.test` module is a simple unit testing module inspired by 438 | Python's [doctest][11]. The idea is to provide code examples in the 439 | docstrings using the syntax of the interactive Lua interpreter. The 440 | code examples can be executed and verified as working Lua code by this 441 | module. It registers itself with the `annotate` module when require'd 442 | and stores the test code it finds in the docstrings in an internal 443 | table for later execution. The tests are started by calling the result 444 | of the `require( "annotate.test" )` call. 445 | 446 | local annotate = require( "annotate" ) 447 | local test = require( "annotate.test" ) 448 | -- ... some function definitions with annotations 449 | test( 1 ) -- parameter is output verbosity (0-3, default is 1) 450 | 451 | [11]: http://en.wikipedia.org/wiki/Doctest 452 | 453 | The test output quotes the function name, if the docstring also 454 | contains a type signature (as for the `annotate.check` module, see 455 | there) *before* the test code section. Test results and statistics are 456 | written to the standard error channel. 457 | 458 | If you want to take unit testing really seriously, the test code will 459 | become way too big to be included in the docstrings. In this case you 460 | should consider using a designated unit testing module for most of the 461 | tests, and only use this module to make sure the examples in the 462 | documentation stay correct. 463 | 464 | 465 | ### Test Syntax ### 466 | 467 | The beginning of the test code section is denoted by a simple header 468 | or a markdown header (in atx-style format). 469 | 470 | * Simple Header: 471 | * One of `example`, `examples`, `test`, or `tests` at the 472 | beginning of a paragraph, optionally followed by a colon 473 | (`:`), and zero or more empty lines (containing only 474 | whitespace). 475 | * The case of `example`/`examples`/`test`/`tests` doesn't 476 | matter. 477 | 478 | * Markdown Header: 479 | * One or more `#` followed by optional whitespace, one of 480 | `example`, `examples`, `test`, or `tests` (again case doesn't 481 | matter), and zero or more empty lines (containing only 482 | whitespace). 483 | * The markdown header line can optionally be "closed" by 484 | whitespace and any number of `#`. 485 | 486 | After the header, any line indented 4 spaces is either a line 487 | containing Lua code, or a line containing output of the Lua code 488 | before. Lua code starts with "`> `" or "`>> `". Each line of Lua code 489 | is compiled as a separate chunk if possible (like in the interactive 490 | interpreter). All tests for a single annotation share a custom 491 | environment containing a modified `print` function, and the global 492 | variable `F` that refers to the value the annotation is for (useful 493 | for testing local functions), as well as `__index` access to the 494 | default global environment. 495 | 496 | The output lines are matched against values returned from the Lua 497 | chunks (via `return` or `=`), against error messages, and against the 498 | output of the `print` function (but only if used directly in the test 499 | code, the output of Lua's standard `print` function cannot be 500 | matched). The string `...` in an output line is equivalent to the 501 | string pattern `.-`, a group of one or more whitespace characters is 502 | equivalent to `%s+`. Additionally, whitespace at the end of the output 503 | is ignored. 504 | 505 | An empty line (containing only whitespace) is skipped (unless it 506 | starts with 4 spaces in which case it is considered an output line). 507 | The test/example section ends with the first non-empty line that is 508 | not indented at least 4 spaces. 509 | 510 | 511 | #### Examples #### 512 | 513 | local annotate = require( "annotate" ) 514 | local test = require( "annotate.test" ) 515 | 516 | func = annotate[=[ 517 | This is function `func`. 518 | 519 | func( n ) ==> number 520 | n: number 521 | 522 | Examples: 523 | > return func( 1 ) 524 | 1 525 | > function f( n ) 526 | >> return func( n ) 527 | >> end 528 | > = f( 2 ) 529 | 2 530 | > = f( 2 ) -- this test will fail! 531 | 3 532 | > print( "hello\nworld" ) 533 | hello 534 | world 535 | > = 2+"x" 536 | ...attempt to perform arithmetic... 537 | 538 | This is the end of the test code! 539 | ]=] .. 540 | function( n ) 541 | return n 542 | end 543 | 544 | test() -- run the tests 545 | 546 | The output is: 547 | 548 | ### [++-++] function func( n ) 549 | ### TOTAL: 4 ok, 1 failed, 5 total 550 | 551 | 552 | ## Changelog ## 553 | 554 | * Version 0.2 [2014/02/xx] 555 | * added plugin for simple interactive help 556 | * added plugin for running test code within annotations 557 | * Version 0.1 [2013/04/21] 558 | * first public release 559 | 560 | 561 | ## Download ## 562 | 563 | The source code (with documentation and test scripts) is available on 564 | [github][12]. 565 | 566 | [12]: https://github.com/siffiejoe/lua-annotate/ 567 | 568 | 569 | ## Installation ## 570 | 571 | There are two ways to install this module, either using luarocks (if 572 | this module already ended up in the [main luarocks repository][13]) or 573 | manually. 574 | 575 | Using luarocks, simply type: 576 | 577 | luarocks install annotate 578 | 579 | To install the module manually just drop `annotate.lua` and 580 | `annotate/*.lua` somewhere into your Lua `package.path`. You will 581 | also need [LPeg][9] (at least for the type checker, and the test 582 | module). 583 | 584 | [13]: http://luarocks.org/repositories/rocks/ (Main Repository) 585 | 586 | 587 | ## Contact ## 588 | 589 | Philipp Janda, siffiejoe(a)gmx.net 590 | 591 | Comments and feedback are always welcome. 592 | 593 | 594 | ## License ## 595 | 596 | `annotate` is *copyrighted free software* distributed under the MIT 597 | license (the same license as Lua 5.1). The full license text follows: 598 | 599 | annotate (c) 2013 Philipp Janda 600 | 601 | Permission is hereby granted, free of charge, to any person obtaining 602 | a copy of this software and associated documentation files (the 603 | "Software"), to deal in the Software without restriction, including 604 | without limitation the rights to use, copy, modify, merge, publish, 605 | distribute, sublicense, and/or sell copies of the Software, and to 606 | permit persons to whom the Software is furnished to do so, subject to 607 | the following conditions: 608 | 609 | The above copyright notice and this permission notice shall be 610 | included in all copies or substantial portions of the Software. 611 | 612 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 613 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 614 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 615 | IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY 616 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 617 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 618 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 619 | 620 | 621 | -------------------------------------------------------------------------------- /src/annotate.lua: -------------------------------------------------------------------------------- 1 | -- general library for Lua value annotations using docstrings 2 | 3 | local assert = assert 4 | local type = assert( type ) 5 | local pairs = assert( pairs ) 6 | local setmetatable = assert( setmetatable ) 7 | 8 | 9 | local M = { 10 | callbacks = {}, 11 | callbacks_r = {}, 12 | } 13 | 14 | 15 | local decorator_meta = { 16 | __concat = function( self, v ) 17 | local docstring = self.docstring 18 | for i = 1, #self.callbacks_r do 19 | v = self.callbacks_r[ i ]( v, docstring ) 20 | end 21 | for cb in pairs( self.callbacks ) do 22 | cb( v, docstring ) 23 | end 24 | return v 25 | end 26 | } 27 | 28 | 29 | local M_meta = { 30 | __index = { 31 | register = function( self, fun, replace ) 32 | assert( type( fun ) == "function", 33 | "docstring callback must be a function" ) 34 | if replace then 35 | local cb = self.callbacks_r 36 | if not cb[ fun ] then 37 | cb[ fun ] = true 38 | cb[ #cb+1 ] = fun 39 | end 40 | else 41 | self.callbacks[ fun ] = true 42 | end 43 | return self 44 | end, 45 | }, 46 | __call = function( self, docstring ) 47 | assert( type( docstring ) == "string", 48 | "docstring must be a string" ) 49 | local decorator = { 50 | docstring = docstring, 51 | callbacks_r = self.callbacks_r, 52 | callbacks = self.callbacks, 53 | } 54 | setmetatable( decorator, decorator_meta ) 55 | return decorator 56 | end, 57 | } 58 | 59 | 60 | setmetatable( M, M_meta ) 61 | return M 62 | 63 | -------------------------------------------------------------------------------- /src/annotate/check.lua: -------------------------------------------------------------------------------- 1 | -- cache globals and require modules 2 | local assert = assert 3 | local require = assert( require ) 4 | local annotate = require( "annotate" ) 5 | local table = require( "table" ) 6 | local string = require( "string" ) 7 | local L = require( "lpeg" ) 8 | local _VERSION = assert( _VERSION ) 9 | local pairs = assert( pairs ) 10 | local ipairs = assert( ipairs ) 11 | local type = assert( type ) 12 | local select = assert( select ) 13 | local error = assert( error ) 14 | local tostring = assert( tostring ) 15 | local setmetatable = assert( setmetatable ) 16 | local t_insert = assert( table.insert ) 17 | local t_concat = assert( table.concat ) 18 | local t_sort = assert( table.sort ) 19 | local s_format = assert( string.format ) 20 | local L_match = assert( L.match ) 21 | local loadstring = assert( loadstring or load ) 22 | local unpack = assert( unpack or table.unpack ) 23 | -- optional 24 | local print, next, io = print, next, io 25 | 26 | 27 | ---------------------------------------------------------------------- 28 | -- The argument and return value specification can be expressed as a 29 | -- regular language. Every regular language can be recognized by a 30 | -- deterministic finite automaton. Below code implements classes 31 | -- for state transitions, NFAs, and DFAs, which can be compiled into 32 | -- Lua code for argument and/or return value checking. 33 | 34 | 35 | -- small class for NFA/DFA transitions 36 | local transition = {} 37 | local transition_meta = { __index = transition } 38 | 39 | function transition:new( from, to, fname, f ) 40 | local tr = { 41 | from = from, to = to, fname = fname or "#eps#", f = f 42 | } 43 | setmetatable( tr, transition_meta ) 44 | return tr 45 | end 46 | 47 | -- for sorting 48 | function transition_meta:__lt( other ) 49 | if self.from == other.from then 50 | if self.to == other.to then 51 | return self.f ~= other.f and self.fname < other.fname 52 | else 53 | return self.to < other.to 54 | end 55 | else 56 | return self.from < other.from 57 | end 58 | end 59 | 60 | 61 | 62 | -- Small class for non-deterministic finite automata (NFAs). 63 | -- Objects are constructed such that the first state is the only 64 | -- starting state, and the last state is the only accepting final 65 | -- state. Also the only state without outgoing transitions is the end 66 | -- state! 67 | local NFA = {} 68 | local NFA_meta = { __index = NFA } 69 | 70 | do 71 | local primitive_types = { 72 | [ "nil" ] = true, 73 | [ "boolean" ] = true, 74 | [ "number" ] = true, 75 | [ "string" ] = true, 76 | [ "table" ] = true, 77 | [ "function" ] = true, 78 | [ "userdata" ] = true, 79 | [ "thread" ] = true, 80 | } 81 | 82 | -- private local function as by itself it does not correctly 83 | -- handle the needs_backtracking flag 84 | local function add_transition( fa, from, to, fname, f ) 85 | local trs = fa.transitions 86 | trs[ #trs+1 ] = transition:new( from, to, fname, f ) 87 | if fname and not primitive_types[ fname ] then 88 | fa.has_user_type = true 89 | end 90 | end 91 | 92 | -- private local function because it isn't useful without the 93 | -- add_transition function above 94 | local function nfa_append( self, a ) 95 | local offset = self.n 96 | self.n = offset + a.n 97 | local self_trs, a_trs = self.transitions, a.transitions 98 | for i = 1, #a_trs do 99 | local tr = a_trs[ i ] 100 | self_trs[ #self_trs+1 ] = transition:new( tr.from + offset, 101 | tr.to + offset, 102 | tr.fname, tr.f ) 103 | end 104 | self.has_user_type = self.has_user_type or a.has_user_type 105 | self.is_nonlinear = self.is_nonlinear or a.is_nonlinear 106 | self.needs_backtracking = self.needs_backtracking or 107 | a.needs_backtracking 108 | end 109 | 110 | function NFA:new( name, f ) 111 | local a = { n = 1, transitions = {} } 112 | setmetatable( a, NFA_meta ) 113 | if name and f then 114 | a.n = 2 115 | add_transition( a, 1, 2, name, f ) 116 | end 117 | return a 118 | end 119 | 120 | -- add the states/transitions from another NFA as an alternative to 121 | -- this NFA 122 | function NFA:alt( a ) 123 | local last = self.n 124 | nfa_append( self, a ) 125 | add_transition( self, 1, last+1 ) 126 | add_transition( self, last, self.n ) 127 | self.is_nonlinear = true 128 | if self.has_user_type or a.has_user_type then 129 | self.needs_backtracking = true 130 | end 131 | end 132 | 133 | -- add the states/transitions from another NFA in sequence to this NFA 134 | function NFA:seq( a ) 135 | local last = self.n 136 | nfa_append( self, a ) 137 | add_transition( self, last, last+1 ) 138 | if self.is_nonlinear and a.has_user_type then 139 | self.needs_backtracking = true 140 | end 141 | end 142 | 143 | -- make all transitions in this NFA optional 144 | function NFA:opt() 145 | local last = self.n 146 | add_transition( self, 1, self.n ) 147 | self.is_nonlinear = true 148 | if self.has_user_type then 149 | self.needs_backtracking = true 150 | end 151 | end 152 | 153 | -- add repetition to this NFA 154 | function NFA:rep() 155 | add_transition( self, self.n, 1 ) 156 | self.n = self.n + 1 157 | add_transition( self, self.n-1, self.n ) 158 | self.is_nonlinear = true 159 | if self.has_user_type then 160 | self.needs_backtracking = true 161 | end 162 | end 163 | 164 | -- collect all states which are connected to any of the given states 165 | -- via epsilon transitions 166 | function NFA:closure( states ) 167 | local queue, set = {}, {} 168 | for i in pairs( states ) do 169 | queue[ #queue+1 ] = i 170 | end 171 | for _,sid in ipairs( queue ) do 172 | set[ sid ] = true 173 | for i = 1, #self.transitions do 174 | local tr = self.transitions[ i ] 175 | if tr.from == sid 176 | and tr.f == nil 177 | and not set[ tr.to ] then 178 | queue[ #queue+1 ] = tr.to 179 | end 180 | end 181 | end 182 | return set 183 | end 184 | 185 | -- collect all states reachable from the given set of states in one 186 | -- step via the predicate function f 187 | function NFA:reachable( states, f ) 188 | local set = {} 189 | for i = 1, #self.transitions do 190 | local tr = self.transitions[ i ] 191 | if states[ tr.from ] and tr.f == f then 192 | set[ tr.to ] = true 193 | end 194 | end 195 | return set 196 | end 197 | end 198 | 199 | 200 | -- small class for deterministic finite automata (DFAs) 201 | local DFA = {} 202 | local DFA_meta = { __index = DFA } 203 | 204 | do 205 | local function set_equal( s1, s2 ) 206 | for k,v in pairs( s1 ) do 207 | if s2[ k ] ~= v then 208 | return false 209 | end 210 | end 211 | for k,v in pairs( s2 ) do 212 | if s1[ k ] ~= v then 213 | return false 214 | end 215 | end 216 | return true 217 | end 218 | 219 | -- assign consecutive ids to sets (ids cached in list) 220 | local function id4set( list, set ) 221 | for i = 1, #list do 222 | if set_equal( list[ i ], set ) then 223 | return i, true 224 | end 225 | end 226 | list[ #list+1 ] = set 227 | return #list, false 228 | end 229 | 230 | -- Constructs an equivalent DFA from the given NFA. The only states 231 | -- without outgoing transitions are end/accepting states. 232 | function DFA:new( an_nfa ) 233 | local a = { 234 | n = 0, 235 | needs_backtracking = an_nfa.needs_backtracking, 236 | flags = {}, 237 | transitions = {}, 238 | } 239 | if an_nfa.n > 0 then 240 | local dfastates, a_trs = {}, a.transitions 241 | id4set( dfastates, an_nfa:closure{ true } ) 242 | for i,st in ipairs( dfastates ) do 243 | if st[ an_nfa.n ] then 244 | a.flags[ i ] = true -- mark as accepting end state 245 | end 246 | local fs = {} 247 | for j = 1, #an_nfa.transitions do 248 | local tr = an_nfa.transitions[ j ] 249 | if st[ tr.from ] and tr.f and not fs[ tr.f ] then 250 | fs[ tr.f ] = true 251 | local n_st = an_nfa:closure( an_nfa:reachable( st, tr.f ) ) 252 | local id = id4set( dfastates, n_st ) 253 | a_trs[ #a_trs+1 ] = transition:new( i, id, tr.fname, tr.f ) 254 | end 255 | end 256 | end 257 | a.n = #dfastates 258 | end 259 | setmetatable( a, DFA_meta ) 260 | return a 261 | end 262 | 263 | -- Sorts the transitions and returns a lookup table t where 264 | -- t[ state_id ] is the first index in the transitions table where 265 | -- transitions originating from state_id are stored. This is used to 266 | -- speed up lookups. 267 | function DFA:lookup() 268 | local indices = {} 269 | t_sort( self.transitions ) 270 | local tr_index = 1 271 | for i = 1, self.n+1 do 272 | indices[ i ] = tr_index 273 | local curr_tr = self.transitions[ tr_index ] 274 | while curr_tr and curr_tr.from == i do 275 | tr_index = tr_index + 1 276 | curr_tr = self.transitions[ tr_index ] 277 | end 278 | end 279 | return indices 280 | end 281 | 282 | function DFA:compile() 283 | if self.needs_backtracking then 284 | return self:compile_backtracking() 285 | else 286 | return self:compile_optimized() 287 | end 288 | end 289 | 290 | -- create n comma separated names given the pattern 291 | local function n_args( n, fmt ) 292 | local s = "" 293 | for i = 1, n do 294 | s = s..s_format( fmt, i ) 295 | if i ~= n then 296 | s = s..", " 297 | end 298 | end 299 | return s 300 | end 301 | 302 | -- array for passing the functions to the compiled code 303 | local function fcollect( trs ) 304 | local f2id, id2f = {}, {} 305 | for i = 1, #trs do 306 | local f = trs[ i ].f 307 | if not f2id[ f ] then 308 | id2f[ #id2f+1 ] = f 309 | f2id[ f ] = #id2f 310 | end 311 | end 312 | return f2id, id2f 313 | end 314 | 315 | function DFA:compile_optimized() 316 | --do return self:compile_backtracking() end 317 | local indices = self:lookup() 318 | local code = "local spec, fname, etype, ioff, erroff, select, error, tconcat" 319 | -- pass all required checking functions 320 | local f2id, id2f = fcollect( self.transitions ) 321 | if #id2f > 0 then 322 | -- get checkers from argument list 323 | code = code..", "..n_args( #id2f, "f_%d" ) 324 | end 325 | code = code.." = ...\n" 326 | -- forward declare the state functions 327 | code = code.."local "..n_args( self.n, "state_%d" ).."\n" 328 | -- generate the state functions 329 | for i = 1, self.n do 330 | code = code..[[ 331 | function state_]]..i..[[( i, n, ... ) 332 | ]] 333 | local types = "" 334 | for j = indices[ i ], indices[ i+1 ]-1 do 335 | if j > indices[ i ] then 336 | types = types.."/" 337 | end 338 | types = types..self.transitions[ j ].fname 339 | end 340 | code = code..[[ 341 | if i > n then 342 | ]] 343 | if self.flags[ i ] then 344 | code = code..[[ 345 | return true 346 | ]] 347 | else 348 | code = code..[[ 349 | return false, "missing "..etype.."(s) at index "..(i+ioff).. 350 | " (expected ]] .. types ..[[)" 351 | ]] 352 | end 353 | code = code..[[ 354 | else 355 | local val = select( i, ... ) 356 | ]] 357 | for j = indices[ i ], indices[ i+1 ]-1 do 358 | local tr = self.transitions[ j ] 359 | code = code..[[ 360 | if f_]]..f2id[ tr.f ]..[[( val ) then 361 | return state_]]..tr.to..[[( i+1, n, ... ) 362 | end 363 | ]] 364 | end 365 | code = code..[[ 366 | local msg 367 | ]] 368 | if indices[ i ] ~= indices[ i+1 ] then 369 | code = code..[[ 370 | msg = "]]..types..[[ expected for "..etype.." no. ".. 371 | (i+ioff).." (got "..type( val )..")" 372 | ]] 373 | end 374 | if self.flags[ i ] then 375 | code = code..[[ 376 | local s = "too many "..etype.."s (expected "..(i+ioff-1)..")" 377 | msg = msg and msg..",\n\tor "..s or s 378 | ]] 379 | end 380 | code = code..[[ 381 | return false, msg or "unknown error" 382 | end 383 | end 384 | ]] 385 | end 386 | code = code..[[ 387 | return function( ... ) 388 | local n = select( '#', ... ) 389 | local ok, msg = state_1( 1, n, ... ) 390 | if not ok then 391 | error( fname..": "..msg..".", 5+erroff ) 392 | end 393 | return ... 394 | end 395 | ]] 396 | return code, id2f 397 | end 398 | 399 | -- returns lua code that implements the DFA 400 | function DFA:compile_backtracking() 401 | local indices = self:lookup() 402 | local code = "local spec, fname, etype, ioff, erroff, select, error, tconcat" 403 | -- pass all required checking functions 404 | local f2id, id2f = fcollect( self.transitions ) 405 | if #id2f > 0 then 406 | -- get checkers from argument list 407 | code = code..", "..n_args( #id2f, "f_%d" ) 408 | end 409 | code = code.." = ...\n" 410 | -- forward declare the state functions 411 | code = code.."local "..n_args( self.n, "state_%d" ).."\n" 412 | -- generate the state functions 413 | for i = 1, self.n do 414 | code = code..[[ 415 | function state_]]..i..[[( msg, i, n, ... ) 416 | ]] 417 | local types = "" 418 | for j = indices[ i ], indices[ i+1 ]-1 do 419 | if j > indices[ i ] then 420 | types = types.."/" 421 | end 422 | types = types..self.transitions[ j ].fname 423 | end 424 | code = code..[[ 425 | if i > n then 426 | ]] 427 | if self.flags[ i ] then 428 | code = code..[[ 429 | return true 430 | ]] 431 | else 432 | code = code..[[ 433 | if msg then 434 | msg[ #msg+1 ] = "missing "..etype.."(s) at index "..(i+ioff).. 435 | " (expected ]]..types..[[)" 436 | end 437 | ]] 438 | end 439 | code = code..[[ 440 | else 441 | local val, match = select( i, ... ), false 442 | ]] 443 | for j = indices[ i ], indices[ i+1 ]-1 do 444 | local tr = self.transitions[ j ] 445 | code = code..[[ 446 | if f_]]..f2id[ tr.f ]..[[( val ) then 447 | match = true 448 | if state_]]..tr.to..[[( msg, i+1, n, ... ) then return true end 449 | end 450 | ]] 451 | end 452 | code = code..[[ 453 | if msg then 454 | ]] 455 | if indices[ i ] ~= indices[ i+1 ] then 456 | code = code..[[ 457 | if not match then 458 | msg[ #msg+1 ] = "]]..types..[[ expected for "..etype.." no. ".. 459 | (i+ioff).." (got "..type( val )..")" 460 | end 461 | ]] 462 | end 463 | if self.flags[ i ] then 464 | code = code..[[ 465 | msg[ #msg+1 ] = "too many "..etype.."s (expected ".. 466 | (i+ioff-1)..")" 467 | ]] 468 | end 469 | code = code..[[ 470 | end 471 | end 472 | return false 473 | end 474 | ]] 475 | end 476 | code = code..[[ 477 | return function( ... ) 478 | local n = select( '#', ... ) 479 | if not state_1( nil, 1, n, ... ) then 480 | local t = {} 481 | state_1( t, 1, n, ... ) -- rerun to collect error messages 482 | error( fname..": "..tconcat( t, ",\n\tor " )..".", 5+erroff ) 483 | end 484 | return ... 485 | end 486 | ]] 487 | return code, id2f 488 | end 489 | end 490 | 491 | 492 | local function debug_automaton( fa ) 493 | local end_states = {} 494 | if fa.flags then 495 | for i = 1, fa.n do 496 | if fa.flags[ i ] then 497 | end_states[ #end_states+1 ] = i 498 | end 499 | end 500 | else 501 | end_states[ 1 ] = fa.n 502 | end 503 | print( "states:", fa.n, "END:", unpack( end_states ) ) 504 | print( "needs_backtracking:", fa.needs_backtracking ) 505 | for i,t in ipairs( fa.transitions ) do 506 | print( "", t.from, "-->", t.to, t.fname ) 507 | end 508 | end 509 | 510 | 511 | 512 | ---------------------------------------------------------------------- 513 | -- A parser for docstrings using LPeg. 514 | -- 515 | -- Example: 516 | -- mod.obj:func = docstring[=[ 517 | -- Some optional text (which is ignored). 518 | -- 519 | -- mod.obj:func( a [, b [, c]], ... ) 520 | -- ==> table/userdata -- when successful 521 | -- ==> nil, string -- in case of error 522 | -- self: object -- implicit if not specified 523 | -- a: table/userdata -- some table or userdata 524 | -- b: integer -- an optional number 525 | -- -- comments can span several lines 526 | -- c: any -- any value allowed 527 | -- ... : (table, string)* 528 | -- 529 | -- Some more text describing the function which is also ignored 530 | -- by the function signature parser! 531 | -- ]=] .. function( a, b, c, ... ) end 532 | 533 | local g = {} 534 | do 535 | local P,R,S,V,C,Cc,Ct = L.P,L.R,L.S,L.V,L.C,L.Cc,L.Ct 536 | local pbreak = P"\n\n" 537 | local comment = P"--" * (P( 1 ) - P"\n")^0 538 | local ws = S" \t\r\n\v\f" 539 | local _ = ((ws + comment) - pbreak)^0 540 | local letter = R( "az", "AZ" ) + P"_" 541 | local digit = R"09" 542 | local id = letter * (letter+digit)^0 543 | local varargs = C( P"..." ) *_ 544 | local retsym = P"="^1 * P">" * _ 545 | 546 | g[ 1 ] = ws^0 * (V"paragraph" - V"typespec")^0 * V"typespec" * V"paragraph"^0 * P( -1 ) 547 | g.paragraph = (P( 1 ) - pbreak)^1 * ws^0 548 | g.typespec = C( _ * V"funcname" * P"(" * _ * Ct( V"arglistv" ) * P")" * _ * V"retlist" * V"paramspec" ) * ws^0 549 | g.funcname = C( id * (P"." * id)^0 * ((P":" * id * Cc( true )) + Cc( false )) ) * _ 550 | -- argument list 551 | g.arglistv = (V"arg" + V"optargs")^0 * (P","^-1 * _ * (V"optargsv" + varargs))^-1 552 | g.arg = P","^-1 * _ * C( id ) * _ * P","^-1 * _ 553 | g.optargs = P"[" * _ * Ct( (V"arg" + V"optargs")^1 ) * P"]" * _ * P","^-1 * _ 554 | g.optargsv = P"[" * _ * Ct( V"arglistv" ) * P"]" * _ 555 | -- return values 556 | g.retlist = Ct( Cc"alt" * (retsym * V"seq")^0 ) 557 | -- argument type specifications 558 | g.paramspec = Ct( V"argspec"^0 * V"varargspec"^-1 * V"argspec"^0 ) 559 | g.argspec = Ct( C( id ) * _ * P":" * _ * C( id ) * _ * (P"/" * _ * C( id ) * _)^0 ) 560 | g.varargspec = Ct( varargs * P":" * _ * V"seq" ) 561 | -- common to return values and vararg type specifications 562 | g.seq = Ct( Cc"seq" * V"alt" * (P"," * _ * V"alt")^1 ) + V"alt" 563 | g.alt = Ct( Cc"alt" * V"mul" * (P"/" * _ * V"mul")^1 ) + V"mul" 564 | g.mul = Ct( Cc"mul" * V"val" * P"*" * _ ) + 565 | Ct( Cc"opt" * V"val" * P"?" * _ ) + V"val" 566 | g.val = (C( id ) + P"(" * _ * V"seq" * P")") * _ 567 | 568 | -- compile grammar once and for all 569 | g = P( g ) 570 | end 571 | 572 | 573 | -- debug function to show some nested tables captured by lpeg 574 | local function debug_ast( node, prefix ) 575 | prefix = prefix or "" 576 | if type( node ) == "table" then 577 | io.stderr:write( "{" ) 578 | if next( node ) ~= nil then 579 | io.stderr:write( "\n" ) 580 | for k,v in pairs( node ) do 581 | io.stderr:write( prefix, " ", tostring( k ), " = " ) 582 | debug_ast( v, prefix.." " ) 583 | end 584 | end 585 | io.stderr:write( prefix, "}\n" ) 586 | else 587 | io.stderr:write( tostring( node ), "\n" ) 588 | end 589 | end 590 | 591 | 592 | 593 | ---------------------------------------------------------------------- 594 | -- Putting it all together ... 595 | 596 | 597 | -- generates an nfa from the given AST (seq,alt,opt,mul,val) 598 | local function nfa_from_expr( types, expr ) 599 | local t = type( expr ) 600 | if t == "string" then 601 | local f = types[ expr ] 602 | if type( f ) ~= "function" then 603 | return nil, "type `"..expr.."' is undefined!" 604 | end 605 | return NFA:new( expr, f ) 606 | elseif t == "table" then 607 | if expr[ 1 ] == "seq" then 608 | local n = NFA:new() 609 | for i = 2, #expr do 610 | local n2, msg = nfa_from_expr( types, expr[ i ] ) 611 | if not n2 then return n2, msg end 612 | n:seq( n2 ) 613 | end 614 | return n 615 | elseif expr[ 1 ] == "alt" then 616 | local n 617 | for i = 2, #expr do 618 | local n2, msg = nfa_from_expr( types, expr[ i ] ) 619 | if not n2 then return n2, msg end 620 | if not n then 621 | n = n2 622 | else 623 | n:alt( n2 ) 624 | end 625 | end 626 | return n or NFA:new() 627 | elseif expr[ 1 ] == "mul" then 628 | local n, msg = nfa_from_expr( types, expr[ 2 ] ) 629 | if n then n:rep() n:opt() end 630 | return n, msg 631 | elseif expr[ 1 ] == "opt" then 632 | local n, msg = nfa_from_expr( types, expr[ 2 ] ) 633 | if n then n:opt() end 634 | return n, msg 635 | else 636 | error( "invalid node in expression tree: "..tostring( expr[ 1 ] ) ) 637 | end 638 | else 639 | error( "invalid value in expression tree: "..tostring( expr ) ) 640 | end 641 | end 642 | 643 | 644 | local function arg2nfa( types, symtab, usedargs, arg ) 645 | local t = type( arg ) 646 | if t == "table" then 647 | local n = NFA:new() 648 | for i = 1, #arg do 649 | local n2, msg = arg2nfa( types, symtab, usedargs, arg[ i ] ) 650 | if not n2 then return n2, msg end 651 | n:seq( n2 ) 652 | end 653 | n:opt() 654 | return n 655 | elseif t == "string" then 656 | if symtab[ arg ] then 657 | if usedargs[ arg ] then 658 | return nil, "argument name `"..arg.."' used multiple times!" 659 | end 660 | usedargs[ arg ] = true 661 | return symtab[ arg ] 662 | elseif types[ arg ] then 663 | return NFA:new( arg, types[ arg ] ) 664 | else 665 | return nil, "argument name `"..arg.."' not defined!" 666 | end 667 | else 668 | error( "invalid value in argument list: "..tostring( arg ) ) 669 | end 670 | end 671 | 672 | 673 | -- combines the argument list with the nfas from the symbol table 674 | local function nfa_from_args( types, symtab, args ) 675 | local usedargs = {} 676 | local n = NFA:new() 677 | for i = 1, #args do 678 | local n2, msg = arg2nfa( types, symtab, usedargs, args[ i ] ) 679 | if not n2 then return n2, msg end 680 | n:seq( n2 ) 681 | end 682 | return n 683 | end 684 | 685 | 686 | -- generate nfas for arg specs 687 | local function build_symbol_table( types, is_method, argtypes, warn ) 688 | local symtab = {} 689 | for i = 1, #argtypes do 690 | local a = argtypes[ i ][ 1 ] 691 | if symtab[ a ] then 692 | return nil, "argument `"..a.."' redefined!" 693 | end 694 | local n, msg 695 | if a == "..." then 696 | n, msg = nfa_from_expr( types, argtypes[ i ][ 2 ] ) 697 | else 698 | argtypes[ i ][ 1 ] = "alt" 699 | n, msg = nfa_from_expr( types, argtypes[ i ] ) 700 | end 701 | if not n then 702 | return nil, msg 703 | end 704 | symtab[ a ] = n 705 | end 706 | if is_method and not symtab.self then 707 | if types.object then 708 | symtab.self = NFA:new( "object", types.object ) 709 | elseif types.table and types.userdata then 710 | local n = NFA:new( "userdata", types.userdata ) 711 | n:alt( NFA:new( "table", types.table ) ) 712 | symtab.self = n 713 | end 714 | end 715 | return symtab 716 | end 717 | 718 | 719 | local function compile_args_check( types, spec, name, is_method, args, 720 | argtypes, warn ) 721 | local symtab, msg = build_symbol_table( types, is_method, argtypes, 722 | warn ) 723 | if not symtab then 724 | warn( "[check]: "..msg.."\n"..spec ) 725 | return 726 | end 727 | -- combine with arglists 728 | if is_method then 729 | t_insert( args, 1, "self" ) 730 | end 731 | local n, msg = nfa_from_args( types, symtab, args ) 732 | if not n then 733 | warn( "[check]: "..msg.."\n"..spec ) 734 | return 735 | end 736 | local d = DFA:new( n ) 737 | --debug_automaton( d ) 738 | local source, id2f = d:compile() 739 | --print( source ) 740 | local f = assert( loadstring( source, "=[compiled_arg_check]" ) ) 741 | local off = is_method and -1 or 0 742 | return f( spec, name, "argument", off, 0, select, error, t_concat, 743 | unpack( id2f ) ) 744 | end 745 | 746 | 747 | local function compile_return_check( types, spec, name, rets, warn ) 748 | local n, msg = nfa_from_expr( types, rets ) 749 | if not n then 750 | warn( "[check]: "..msg.."\n"..spec ) 751 | return 752 | end 753 | local d = DFA:new( n ) 754 | --debug_automaton( d ) 755 | local source, id2f = d:compile() 756 | --print( source ) 757 | local f = assert( loadstring( source, "=[compiled_ret_check]" ) ) 758 | -- Lua 5.2 doesn't count tailcalls for errorlevels ... 759 | local erroff = _VERSION ~= "Lua 5.1" and -1 or 0 760 | return f( spec, name, "return value", 0, erroff, select, error, 761 | t_concat, unpack( id2f ) ) 762 | end 763 | 764 | 765 | -- compiles the given string into argument and return checking functions 766 | local function compile_typespec( input, types, do_arg, do_ret, warn ) 767 | warn = warn or error 768 | local spec, name, is_method, args, rets, argtypes = L_match( g, input ) 769 | if not spec then 770 | warn( "[check]: docstring does not contain type specification!" ) 771 | else 772 | name = is_method and name:gsub( ":", "." ) or name 773 | local arg_check_func, ret_check_func 774 | if do_arg then 775 | arg_check_func = compile_args_check( types, spec, name, is_method, 776 | args, argtypes, warn ) 777 | end 778 | if do_ret then 779 | ret_check_func = compile_return_check( types, spec, name, rets, 780 | warn ) 781 | end 782 | return arg_check_func, ret_check_func 783 | end 784 | end 785 | 786 | 787 | -- primitive type checking functions 788 | local types = { 789 | ["nil"] = function( val ) return val == nil end, 790 | boolean = function( val ) return type( val ) == "boolean" end, 791 | number = function( val ) return type( val ) == "number" end, 792 | string = function( val ) return type( val ) == "string" end, 793 | table = function( val ) return type( val ) == "table" end, 794 | userdata = function( val ) return type( val ) == "userdata" end, 795 | ["function"] = function( val ) return type( val ) == "function" end, 796 | thread = function( val ) return type( val ) == "thread" end, 797 | any = function( val ) return true end, 798 | integer = function( val ) 799 | return type( val ) == "number" and val % 1 == 0 800 | end, 801 | object = function( val ) 802 | local t = type( val ) 803 | return t == "userdata" or t == "table" 804 | end, 805 | [ "true" ] = function( val ) return val ~= nil and val ~= false end, 806 | [ "false" ] = function( val ) return val == nil or val == false end, 807 | } 808 | 809 | -- additional type checking functions depending on optional modules 810 | if type( io ) == "table" and type( io.type ) == "function" then 811 | local iotype = io.type 812 | types[ "file" ] = function( val ) 813 | return iotype( val ) == "file" 814 | end 815 | end 816 | if type( L.type ) == "function" then 817 | local lpegtype = L.type 818 | types[ "pattern" ] = function( val ) 819 | return lpegtype( val ) == "pattern" 820 | end 821 | end 822 | 823 | 824 | 825 | local M = { 826 | enabled = true, 827 | types = types, 828 | errorf = function( s ) return error( s, 0 ) end, 829 | arguments = true, 830 | return_values = true, 831 | } 832 | 833 | 834 | local function docstring_callback( fun, docstring ) 835 | local newfun = fun 836 | if M.enabled and type( fun ) == "function" then 837 | local argc, retc = compile_typespec( docstring, M.types, 838 | M.arguments, M.return_values, 839 | M.errorf ) 840 | if argc and retc then 841 | newfun = function( ... ) 842 | return retc( fun( argc( ... ) ) ) 843 | end 844 | elseif argc then 845 | newfun = function( ... ) 846 | return fun( argc( ... ) ) 847 | end 848 | elseif retc then 849 | newfun = function( ... ) 850 | return retc( fun( ... ) ) 851 | end 852 | end 853 | end 854 | return newfun 855 | end 856 | 857 | annotate:register( docstring_callback, true ) 858 | 859 | return M 860 | 861 | -------------------------------------------------------------------------------- /src/annotate/help.lua: -------------------------------------------------------------------------------- 1 | local assert = assert 2 | local require = assert( require ) 3 | local annotate = require( "annotate" ) 4 | local string = require( "string" ) 5 | local s_gsub = assert( string.gsub ) 6 | local s_match = assert( string.match ) 7 | local s_rep = assert( string.rep ) 8 | local _VERSION = assert( _VERSION ) 9 | local type = assert( type ) 10 | local next = assert( next ) 11 | local select = assert( select ) 12 | local tostring = assert( tostring ) 13 | local tonumber = assert( tonumber ) 14 | local print = assert( print ) 15 | local pcall = assert( pcall ) 16 | local setmetatable = assert( setmetatable ) 17 | 18 | local _G, bit32, coroutine, debug, io, math, os, package, table = 19 | _G, bit32, coroutine, debug, io, math, os, package, table 20 | 21 | local V = assert( tonumber( s_match( _VERSION, "^Lua%s+(%d+%.%d+)$" ) ) ) 22 | 23 | 24 | local docstring_cache = {} 25 | setmetatable( docstring_cache, { __mode="k" } ) 26 | 27 | local function docstring_callback( v, docstring ) 28 | docstring_cache[ v ] = docstring 29 | end 30 | 31 | annotate:register( docstring_callback ) 32 | 33 | ---------------------------------------------------------------------- 34 | 35 | local function check( t, name, cond ) 36 | if cond == nil then cond = true end -- default is true 37 | if type( cond ) == "number" then -- minimum version specified 38 | cond = (V >= cond) and (V < 5.3) 39 | end 40 | return cond and type( t ) == "table" and t[ name ] ~= nil 41 | end 42 | 43 | -- disable type checking temporarily 44 | local ARG_C, RET_C = false, false 45 | if type( package ) == "table" then 46 | local p_loaded = package.loaded 47 | if type( p_loaded ) == "table" then 48 | local c = p_loaded[ "annotate.check" ] 49 | if type( c ) == "table" then 50 | ARG_C, RET_C = c.arguments, c.return_values 51 | c.arguments, c.return_values = false, false 52 | end 53 | end 54 | end 55 | 56 | local A 57 | 58 | ---------------------------------------------------------------------- 59 | -- base library 60 | 61 | if check( _G, "_G", V >= 5.1 and V < 5.2 ) then 62 | A = annotate[=[ 63 | ## Lua Base Library ## 64 | 65 | Lua's base library defines the following global functions: 66 | 67 | * `assert` -- Raise an error if a condition is false. 68 | * `collectgarbage` -- Control the Lua garbage collector. 69 | * `dofile` -- Load and run a Lua file. 70 | * `error` -- Raise an error. 71 | * `getfenv` -- Get a function's environment. 72 | * `getmetatable` -- Get a table's/userdata's metatable. 73 | * `ipairs` -- Iterate over array elements in order. 74 | * `load` -- Generic function for loading Lua code. 75 | * `loadfile` -- Load Lua code from a file. 76 | * `loadstring` -- Load Lua code from a string. 77 | * `module` -- Declare a Lua module. 78 | * `next` -- Query next key/value from a table. 79 | * `pairs` -- Iterator over all elements in a table. 80 | * `pcall` -- Call Lua function catching all errors. 81 | * `print` -- Show Lua values on console. 82 | * `rawequal` -- Compare values without invoking metamethods. 83 | * `rawget` -- Get a value for a key without invoking metamethods. 84 | * `rawset` -- Set a value for a key without invoking metamethods. 85 | * `require` -- Load a module. 86 | * `select` -- Extract length/elements of varargs (`...`). 87 | * `setfenv` -- Set environment of functions. 88 | * `setmetatable` -- Set metatable on a tables/userdata. 89 | * `tonumber` -- Convert a string to a Lua number. 90 | * `tostring` -- Convert any Lua value to a string. 91 | * `type` -- Query the type of a Lua value. 92 | * `unpack` -- Convert an array to multiple values (vararg). 93 | * `xpcall` -- Like `pcall`, but provide stack traces for errors. 94 | 95 | Typically, the following libraries/tables are available: 96 | 97 | * `coroutine` -- Suspend/pause Lua code and resume it later. 98 | * `debug` -- Access debug information for Lua code. 99 | * `io` -- Input/output functions for files. 100 | * `math` -- Mathematical functions from C's standard library. 101 | * `os` -- Minimal interface to OS services. 102 | * `package` -- Settings/Functions for Loading Lua/C modules. 103 | * `string` -- Functions for manipulating strings. 104 | * `table` -- Functions for manipulating arrays. 105 | ]=] .. _G 106 | assert( A == _G, "_G modified by annotate plugin" ) 107 | end 108 | 109 | if check( _G, "_G", 5.2 ) then 110 | A = annotate[=[ 111 | ## Lua Base Library ## 112 | 113 | Lua's base library defines the following global functions: 114 | 115 | * `assert` -- Raise an error if a condition is false. 116 | * `collectgarbage` -- Control the Lua garbage collector. 117 | * `dofile` -- Load and run a Lua file. 118 | * `error` -- Raise an error. 119 | * `getmetatable` -- Get a table's/userdata's metatable. 120 | * `ipairs` -- Iterate over array elements in order. 121 | * `load` -- Generic function for loading Lua code. 122 | * `loadfile` -- Load Lua code from a file. 123 | * `next` -- Query next key/value from a table. 124 | * `pairs` -- Iterator over all elements in a table. 125 | * `pcall` -- Call Lua function catching all errors. 126 | * `print` -- Show Lua values on console. 127 | * `rawequal` -- Compare values without invoking metamethods. 128 | * `rawget` -- Get a value for a key without invoking metamethods. 129 | * `rawlen` -- Get length without invoking metamethods. 130 | * `rawset` -- Set a value for a key without invoking metamethods. 131 | * `require` -- Load a module. 132 | * `select` -- Extract length/elements of varargs (`...`). 133 | * `setmetatable` -- Set metatable on a tables/userdata. 134 | * `tonumber` -- Convert a string to a Lua number. 135 | * `tostring` -- Convert any Lua value to a string. 136 | * `type` -- Query the type of a Lua value. 137 | * `xpcall` -- Like `pcall`, but provide stack traces for errors. 138 | 139 | Typically, the following libraries/tables are available: 140 | 141 | * `bit32` -- Bit manipulation for 32bit unsigned integers. 142 | * `coroutine` -- Suspend/pause Lua code and resume it later. 143 | * `debug` -- Access debug information for Lua code. 144 | * `io` -- Input/output functions for files. 145 | * `math` -- Mathematical functions from C's standard library. 146 | * `os` -- Minimal interface to OS services. 147 | * `package` -- Settings/Functions for Loading Lua/C modules. 148 | * `string` -- Functions for manipulating strings. 149 | * `table` -- Functions for manipulating arrays. 150 | ]=] .. _G 151 | assert( A == _G, "_G modified by annotate plugin" ) 152 | end 153 | 154 | if check( _G, "assert", 5.1 ) then 155 | A = annotate[=[ 156 | ## The `assert` Function ## 157 | 158 | assert( cond, ... ) ==> any* 159 | cond: any -- evaluated as a condition 160 | ... : any* -- additional arguments 161 | 162 | If `assert`'s first argument evaluates to a true value (anything but 163 | `nil` or `false`), `assert` passes all arguments as return values. If 164 | the first argument is `false` or `nil`, `assert` raises an error using 165 | the second argument as an error message. If there is no second 166 | argument, a generic error message is used. 167 | 168 | ### Examples ### 169 | 170 | > =assert( true, 1, "two", {} ) 171 | true 1 two table: ... 172 | > =assert( false, "my error message", {} ) 173 | ...: my error message 174 | stack traceback: 175 | ... 176 | > function f() return nil end 177 | > assert( f() ) 178 | ...: assertion failed! 179 | stack traceback: 180 | ... 181 | ]=] .. _G.assert 182 | if A ~= _G.assert then _G.assert = A end 183 | end 184 | 185 | if check( _G, "collectgarbage", V >= 5.1 and V < 5.2 ) then 186 | A = annotate[=[ 187 | ## The `collectgarbage` Function ## 188 | 189 | collectgarbage( [opt [, arg]] ) ==> number/boolean 190 | opt: string -- one of a set of commands 191 | arg: integer 192 | 193 | This function controls Lua's garbage collector. The specific outcome 194 | depends on the value of the `opt` argument: 195 | 196 | * `"collect"`: Perform a full garbage collection cycle (default). 197 | * `"stop"`: Stop the garbage collector. 198 | * `"restart"`: Restart the garbage collector. 199 | * `"count"`: Return total number of memory used by Lua (in kB). 200 | * `"step"`: Perform a single garbage collection step. The amount of 201 | garbage collected depends on the `arg` parameter. Returns `true` 202 | if a full collection is complete. 203 | * `"setpause"`: Set the `pause` parameter. Returns old value. 204 | * `"setstepmul"`: Set the `step multiplier` parameter. Returns old 205 | value. 206 | ]=] .. _G.collectgarbage 207 | if A ~= _G.collectgarbage then _G.collectgarbage = A end 208 | end 209 | 210 | if check( _G, "collectgarbage", 5.2 ) then 211 | A = annotate[=[ 212 | ## The `collectgarbage` Function ## 213 | 214 | collectgarbage( [opt [, arg]] ) ==> number, integer 215 | ==> integer 216 | ==> boolean 217 | opt: string -- one of a set of commands 218 | arg: integer 219 | 220 | This function controls Lua's garbage collector. The specific outcome 221 | depends on the value of the `opt` argument: 222 | 223 | * `"collect"`: Perform a full garbage collection cycle (default). 224 | * `"stop"`: Stop the garbage collector. 225 | * `"restart"`: Restart the garbage collector. 226 | * `"count"`: Return total number of memory used by Lua in kB and 227 | in bytes modulo 1024. 228 | * `"step"`: Perform a single garbage collection step. The amount of 229 | garbage collected depends on the `arg` parameter. Returns `true` 230 | if a full collection is complete. 231 | * `"setpause"`: Set the `pause` parameter. Returns old value. 232 | * `"setstepmul"`: Set the `step multiplier` parameter. Returns old 233 | value. 234 | * `"isrunning"`: Check if the garbage collector is active/stopped. 235 | * `"generational"`: Set the GC to generational mode. 236 | * `"incremental"`: Set the GC to incremental mode (the default). 237 | ]=] .. _G.collectgarbage 238 | if A ~= _G.collectgarbage then _G.collectgarbage = A end 239 | end 240 | 241 | if check( _G, "dofile", 5.1 ) then 242 | A = annotate[=[ 243 | ## The `dofile` Function ## 244 | 245 | dofile( [filename] ) ==> any* 246 | filename: string -- file name to load and run 247 | 248 | Opens the given file, loads the contents as a Lua chunk, and calls it, 249 | returning all results and propagating errors raised within the chunk. 250 | If no file name is given, this function reads from the standard input 251 | `stdin`. 252 | ]=] .. _G.dofile 253 | if A ~= _G.dofile then _G.dofile = A end 254 | end 255 | 256 | if check( _G, "error", 5.1 ) then 257 | A = annotate[=[ 258 | ## The `error` Function ## 259 | 260 | error( message [, level] ) 261 | message: any -- an error message (typically a string) 262 | level : integer -- stack level where the error is raised 263 | 264 | This function raises a runtime error using the given error message and 265 | terminates the last protected function call. The `level` argument 266 | specifies the prefix added to the error message indicating the 267 | location of the error (`1` is the function calling `error`, `2` is the 268 | function calling the function that called `error`, etc.). `0` disables 269 | the error location prefix. 270 | 271 | ### Examples ### 272 | 273 | > error( "argh" ) 274 | ...: argh 275 | stack traceback: 276 | ... 277 | > error( "argh", 0 ) 278 | argh 279 | stack traceback: 280 | ... 281 | ]=] .. _G.error 282 | if A ~= _G.error then _G.error = A end 283 | end 284 | 285 | if check( _G, "getfenv", V >= 5.1 and V < 5.2 ) then 286 | A = annotate[=[ 287 | ## The `getfenv` Function ## 288 | 289 | getfenv( [f] ) ==> table/nil 290 | f: function/integer -- a function or a stack level 291 | 292 | Returns the current environment for the given function. If `f` is an 293 | integer, it is interpreted as a stack level to find the function on 294 | the call stack: `1` (which is the default) is the function calling 295 | `getfenv`, `2` is the function calling the function which called 296 | `getfenv`, and so on. If the given function is not a Lua function or 297 | if the stack level is `0`, the global environment is returned. 298 | 299 | ### Examples ### 300 | 301 | > function f() end 302 | > e = {} 303 | > setfenv( f, e ) 304 | > =getfenv( f ) == e 305 | true 306 | ]=] .. _G.getfenv 307 | if A ~= _G.getfenv then _G.getfenv = A end 308 | end 309 | 310 | if check( _G, "getmetatable", 5.1 ) then 311 | A = annotate[=[ 312 | ## The `getmetatable` Function ## 313 | 314 | getmetatable( val ) ==> table/nil 315 | val: any 316 | 317 | If the given value has a metatable with a `__metatable` field, this 318 | function returns the value of this field, otherwise it returns the 319 | metatable itself (or nil if there is no metatable). 320 | 321 | ### Examples ### 322 | 323 | > =getmetatable( "" ).__index == string 324 | true 325 | > =getmetatable( io.stdin ) 326 | table: ... 327 | > =getmetatable( {} ) 328 | nil 329 | ]=] .. _G.getmetatable 330 | end 331 | 332 | if check( _G, "ipairs", V >= 5.1 and V < 5.2 ) then 333 | A = annotate[=[ 334 | ## The `ipairs` Function ## 335 | 336 | ipairs( table ) ==> function, (any, any?)? 337 | 338 | This function returns a for-loop iterator tuple that iterates (in 339 | order) over the integer keys (and corresponding values) in the given 340 | table starting at index `1` until the first `nil` value is 341 | encountered. 342 | 343 | ### Examples ### 344 | 345 | > for i,v in ipairs( { 1, 2, 3, nil, 5 } ) do print( i, v ) end 346 | 1 1 347 | 2 2 348 | 3 3 349 | ]=] .. _G.ipairs 350 | if A ~= _G.ipairs then _G.ipairs = A end 351 | end 352 | 353 | if check( _G, "ipairs", 5.2 ) then 354 | A = annotate[=[ 355 | ## The `ipairs` Function ## 356 | 357 | ipairs( val ) ==> function, (any, any?)? 358 | val: any 359 | 360 | If the given value has a metatable with a `__ipairs` field, this 361 | function calls the `__ipairs` field to get a for-loop iterator tuple. 362 | If there is no `__ipairs` metafield (in which case `val` must be a 363 | table), this function returns a for-loop iterator tuple that iterates 364 | (in order) over the integer keys (and corresponding values) in the 365 | given table starting at index `1` until the first `nil` value is 366 | encountered. 367 | 368 | ### Examples ### 369 | 370 | > for i,v in ipairs( { 1, 2, 3, nil, 5 } ) do print( i, v ) end 371 | 1 1 372 | 2 2 373 | 3 3 374 | > getmetatable( "" ).__ipairs = function( s ) 375 | >> return function( st, i ) 376 | >> i = i + 1 377 | >> if i <= #st then 378 | >> return i, st:sub( i, i ) 379 | >> end 380 | >> end, s, 0 381 | >> end 382 | > for i,c in ipairs( "abc" ) do print( i, c ) end 383 | 1 a 384 | 2 b 385 | 3 c 386 | ]=] .. _G.ipairs 387 | if A ~= _G.ipairs then _G.ipairs = A end 388 | end 389 | 390 | if check( _G, "load", V >= 5.1 and V < 5.2 ) then 391 | A = annotate[=[ 392 | ## The `load` Function ## 393 | 394 | load( func [, chunkname] ) ==> function -- on success 395 | ==> nil, string -- in case of error 396 | func : function -- function to produce Lua code 397 | chunkname: string -- name to use in error messages 398 | ]=] .. _G.load 399 | if A ~= _G.load then _G.load = A end 400 | end 401 | 402 | if check( _G, "load", 5.2 ) then 403 | A = annotate[=[ 404 | ## The `load` Function ## 405 | 406 | load( ld [, source [, mode [, env]]] ) ==> function -- success 407 | ==> nil, string -- error 408 | ld : function/string -- (function producing) Lua code 409 | source: string -- name of the chunk for messages 410 | mode : string -- allow text/binary Lua code 411 | env : table -- the environment to load in 412 | ]=] .. _G.load 413 | if A ~= _G.load then _G.load = A end 414 | end 415 | 416 | if check( _G, "loadfile", V >= 5.1 and V < 5.2 ) then 417 | A = annotate[=[ 418 | ## The `loadfile` Function ## 419 | 420 | loadfile( [filename] ) ==> function -- on success 421 | ==> nil, string -- in case of error 422 | filename: string -- file name to load 423 | ]=] .. _G.loadfile 424 | if A ~= _G.loadfile then _G.loadfile = A end 425 | end 426 | 427 | if check( _G, "loadfile", 5.2 ) then 428 | A = annotate[=[ 429 | ## The `loadfile` Function ## 430 | 431 | loadfile( [filename [, mode [, env ]]] ) ==> function -- ok 432 | ==> nil, string -- error 433 | filename: string -- file name to load 434 | mode : string -- allow text/binary Lua code 435 | env : table -- the environment to load in 436 | ]=] .. _G.loadfile 437 | if A ~= _G.loadfile then _G.loadfile = A end 438 | end 439 | 440 | if check( _G, "loadstring", V >= 5.1 and V < 5.2 ) then 441 | A = annotate[=[ 442 | ## The `loadstring` Function ## 443 | 444 | loadstring( string [, chunkname] ) ==> function -- on success 445 | ==> nil, string -- on error 446 | chunkname: string -- name used in error messages 447 | ]=] .. _G.loadstring 448 | if A ~= _G.loadstring then _G.loadstring = A end 449 | end 450 | 451 | if check( _G, "module", V >= 5.1 and V < 5.3 ) then 452 | A = annotate[=[ 453 | ## The `module` Function ## 454 | 455 | module( name [, ...] ) 456 | name: string -- the module name as passed to require 457 | ... : function* -- options/modifiers for the module 458 | ]=] .. _G.module 459 | if A ~= _G.module then _G.module = A end 460 | end 461 | 462 | if check( _G, "next", 5.1 ) then 463 | A = annotate[=[ 464 | ## The `next` Function ## 465 | 466 | next( table [, index] ) ==> any, any? 467 | index: any -- current key in table, defaults to nil 468 | ]=] .. _G.next 469 | if A ~= _G.next then _G.next = A end 470 | end 471 | 472 | if check( _G, "pairs", V >= 5.1 and V < 5.2 ) then 473 | A = annotate[=[ 474 | ## The `pairs` Function ## 475 | 476 | pairs( table ) ==> function, (any, any?)? 477 | ]=] .. _G.pairs 478 | if A ~= _G.pairs then _G.pairs = A end 479 | end 480 | 481 | if check( _G, "pairs", 5.2 ) then 482 | A = annotate[=[ 483 | ## The `pairs` Function ## 484 | 485 | pairs( object ) ==> function, (any, any?)? 486 | ]=] .. _G.pairs 487 | if A ~= _G.pairs then _G.pairs = A end 488 | end 489 | 490 | if check( _G, "pcall", 5.1 ) then 491 | A = annotate[=[ 492 | ## The `pcall` Function ## 493 | 494 | pcall( function, ... ) ==> boolean, any* 495 | ...: any* -- arguments for the function 496 | ]=] .. _G.pcall 497 | if A ~= _G.pcall then _G.pcall = A end 498 | end 499 | 500 | if check( _G, "print", 5.1 ) then 501 | A = annotate[=[ 502 | ## The `print` Function ## 503 | 504 | print( ... ) 505 | ...: any* -- values to print 506 | ]=] .. _G.print 507 | if A ~= _G.print then _G.print = A end 508 | end 509 | 510 | if check( _G, "rawequal", 5.1 ) then 511 | A = annotate[=[ 512 | ## The `rawequal` Function ## 513 | 514 | rawequal( v1, v2 ) ==> boolean 515 | v1: any 516 | v2: any 517 | ]=] .. _G.rawequal 518 | if A ~= _G.rawequal then _G.rawequal = A end 519 | end 520 | 521 | if check( _G, "rawget", 5.1 ) then 522 | A = annotate[=[ 523 | ## The `rawget` Function ## 524 | 525 | rawget( table, index ) ==> any 526 | index: any -- key to query table for 527 | ]=] .. _G.rawget 528 | if A ~= _G.rawget then _G.rawget = A end 529 | end 530 | 531 | if check( _G, "rawlen", 5.2 ) then 532 | A = annotate[=[ 533 | ## The `rawlen` Function ## 534 | 535 | rawlen( v ) ==> integer 536 | v: string/table 537 | ]=] .. _G.rawlen 538 | if A ~= _G.rawlen then _G.rawlen = A end 539 | end 540 | 541 | if check( _G, "rawset", 5.1 ) then 542 | A = annotate[=[ 543 | ## The `rawset` Function ## 544 | 545 | rawset( table, index, value ) 546 | index: any -- key to use 547 | value: any -- value to add to the table 548 | ]=] .. _G.rawset 549 | if A ~= _G.rawset then _G.rawset = A end 550 | end 551 | 552 | if check( _G, "require", 5.1 ) then 553 | A = annotate[=[ 554 | ## The `require` Function ## 555 | 556 | require( modname ) ==> any 557 | modname: string -- the name of the module to load 558 | ]=] .. _G.require 559 | if A ~= _G.require then _G.require = A end 560 | end 561 | 562 | if check( _G, "select", 5.1 ) then 563 | A = annotate[=[ 564 | ## The `select` Function ## 565 | 566 | select( index, ... ) ==> any* 567 | index: string/integer -- index to select or `"#"` 568 | ... : any* -- varargs 569 | ]=] .. _G.select 570 | if A ~= _G.select then _G.select = A end 571 | end 572 | 573 | if check( _G, "setfenv", V >= 5.1 and V < 5.2 ) then 574 | A = annotate[=[ 575 | ## The `setfenv` Function ## 576 | 577 | setfenv( f, table ) ==> function? 578 | f: function/integer -- (stack level of) function to modify 579 | 580 | ### Examples ### 581 | 582 | > function p() print( "hello world" ) end 583 | > function f() x() end 584 | > setfenv( f, { x = p } ) 585 | > f() 586 | hello world 587 | ]=] .. _G.setfenv 588 | if A ~= _G.setfenv then _G.setfenv = A end 589 | end 590 | 591 | if check( _G, "setmetatable", 5.1 ) then 592 | A = annotate[=[ 593 | ## The `setmetatable` Function ## 594 | 595 | setmetatable( table, metatable ) ==> table 596 | metatable: table/nil -- table to use as a metatable 597 | ]=] .. _G.setmetatable 598 | if A ~= _G.setmetatable then _G.setmetatable = A end 599 | end 600 | 601 | if check( _G, "tonumber", 5.1 ) then 602 | A = annotate[=[ 603 | ## The `tonumber` Function ## 604 | 605 | tonumber( v [, base] ) ==> number/nil 606 | v : any -- value to convert 607 | base: integer -- base for conversion if not decimal 608 | ]=] .. _G.tonumber 609 | if A ~= _G.tonumber then _G.tonumber = A end 610 | end 611 | 612 | if check( _G, "tostring", 5.1 ) then 613 | A = annotate[=[ 614 | ## The `tostring` Function ## 615 | 616 | tostring( any ) ==> string 617 | ]=] .. _G.tostring 618 | if A ~= _G.tostring then _G.tostring = A end 619 | end 620 | 621 | if check( _G, "type", 5.1 ) then 622 | A = annotate[=[ 623 | ## The `type` Function ## 624 | 625 | type( any ) ==> string 626 | ]=] .. _G.type 627 | if A ~= _G.type then _G.type = A end 628 | end 629 | 630 | if check( _G, "unpack", V >= 5.1 and V < 5.2 ) then 631 | A = annotate[=[ 632 | ## The `unpack` Function ## 633 | 634 | unpack( list [, i [, j]] ) ==> any* 635 | list: table -- an array 636 | i : integer -- optional start index, defaults to 1 637 | j : integer -- optional end index, defaults to #list 638 | 639 | The `unpack` function returns the elements of the array separately. An 640 | optional start as well as end index can be specified. The start index 641 | defaults to `1`, the end index to the length of the array as 642 | determined by the length operator `#`. The array may contain holes, 643 | but in this case explicit start and end indices must be given. 644 | 645 | ### Examples ### 646 | 647 | > =unpack( { 1, 2, 3, 4 } ) 648 | 1 2 3 4 649 | > =unpack( { 1, 2, 3, 4 }, 2 ) 650 | 2 3 4 651 | > =unpack( { 1, 2, 3 }, 2, 3 ) 652 | 2 3 653 | > =unpack( { 1, nil, nil, 4 }, 1, 4 ) 654 | 1 nil nil 4 655 | ]=] .. _G.unpack 656 | if A ~= _G.unpack then _G.unpack = A end 657 | end 658 | 659 | if check( _G, "xpcall", V >= 5.1 and V < 5.2 ) then 660 | A = annotate[=[ 661 | ## The `xpcall` Function ## 662 | 663 | xpcall( function, err ) ==> boolean, any* 664 | err: function -- error handler (for producing stack traces) 665 | ]=] .. _G.xpcall 666 | if A ~= _G.xpcall then _G.xpcall = A end 667 | end 668 | 669 | if check( _G, "xpcall", 5.2 ) then 670 | A = annotate[=[ 671 | ## The `xpcall` Function ## 672 | 673 | xpcall( function, err, ... ) ==> boolean, any* 674 | err: function -- error handler (for producing stack traces) 675 | ...: any* -- arguments for the function 676 | ]=] .. _G.xpcall 677 | if A ~= _G.xpcall then _G.xpcall = A end 678 | end 679 | 680 | ---------------------------------------------------------------------- 681 | -- bit32 library 682 | 683 | if check( _G, "bit32", 5.2 ) then 684 | A = annotate[=[ 685 | ## Bitwise Operations ## 686 | 687 | The following functions are provided by Lua's `bit32` library: 688 | 689 | * `bit32.arshift` -- Arithmetic bit-shift to the right. 690 | * `bit32.band` -- Perform bitwise and operation. 691 | * `bit32.bnot` -- Perform bitwise not operation. 692 | * `bit32.bor` -- Perform bitwise or operation. 693 | * `bit32.btest` -- Test if all arguments have a 1-bit in common. 694 | * `bit32.bxor` -- Perform bitwise exclusive or operation. 695 | * `bit32.extract` -- Extract a sub-range of bits. 696 | * `bit32.lrotate` -- Left bit-shift (bits re-enter on the right). 697 | * `bit32.lshift` -- Bit-shift to the left. 698 | * `bit32.replace` -- Replace a sub-range of bits. 699 | * `bit32.rrotate` -- Right bit-shift (bits re-enter on the left). 700 | * `bit32.rshift` -- Normal bit-shift to the right. 701 | ]=] .. bit32 702 | assert( A == bit32, "bit32 table modified by annotate plugin" ) 703 | end 704 | 705 | if check( bit32, "arshift", 5.2 ) then 706 | A = annotate[=[ 707 | ## The `bit32.arshift` Function ## 708 | 709 | bit32.arshift( number, disp ) ==> integer 710 | disp: integer -- number of bits to shift 711 | 712 | Right-shifts (from highest-order bit to lowest-order bit) the given 713 | number by `disp` bits and returns the result. Inserts ones at the 714 | position of the highest order bit if the highest order bit was set, 715 | and zeros otherwise. If `disp` is negative, the function performs a 716 | left-shift inserting zeros at the lowest-order bit position. 717 | 718 | ### Examples ### 719 | 720 | > =bit32.arshift( 4, 1 ) 721 | 2 722 | > =bit32.arshift( 2, -2 ) 723 | 8 724 | > =bit32.arshift( 4294967295, -1 ) 725 | 4294967294 726 | > =bit32.arshift( 4294967295, 3 ) 727 | 4294967295 728 | ]=] .. bit32.arshift 729 | if A ~= bit32.arshift then bit32.arshift = A end 730 | end 731 | 732 | if check( bit32, "band", 5.2 ) then 733 | A = annotate[=[ 734 | ## The `bit32.band` Function ## 735 | 736 | bit32.band( ... ) ==> integer 737 | ...: number* 738 | 739 | This function performs a binary `and` on all given numbers and returns 740 | the result. If no number is given, `4294967295` is returned. 741 | 742 | ### Examples ### 743 | 744 | > =bit32.band() 745 | 4294967295 746 | > =bit32.band( 8 ) 747 | 8 748 | > =bit32.band( 7, 3, 2 ) 749 | 2 750 | ]=] .. bit32.band 751 | if A ~= bit32.band then bit32.band = A end 752 | end 753 | 754 | if check( bit32, "bnot", 5.2 ) then 755 | A = annotate[=[ 756 | ## The `bit32.bnot` Function ## 757 | 758 | bit32.bnot( number ) ==> integer 759 | 760 | This function inverts all bits in the given number and returns the 761 | result. 762 | 763 | ### Examples ### 764 | 765 | > =bit32.bnot( 2^32-1 ) 766 | 0 767 | > =bit32.bnot( 0 ) 768 | 4294967295 769 | > =bit32.bnot( 1 ) 770 | 4294967294 771 | ]=] .. bit32.bnot 772 | if A ~= bit32.bnot then bit32.bnot = A end 773 | end 774 | 775 | if check( bit32, "bor", 5.2 ) then 776 | A = annotate[=[ 777 | ## The `bit32.bor` Function ## 778 | 779 | bit32.bor( ... ) ==> integer 780 | ...: number* 781 | 782 | This function performs a bitwise `or` on its arguments and returns the 783 | resulting number. If no number is given, `0` is returned. 784 | 785 | ### Examples ### 786 | 787 | > =bit32.bor() 788 | 0 789 | > =bit32.bor( 8 ) 790 | 8 791 | > =bit32.bor( 1, 2, 4 ) 792 | 7 793 | ]=] .. bit32.bor 794 | if A ~= bit32.bor then bit32.bor = A end 795 | end 796 | 797 | if check( bit32, "btest", 5.2 ) then 798 | A = annotate[=[ 799 | ## The `bit32.btest` Function ## 800 | 801 | bit32.btest( ... ) ==> boolean 802 | ...: number* 803 | 804 | The `bit32.btest` function checks whether its arguments have a 1-bit 805 | in common (i.e. if the bitwise and of its arguments is non-zero). It 806 | returns true in this case (or if there are no arguments) and false 807 | otherwise. 808 | 809 | ### Examples ### 810 | 811 | > =bit32.btest( 1, 2, 4, 8, 16, 32, 64, 128, 256 ) 812 | false 813 | > =bit32.btest( 1, 3, 5, 9, 17, 33, 65, 129, 257 ) 814 | true 815 | > =bit32.btest() 816 | true 817 | ]=] .. bit32.btest 818 | if A ~= bit32.btest then bit32.btest = A end 819 | end 820 | 821 | if check( bit32, "bxor", 5.2 ) then 822 | A = annotate[=[ 823 | ## The `bit32.bxor` Function ## 824 | 825 | bit32.bxor( ... ) ==> integer 826 | ...: number* 827 | 828 | This function performs a binary `exclusive or` an its arguments and 829 | returns the resulting number. If no number is given, `0` is returned. 830 | 831 | ### Examples ### 832 | 833 | > =bit32.bxor() 834 | 0 835 | > =bit32.bxor( 8 ) 836 | 8 837 | > =bit32.bxor( 7, 3, 5 ) 838 | 1 839 | ]=] .. bit32.bxor 840 | if A ~= bit32.bxor then bit32.bxor = A end 841 | end 842 | 843 | if check( bit32, "extract", 5.2 ) then 844 | A = annotate[=[ 845 | ## The `bit32.extract` Function ## 846 | 847 | bit32.extract( number, index [, width] ) ==> integer 848 | index: integer -- starting index of bits to extract 849 | width: integer -- number of bits in field, default is 1 850 | 851 | This function extracts an contiguous subset of bits from the given 852 | number and returns it as an unsigned number. The starting index 853 | `index` may be in the range of `0` (least significant bit) to `31` 854 | (most significant bit). The end index `index+width-1` must be in the 855 | same range. 856 | 857 | ### Examples ### 858 | 859 | > =bit32.extract( 7, 0, 2 ) 860 | 3 861 | > =bit32.extract( 5, 1, 2 ) 862 | 2 863 | > =bit32.extract( 2^31, 31 ) 864 | 1 865 | ]=] .. bit32.extract 866 | if A ~= bit32.extract then bit32.extract = A end 867 | end 868 | 869 | if check( bit32, "lrotate", 5.2 ) then 870 | A = annotate[=[ 871 | ## The `bit32.lrotate` Function ## 872 | 873 | bit32.lrotate( number, disp ) ==> integer 874 | disp: integer -- number of bits to shift 875 | 876 | Shifts the bits in the given number `disp` positions to the left (in 877 | the direction of the most significant bit), reinserting the overflow 878 | bits at the position of the least significant bit (at the right). 879 | Negative values for `disp` shift to the right, reinserting at the 880 | left. 881 | 882 | ### Examples ### 883 | 884 | > =bit32.lrotate( 2^31, 1 ) 885 | 1 886 | > =bit32.lrotate( 2, -1 ) 887 | 1 888 | > =bit32.lrotate( 3, 2 ) 889 | 12 890 | ]=] .. bit32.lrotate 891 | if A ~= bit32.lrotate then bit32.lrotate = A end 892 | end 893 | 894 | if check( bit32, "lshift", 5.2 ) then 895 | A = annotate[=[ 896 | ## The `bit32.lshift` Function ## 897 | 898 | bit32.lshift( number, disp ) ==> integer 899 | disp: integer -- number of bits to shift 900 | 901 | Shifts the bits in the given number `disp` positions to the left (in 902 | the direction of the most significant bit), inserting `0` bits at the 903 | right (position of least significant bit). Negative values for `disp` 904 | shift to the right, inserting `0` at the left. 905 | 906 | ### Examples ### 907 | 908 | > =bit32.lshift( 2^31, 1 ) 909 | 0 910 | > =bit32.lshift( 2, -1 ) 911 | 1 912 | > =bit32.lshift( 3, 2 ) 913 | 12 914 | ]=] .. bit32.lshift 915 | if A ~= bit32.lshift then bit32.lshift = A end 916 | end 917 | 918 | if check( bit32, "replace", 5.2 ) then 919 | A = annotate[=[ 920 | ## The `bit32.replace` Function ## 921 | 922 | bit32.replace( number, v, index [, width] ) ==> integer 923 | v : number -- replacement value for the bit field 924 | index: integer -- starting index of bits to replace 925 | width: integer -- number of bits to replace, default is 1 926 | 927 | This function replaces a contiguous subset of bit in the given number 928 | with an equal amount of bits from the number `v` and returns the 929 | result. The starting index `index` and end index `index+width-1` must 930 | be in the range of `0` (least significant bit) to `31` (most 931 | significant bit). The replacement bit field is always taken starting 932 | at the least significant bit. 933 | 934 | ### Examples ### 935 | 936 | > =bit32.replace( 15, 0, 0 ) 937 | 14 938 | > =bit32.replace( 15, 0, 2, 2 ) 939 | 3 940 | > =bit32.replace( 0, 1, 31 ) 941 | 2147483648 942 | ]=] .. bit32.replace 943 | if A ~= bit32.replace then bit32.replace = A end 944 | end 945 | 946 | if check( bit32, "rrotate", 5.2 ) then 947 | A = annotate[=[ 948 | ## The `bit32.rrotate` Function ## 949 | 950 | bit32.rrotate( number, disp ) ==> integer 951 | disp: integer -- number of bits to shift 952 | 953 | Shifts the bits in the given number `disp` positions to the right (in 954 | the direction of the least significant bit), reinserting the overflow 955 | bits at the position of the most significant bit (at the left). 956 | Negative values for `disp` shift to the left, reinserting at the 957 | right. 958 | 959 | ### Examples ### 960 | 961 | > =bit32.rrotate( 1, 1 ) 962 | 2147483648 963 | > =bit32.rrotate( 12, 2 ) 964 | 3 965 | > =bit32.rrotate( 1, -1 ) 966 | 2 967 | ]=] .. bit32.rrotate 968 | if A ~= bit32.rrotate then bit32.rrotate = A end 969 | end 970 | 971 | if check( bit32, "rshift", 5.2 ) then 972 | A = annotate[=[ 973 | ## The `bit32.rshift` Function ## 974 | 975 | bit32.rshift( number, disp ) ==> integer 976 | disp: integer -- number of bits to shift 977 | 978 | Shifts the bits in the given number `disp` positions to the right (in 979 | the direction of the least significant bit), inserting `0` bits at the 980 | left (position of most significant bit). Negative values for `disp` 981 | shift to the left, inserting `0` at the right. 982 | 983 | ### Examples ### 984 | 985 | > =bit32.rshift( 2, 2 ) 986 | 0 987 | > =bit32.rshift( 1, -1 ) 988 | 2 989 | > =bit32.rshift( 12, 2 ) 990 | 3 991 | ]=] .. bit32.rshift 992 | if A ~= bit32.rshift then bit32.rshift = A end 993 | end 994 | 995 | ---------------------------------------------------------------------- 996 | -- coroutine library 997 | 998 | if check( _G, "coroutine", 5.1 ) then 999 | A = annotate[=[ 1000 | ## Coroutine Manipulation ## 1001 | 1002 | The `coroutine` table, which is part of Lua's base library, contains 1003 | the following functions: 1004 | 1005 | * `coroutine.create` -- Create new coroutines. 1006 | * `coroutine.resume` -- Resume coroutine where it last `yield`ed. 1007 | * `coroutine.running` -- Get currently running coroutine. 1008 | * `coroutine.status` -- Query status of a coroutine value. 1009 | * `coroutine.wrap` -- Create coroutines, disguise them as functions. 1010 | * `coroutine.yield` -- Suspend execution of current coroutine. 1011 | ]=] .. coroutine 1012 | assert( A == coroutine, "coroutine table modified by annotate plugin" ) 1013 | end 1014 | 1015 | if check( coroutine, "create", 5.1 ) then 1016 | A = annotate[=[ 1017 | ## The `coroutine.create` Function ## 1018 | 1019 | coroutine.create( function ) ==> thread 1020 | 1021 | This function creates and returns a new coroutine which, when resumed, 1022 | executes the given function. 1023 | 1024 | ### Examples ### 1025 | 1026 | > co = coroutine.create( function() print( "xy" ) end ) 1027 | > =co 1028 | thread: ... 1029 | > coroutine.resume( co ) 1030 | xy 1031 | ]=] .. coroutine.create 1032 | if A ~= coroutine.create then coroutine.create = A end 1033 | end 1034 | 1035 | if check( coroutine, "resume", 5.1 ) then 1036 | A = annotate[=[ 1037 | ## The `coroutine.resume` Function ## 1038 | 1039 | coroutine.resume( thread, ... ) ==> boolean, any* 1040 | ...: any* -- arguments passed to the thread 1041 | 1042 | This function starts or continues the given coroutine which must be in 1043 | a suspended state. All extra arguments given to `coroutine.resume` are 1044 | passed to the coroutine via arguments to the coroutine body (if the 1045 | coroutine has never been resumed before), or as return values of the 1046 | previous call to `coroutine.yield` (if the coroutine yielded before). 1047 | The first return value of `coroutine.resume` indicates whether the 1048 | coroutine executed normally (`true`), or raised an error (`false`). 1049 | In case of an error, the error messages is passed as the second return 1050 | value. In case of successful execution, the extra return values are 1051 | the arguments passed to the last `coroutine.yield` call inside the 1052 | resumed coroutine. 1053 | 1054 | ### Examples ### 1055 | 1056 | > co1 = coroutine.create( function( a, b ) 1057 | >> while true do 1058 | >> print( a, b ) 1059 | >> a = coroutine.yield( a ) 1060 | >> end 1061 | >> end ) 1062 | > =coroutine.resume( co1, 1, 1 ) 1063 | 1 1 1064 | true 1 1065 | > =coroutine.resume( co1, 2, 2 ) 1066 | 2 1 1067 | true 2 1068 | > co2 = coroutine.create( function() error( "argh" ) end ) 1069 | > =coroutine.resume( co2 ) 1070 | false ...argh 1071 | 1072 | 1073 | ]=] .. coroutine.resume 1074 | if A ~= coroutine.resume then coroutine.resume = A end 1075 | end 1076 | 1077 | if check( coroutine, "running", V >= 5.1 and V < 5.2 ) then 1078 | A = annotate[=[ 1079 | ## The `coroutine.running` Function ## 1080 | 1081 | coroutine.running() ==> thread/nil 1082 | 1083 | When this function is called from within a resumed coroutine, it 1084 | returns this coroutine. Otherwise it returns nil. 1085 | 1086 | ### Examples ### 1087 | 1088 | > =coroutine.wrap( function() return coroutine.running() end )() 1089 | thread: ... 1090 | > =coroutine.running() 1091 | nil 1092 | ]=] .. coroutine.running 1093 | if A ~= coroutine.running then coroutine.running = A end 1094 | end 1095 | 1096 | if check( coroutine, "running", 5.2 ) then 1097 | A = annotate[=[ 1098 | ## The `coroutine.running` Function ## 1099 | 1100 | coroutine.running() ==> thread, boolean 1101 | 1102 | This function returns the currently resumed coroutine and a boolean, 1103 | which indicates whether the coroutine is the main coroutine (`true`) 1104 | or a coroutine created during the execution of the program (`false`). 1105 | 1106 | ### Examples ### 1107 | 1108 | > =coroutine.wrap( function() return coroutine.running() end )() 1109 | thread: ... false 1110 | > =coroutine.running() 1111 | thread: ... true 1112 | ]=] .. coroutine.running 1113 | if A ~= coroutine.running then coroutine.running = A end 1114 | end 1115 | 1116 | if check( coroutine, "status", 5.1 ) then 1117 | A = annotate[=[ 1118 | ## The `coroutine.status` Function ## 1119 | 1120 | coroutine.status( thread ) ==> string 1121 | 1122 | This function returns the current status of the given coroutine as a 1123 | string, which can be "running", "suspended", "normal", or "dead". A 1124 | coroutine is "dead", if it has returned from its body or raised an 1125 | error. A coroutine is "suspended", if it isn't dead, and hasn't 1126 | yielded, or if it hasn't been resumed yet. A coroutine is "running" if 1127 | it is not dead or suspended, and has not resumed another coroutine. A 1128 | coroutine that resumes another coroutine has "normal" status. 1129 | 1130 | ### Examples ### 1131 | 1132 | > co1 = coroutine.create( function() 1133 | >> print( "[co1] co2 is", coroutine.status( co2 ) ) 1134 | >> end ) 1135 | > co2 = coroutine.create( function() 1136 | >> print( "[co2] co2 is", coroutine.status( co2 ) ) 1137 | >> coroutine.yield() 1138 | >> coroutine.resume( co1 ) 1139 | >> end ) 1140 | > =coroutine.status( co2 ) 1141 | suspended 1142 | > coroutine.resume( co2 ) 1143 | [co2] co2 is running 1144 | > =coroutine.status( co2 ) 1145 | suspended 1146 | > coroutine.resume( co2 ) 1147 | [co1] co2 is normal 1148 | > =coroutine.status( co2 ) 1149 | dead 1150 | 1151 | ]=] .. coroutine.status 1152 | if A ~= coroutine.status then coroutine.status = A end 1153 | end 1154 | 1155 | if check( coroutine, "wrap", 5.1 ) then 1156 | A = annotate[=[ 1157 | ## The `coroutine.wrap` Function ## 1158 | 1159 | coroutine.wrap( function ) ==> function 1160 | 1161 | This function creates a new coroutine and returns a wrapper function 1162 | that, when called, resumes the couroutine which in turn calls the 1163 | function passed as argument to `coroutine.wrap`. All arguments of the 1164 | wrapper function call are passed to `coroutine.resume`. 1165 | 1166 | ### Examples ### 1167 | 1168 | > co = coroutine.wrap( function( ... ) 1169 | >> local n, a, b = 0, ... 1170 | >> while true do 1171 | >> n = n + 1 1172 | >> print( n, a, b ) 1173 | >> a, b = coroutine.yield() 1174 | >> end 1175 | >> end ) 1176 | > co( "a", "b" ) 1177 | 1 a b 1178 | > co( "c", "d" ) 1179 | 2 c d 1180 | ]=] .. coroutine.wrap 1181 | if A ~= coroutine.wrap then coroutine.wrap = A end 1182 | end 1183 | 1184 | if check( coroutine, "yield", 5.1 ) then 1185 | A = annotate[=[ 1186 | ## The `coroutine.yield` Function ## 1187 | 1188 | coroutine.yield( ... ) ==> any* 1189 | ...: any* -- arguments passed to resume 1190 | 1191 | When called from inside a running coroutine, this function suspends 1192 | the coroutine and returns execution to the last `coroutine.resume` 1193 | call that activated the coroutine. All arguments to `coroutine.yield` 1194 | are passed as return values of this `coroutine.resume` call. When 1195 | activated again, the execution of the coroutine continues with the 1196 | return from the `coroutine.yield` call, which passes all extra 1197 | arguments of the last `coroutine.resume` as return values. 1198 | 1199 | ### Examples ### 1200 | 1201 | > co = coroutine.create( function() 1202 | >> print( "resuming after yield 1", coroutine.yield( 1 ) ) 1203 | >> print( "resuming after yield 2", coroutine.yield( 2 ) ) 1204 | >> end ) 1205 | > =coroutine.resume( co ) 1206 | true 1 1207 | > =coroutine.resume( co, "a" ) 1208 | resuming after yield 1 a 1209 | true 2 1210 | > =coroutine.resume( co, "b" ) 1211 | resuming after yield 2 b 1212 | true 1213 | ]=] .. coroutine.yield 1214 | if A ~= coroutine.yield then coroutine.yield = A end 1215 | end 1216 | 1217 | ---------------------------------------------------------------------- 1218 | -- debug library 1219 | 1220 | if check( _G, "debug", V >= 5.1 and V < 5.2 ) then 1221 | A = annotate[=[ 1222 | ## The Debug Library ## 1223 | 1224 | Lua's `debug` library provides the following functions: 1225 | 1226 | * `debug.debug` -- Start a simple interactive prompt for debugging. 1227 | * `debug.getfenv` -- Get environment for function or userdata. 1228 | * `debug.gethook` -- Get current hook settings of a thread. 1229 | * `debug.getinfo` -- Get general information about a function. 1230 | * `debug.getlocal` -- Get name and value of a local variable. 1231 | * `debug.getmetatable` -- Get metatable for any Lua object. 1232 | * `debug.getregistry` -- Get reference to the Lua registry. 1233 | * `debug.getupvalue` -- Get name and value of a function's upvalue. 1234 | * `debug.setfenv` -- Set environment for function or userdata. 1235 | * `debug.sethook` -- Register hook function for Lua code. 1236 | * `debug.setlocal` -- Set the value of a local variable. 1237 | * `debug.setmetatable` -- Set metatable on any Lua object. 1238 | * `debug.setupvalue` -- Set the value of an upvalue for a function. 1239 | * `debug.traceback` -- Traceback generator for `xpcall` 1240 | ]=] .. debug 1241 | assert( A == debug, "debug table modified by annotate plugin" ) 1242 | elseif check( _G, "debug", 5.2 ) then 1243 | A = annotate[=[ 1244 | ## The Debug Library ## 1245 | 1246 | Lua's `debug` library provides the following functions: 1247 | 1248 | * `debug.debug` -- Start a simple interactive prompt for debugging. 1249 | * `debug.gethook` -- Get current hook settings of a thread. 1250 | * `debug.getinfo` -- Get general information about a function. 1251 | * `debug.getlocal` -- Get name and value of a local variable. 1252 | * `debug.getmetatable` -- Get metatable for any Lua object. 1253 | * `debug.getregistry` -- Get reference to the Lua registry. 1254 | * `debug.getupvalue` -- Get name and value of a function's upvalue. 1255 | * `debug.getuservalue` -- Get the value associated with a userdata. 1256 | * `debug.sethook` -- Register hook function for Lua code. 1257 | * `debug.setlocal` -- Set the value of a local variable. 1258 | * `debug.setmetatable` -- Set metatable on any Lua object. 1259 | * `debug.setupvalue` -- Set the value of an upvalue for a function. 1260 | * `debug.setuservalue` -- Associate a value with a userdata. 1261 | * `debug.traceback` -- Traceback generator for `xpcall` 1262 | * `debug.upvalueid` -- Uniquely identify an upvalue. 1263 | * `debug.upvaluejoin` -- Make upvalue of function refer to another. 1264 | ]=] .. debug 1265 | assert( A == debug, "debug table modified by annotate plugin" ) 1266 | end 1267 | 1268 | if check( debug, "debug", 5.1 ) then 1269 | A = annotate[=[ 1270 | ## The `debug.debug` Function ## 1271 | 1272 | debug.debug() 1273 | ]=] .. debug.debug 1274 | if A ~= debug.debug then debug.debug = A end 1275 | end 1276 | 1277 | if check( debug, "getfenv", V >= 5.1 and V < 5.2 ) then 1278 | A = annotate[=[ 1279 | ## The `debug.getfenv` Function ## 1280 | 1281 | debug.getfenv( any ) ==> table/nil 1282 | ]=] .. debug.getfenv 1283 | if A ~= debug.getfenv then debug.getfenv = A end 1284 | end 1285 | 1286 | if check( debug, "gethook", 5.1 ) then 1287 | A = annotate[=[ 1288 | ## The `debug.gethook` Function ## 1289 | 1290 | debug.gethook( [thread] ) ==> function, string, integer 1291 | ]=] .. debug.gethook 1292 | if A ~= debug.gethook then debug.gethook = A end 1293 | end 1294 | 1295 | if check( debug, "getinfo", 5.1 ) then 1296 | A = annotate[=[ 1297 | ## The `debug.getinfo` Function ## 1298 | 1299 | debug.getinfo( [thread,] f [, what] ) ==> table/nil 1300 | f : function/integer -- a function or a stack level 1301 | what: string -- what fields to request 1302 | ]=] .. debug.getinfo 1303 | if A ~= debug.getinfo then debug.getinfo = A end 1304 | end 1305 | 1306 | if check( debug, "getlocal", V >= 5.1 and V < 5.2 ) then 1307 | A = annotate[=[ 1308 | ## The `debug.getlocal` Function ## 1309 | 1310 | debug.getlocal( [thread,] level, index ) ==> string, any 1311 | ==> nil 1312 | level: integer -- a stack level 1313 | index: integer -- index for the local at given stack level 1314 | ]=] .. debug.getlocal 1315 | if A ~= debug.getlocal then debug.getlocal = A end 1316 | end 1317 | 1318 | if check( debug, "getlocal", 5.2 ) then 1319 | A = annotate[=[ 1320 | ## The `debug.getlocal` Function ## 1321 | 1322 | debug.getlocal( [thread,] f, index ) ==> string, any? 1323 | ==> nil 1324 | f : function/integer -- a function or a stack level 1325 | index: integer -- index for local 1326 | ]=] .. debug.getlocal 1327 | if A ~= debug.getlocal then debug.getlocal = A end 1328 | end 1329 | 1330 | if check( debug, "getmetatable", 5.1 ) then 1331 | A = annotate[=[ 1332 | ## The `debug.getmetatable` Function ## 1333 | 1334 | debug.getmetatable( any ) ==> table/nil 1335 | ]=] .. debug.getmetatable 1336 | if A ~= debug.getmetatable then debug.getmetatable = A end 1337 | end 1338 | 1339 | if check( debug, "getregistry", 5.1 ) then 1340 | A = annotate[=[ 1341 | ## The `debug.getregistry` Function ## 1342 | 1343 | debug.getregistry() ==> table 1344 | ]=] .. debug.getregistry 1345 | if A ~= debug.getregistry then debug.getregistry = A end 1346 | end 1347 | 1348 | if check( debug, "getupvalue", 5.1 ) then 1349 | A = annotate[=[ 1350 | ## The `debug.getupvalue` Function ## 1351 | 1352 | debug.getupvalue( function, index ) ==> (string, any)? 1353 | index: integer -- index of the function's upvalue 1354 | ]=] .. debug.getupvalue 1355 | if A ~= debug.getupvalue then debug.getupvalue = A end 1356 | end 1357 | 1358 | if check( debug, "getuservalue", 5.2 ) then 1359 | A = annotate[=[ 1360 | ## The `debug.getuservalue` Function ## 1361 | 1362 | debug.getuservalue( any ) ==> table/nil 1363 | ]=] .. debug.getuservalue 1364 | if A ~= debug.getuservalue then debug.getuservalue = A end 1365 | end 1366 | 1367 | if check( debug, "setfenv", V >= 5.1 and V < 5.2 ) then 1368 | A = annotate[=[ 1369 | ## The `debug.setfenv` Function ## 1370 | 1371 | debug.setfenv( o, table ) ==> function/userdata 1372 | o: function/userdata 1373 | ]=] .. debug.setfenv 1374 | if A ~= debug.setfenv then debug.setfenv = A end 1375 | end 1376 | 1377 | if check( debug, "sethook", 5.1 ) then 1378 | A = annotate[=[ 1379 | ## The `debug.sethook` Function ## 1380 | 1381 | debug.sethook( [thread,] hookf, mask [, count] ) 1382 | hookf: function -- the hook function 1383 | mask : string -- when to call the hook function 1384 | count: integer -- number of instructions 1385 | ]=] .. debug.sethook 1386 | if A ~= debug.sethook then debug.sethook = A end 1387 | end 1388 | 1389 | if check( debug, "setlocal", 5.1 ) then 1390 | A = annotate[=[ 1391 | ## The `debug.setlocal` Function ## 1392 | 1393 | debug.setlocal( [thread,] level, index, value ) ==> string/nil 1394 | level: integer -- a stack level 1395 | index: integer -- index of the function's local 1396 | value: any -- value to set the local to 1397 | ]=] .. debug.setlocal 1398 | if A ~= debug.setlocal then debug.setlocal = A end 1399 | end 1400 | 1401 | if check( debug, "setmetatable", V >= 5.1 and V < 5.2 ) then 1402 | A = annotate[=[ 1403 | ## The `debug.setmetatable` Function ## 1404 | 1405 | debug.setmetatable( any, t ) ==> boolean 1406 | t: table/nil -- the metatable to set 1407 | ]=] .. debug.setmetatable 1408 | if A ~= debug.setmetatable then debug.setmetatable = A end 1409 | end 1410 | 1411 | if check( debug, "setmetatable", 5.2 ) then 1412 | A = annotate[=[ 1413 | ## The `debug.setmetatable` Function ## 1414 | 1415 | debug.setmetatable( any, t ) ==> any 1416 | t: table/nil -- the metatable to set 1417 | ]=] .. debug.setmetatable 1418 | if A ~= debug.setmetatable then debug.setmetatable = A end 1419 | end 1420 | 1421 | if check( debug, "setupvalue", 5.1 ) then 1422 | A = annotate[=[ 1423 | ## The `debug.setupvalue` Function ## 1424 | 1425 | debug.setupvalue( function, index, value ) ==> string? 1426 | index: integer -- index of the upvalue to set 1427 | value: any -- value to set the upvalue to 1428 | ]=] .. debug.setupvalue 1429 | if A ~= debug.setupvalue then debug.setupvalue = A end 1430 | end 1431 | 1432 | if check( debug, "setuservalue", 5.2 ) then 1433 | A = annotate[=[ 1434 | ## The `debug.setuservalue` Function ## 1435 | 1436 | debug.setuservalue( userdata [, value] ) ==> userdata 1437 | value: table/nil -- the uservalue to set 1438 | ]=] .. debug.setuservalue 1439 | if A ~= debug.setuservalue then debug.setuservalue = A end 1440 | end 1441 | 1442 | if check( debug, "traceback", 5.1 ) then 1443 | A = annotate[=[ 1444 | ## The ´debug.traceback` Function ## 1445 | 1446 | debug.traceback( [thread,] [message [, level]] ) ==> string 1447 | message: string -- prefix for stack trace 1448 | level : integer -- stack level where to start stack trace 1449 | ]=] .. debug.traceback 1450 | if A ~= debug.traceback then debug.traceback = A end 1451 | end 1452 | 1453 | if check( debug, "upvalueid", 5.2 ) then 1454 | A = annotate[=[ 1455 | ## The `debug.upvalueid` Function ## 1456 | 1457 | debug.upvalueid( function, index ) ==> userdata 1458 | index: integer -- index of the upvalue to query 1459 | ]=] .. debug.upvalueid 1460 | if A ~= debug.upvalueid then debug.upvalueid = A end 1461 | end 1462 | 1463 | if check( debug, "upvaluejoin", 5.2 ) then 1464 | A = annotate[=[ 1465 | ## The `debug.upvaluejoin` Function ## 1466 | 1467 | debug.upvaluejoin( f1, n1, f2, n2 ) 1468 | f1: function -- target closure 1469 | n1: integer -- index of upvalue to set 1470 | f2: function -- source closure 1471 | n2: integer -- index of upvalue used as source 1472 | ]=] .. debug.upvaluejoin 1473 | if A ~= debug.upvaluejoin then debug.upvaluejoin = A end 1474 | end 1475 | 1476 | ---------------------------------------------------------------------- 1477 | -- io library 1478 | 1479 | if check( _G, "io", 5.1 ) then 1480 | A = annotate[=[ 1481 | ## Input and Output Facilities ## 1482 | 1483 | Lua's `io` library contains the following fields/functions: 1484 | 1485 | * `io.close` -- Close a file or the default output stream. 1486 | * `io.flush` -- Flush buffers for the default output stream. 1487 | * `io.input` -- Get/Set the default input stream. 1488 | * `io.lines` -- Iterate over the lines of the given file. 1489 | * `io.open` -- Open a file for reading and/or writing. 1490 | * `io.output` -- Get/set the default output stream. 1491 | * `io.popen` -- Run program, read its output or write to its input. 1492 | * `io.read` -- Read from the default input stream. 1493 | * `io.stderr` -- File object for the standard error stream. 1494 | * `io.stdin` -- File object for the standard input stream. 1495 | * `io.stdout` -- File object for the standard output stream. 1496 | * `io.tmpfile` -- Get a handle for a temporary file. 1497 | * `io.type` -- Check if a value is a file object. 1498 | * `io.write` -- Write to the default output stream. 1499 | 1500 | Lua file handles have the following methods: 1501 | 1502 | * `file:close` -- Close the file object. 1503 | * `file:flush` -- Flush output buffers for the file object. 1504 | * `file:lines` -- Iterate over the lines of the given file object. 1505 | * `file:read` -- Read bytes/lines from the file object 1506 | * `file:seek` -- Set/get the file position where to read/write. 1507 | * `file:setvbuf` -- Set buffering mode for an output file object. 1508 | * `file:write` -- Write strings (or numbers) to a file object. 1509 | ]=] .. io 1510 | assert( A == io, "io table modified by annotate plugin" ) 1511 | end 1512 | 1513 | if check( io, "close", V >= 5.1 and V < 5.2 ) then 1514 | A = annotate[=[ 1515 | ## The `io.close` Function ## 1516 | 1517 | io.close( [file] ) ==> boolean -- on success 1518 | ==> nil, string, integer -- in case of error 1519 | ]=] .. io.close 1520 | if A ~= io.close then io.close = A end 1521 | end 1522 | 1523 | if check( io, "close", 5.2 ) then 1524 | A = annotate[=[ 1525 | ## The `io.close` Function ## 1526 | 1527 | io.close( [file] ) ==> boolean, (string, integer)? -- on success 1528 | ==> nil, string, integer -- on error 1529 | ]=] .. io.close 1530 | if A ~= io.close then io.close = A end 1531 | end 1532 | 1533 | if check( io, "flush", 5.1 ) then 1534 | A = annotate[=[ 1535 | ## The `io.flush` Function ## 1536 | 1537 | io.flush() ==> boolean -- on success 1538 | ==> nil, string, integer -- in case of error 1539 | ]=] .. io.flush 1540 | if A ~= io.flush then io.flush = A end 1541 | end 1542 | 1543 | if check( io, "input", 5.1 ) then 1544 | A = annotate[=[ 1545 | ## The `io.input` Function ## 1546 | 1547 | io.input( [f] ) ==> file? 1548 | f: file/string -- a file or file name 1549 | ]=] .. io.input 1550 | if A ~= io.input then io.input = A end 1551 | end 1552 | 1553 | if check( io, "lines", 5.1 ) then 1554 | A = annotate[=[ 1555 | ## The `io.lines` Function ## 1556 | 1557 | io.lines( [filename] ) ==> function, (any, any?)? 1558 | filename: string -- name of file to read 1559 | ]=] .. io.lines 1560 | if A ~= io.lines then io.lines = A end 1561 | end 1562 | 1563 | if check( io, "open", 5.1 ) then 1564 | A = annotate[=[ 1565 | ## The `io.open` Function ## 1566 | 1567 | io.open( filename [, mode] ) ==> file -- on success 1568 | ==> nil, string, integer -- on error 1569 | filename: string -- name of the file to open 1570 | mode : string -- open for reading/writing?, default is "r" 1571 | ]=] .. io.open 1572 | if A ~= io.open then io.open = A end 1573 | end 1574 | 1575 | if check( io, "output", 5.1 ) then 1576 | A = annotate[=[ 1577 | ## The `io.output` Function ## 1578 | 1579 | io.output( [f] ) ==> file? 1580 | f: file/string -- a file or file name 1581 | ]=] .. io.output 1582 | if A ~= io.output then io.output = A end 1583 | end 1584 | 1585 | if check( io, "popen", 5.1 ) then 1586 | A = annotate[=[ 1587 | ## The `io.popen` Function ## 1588 | 1589 | io.popen( prog [, mode] ) ==> file -- on success 1590 | ==> nil, string, integer -- on error 1591 | prog: string -- the command line of the program to run 1592 | mode: string -- read output from command or write intput 1593 | ]=] .. io.popen 1594 | if A ~= io.popen then io.popen = A end 1595 | end 1596 | 1597 | if check( io, "read", 5.1 ) then 1598 | A = annotate[=[ 1599 | ## The `io.read` Function ## 1600 | 1601 | io.read( ... ) ==> (string/number/nil)* 1602 | ...: string/number -- what to read from io.stdin() 1603 | ]=] .. io.read 1604 | if A ~= io.read then io.read = A end 1605 | end 1606 | 1607 | if check( io, "stderr", 5.1 ) then 1608 | A = annotate[=[ 1609 | ## The `io.stderr` File Object ## 1610 | 1611 | The `io.stderr` file object represents the `stderr` file stream of C 1612 | programs and is intended for error messages. Typically it is connected 1613 | to a console/terminal. 1614 | 1615 | It supports the following methods: 1616 | 1617 | * `file:close` -- Close the file object. 1618 | * `file:flush` -- Flush output buffers for the file object. 1619 | * (`file:seek` -- Set/get the file position where to read/write.) 1620 | * `file:setvbuf` -- Set buffering mode for an output file object. 1621 | * `file:write` -- Write strings (or numbers) to a file object. 1622 | 1623 | (The methods for input are available too, but make no sense for an 1624 | output file object.) 1625 | ]=] .. io.stderr 1626 | assert( A == io.stderr, "io.stderr modified by annotate plugin" ) 1627 | end 1628 | 1629 | if check( io, "stdin", 5.1 ) then 1630 | A = annotate[=[ 1631 | ## The `io.stdin` File Object ## 1632 | 1633 | The `io.stdin` file object represents the `stdin` file stream of C 1634 | programs and is intended for user input. Typically it is connected to 1635 | a console/terminal. 1636 | 1637 | It supports the following methods: 1638 | 1639 | * `file:close` -- Close the file object. 1640 | * `file:lines` -- Iterate over the lines of the given file object. 1641 | * `file:read` -- Read bytes/lines from the file object 1642 | * (`file:seek` -- Set/get the file position where to read/write.) 1643 | 1644 | (The methods for output are available too, but make no sense for an 1645 | input file object.) 1646 | ]=] .. io.stdin 1647 | assert( A == io.stdin, "io.stdin modified by annotate plugin" ) 1648 | end 1649 | 1650 | if check( io, "stdout", 5.1 ) then 1651 | A = annotate[=[ 1652 | ## The `io.stdout` File Object ## 1653 | 1654 | The `io.stdout` file object represents the `stdout` file stream of C 1655 | programs and is intended for normal program output. By default it is 1656 | connected to a console/terminal. 1657 | 1658 | It supports the following methods: 1659 | 1660 | * `file:close` -- Close the file object. 1661 | * `file:flush` -- Flush output buffers for the file object. 1662 | * (`file:seek` -- Set/get the file position where to read/write.) 1663 | * `file:setvbuf` -- Set buffering mode for an output file object. 1664 | * `file:write` -- Write strings (or numbers) to a file object. 1665 | 1666 | (The methods for input are available too, but make no sense for an 1667 | output file object.) 1668 | ]=] .. io.stdout 1669 | assert( A == io.stdout, "io.stdout modified by annotate plugin" ) 1670 | end 1671 | 1672 | if check( io, "tmpfile", 5.1 ) then 1673 | A = annotate[=[ 1674 | ## The `io.tmpfile` Function ## 1675 | 1676 | io.tmpfile() ==> file -- on success 1677 | ==> nil, string, integer -- in case of error 1678 | ]=] .. io.tmpfile 1679 | if A ~= io.tmpfile then io.tmpfile = A end 1680 | end 1681 | 1682 | if check( io, "type", 5.1 ) then 1683 | A = annotate[=[ 1684 | ## The `io.type` Function ## 1685 | 1686 | io.type( any ) ==> string/nil 1687 | ]=] .. io.type 1688 | if A ~= io.type then io.type = A end 1689 | end 1690 | 1691 | if check( io, "write", V >= 5.1 and V < 5.2 ) then 1692 | A = annotate[=[ 1693 | ## The `io.write` Function ## 1694 | 1695 | io.write( ... ) ==> boolean -- on success 1696 | ==> nil, string, integer -- in case of error 1697 | ...: (string/number)* -- values to write to io.output() 1698 | ]=] .. io.write 1699 | if A ~= io.write then io.write = A end 1700 | end 1701 | 1702 | if check( io, "write", 5.2 ) then 1703 | A = annotate[=[ 1704 | ## The `io.write` Function ## 1705 | 1706 | io.write( ... ) ==> file -- on success 1707 | ==> nil, string, integer -- in case of error 1708 | ...: (string/number)* -- values to write to io.output() 1709 | ]=] .. io.write 1710 | if A ~= io.write then io.write = A end 1711 | end 1712 | 1713 | -- get access to file methods 1714 | local file 1715 | if type( debug ) == "table" and type( io ) == "table" then 1716 | local getmeta = debug.getmetatable 1717 | local handle = io.stdout or io.stderr or io.stdin 1718 | if type( getmeta ) == "function" and 1719 | type( handle ) == "userdata" then 1720 | local m = getmeta( handle ) 1721 | if m and type( m.__index ) == "table" then 1722 | file = m.__index 1723 | end 1724 | end 1725 | end 1726 | 1727 | if check( file, "close", V >= 5.1 and V < 5.2 ) then 1728 | if io.close ~= file.close then 1729 | A = annotate[=[ 1730 | ## The `file:close()` Method ## 1731 | 1732 | file:close() ==> boolean -- on success 1733 | ==> nil, string, integer -- in case of error 1734 | self: file 1735 | ]=] .. file.close 1736 | if A ~= file.close then file.close = A end 1737 | end 1738 | end 1739 | 1740 | if check( file, "close", 5.2 ) then 1741 | if io.close ~= file.close then 1742 | A = annotate[=[ 1743 | ## The `file:close()` Method ## 1744 | 1745 | file:close() ==> boolean, (string, integer)? -- on success 1746 | ==> nil, string, integer -- in case of error 1747 | self: file 1748 | ]=] .. file.close 1749 | if A ~= file.close then file.close = A end 1750 | end 1751 | end 1752 | 1753 | if check( file, "flush", 5.1 ) then 1754 | if io.flush ~= file.flush then 1755 | A = annotate[=[ 1756 | ## The `file:flush()` Method ## 1757 | 1758 | file:flush() ==> boolean -- on success 1759 | ==> nil, string, integer -- in case of error 1760 | self: file 1761 | ]=] .. file.flush 1762 | if A ~= file.flush then file.flush = A end 1763 | end 1764 | end 1765 | 1766 | if check( file, "lines", 5.1 ) then 1767 | A = annotate[=[ 1768 | ## The `file:lines()` Method ## 1769 | 1770 | file:lines() ==> function, (any, any?)? 1771 | self: file 1772 | ]=] .. file.lines 1773 | if A ~= file.lines then file.lines = A end 1774 | end 1775 | 1776 | if check( file, "read", 5.1 ) then 1777 | A = annotate[=[ 1778 | ## The `file:read()` Method ## 1779 | 1780 | file:read( ... ) ==> (string/number/nil)* 1781 | self: file 1782 | ... : string/number -- what to read from the file 1783 | ]=] .. file.read 1784 | if A ~= file.read then file.read = A end 1785 | end 1786 | 1787 | if check( file, "seek", 5.1 ) then 1788 | A = annotate[=[ 1789 | ## The `file:seek()` Method ## 1790 | 1791 | file:seek( [whence] [, offset] ) ==> integer 1792 | ==> nil, string, integer 1793 | self : file 1794 | whence: string -- where to count the offset from 1795 | offset: integer -- where to move the file pointer to 1796 | ]=] .. file.seek 1797 | if A ~= file.seek then file.seek = A end 1798 | end 1799 | 1800 | if check( file, "setvbuf", 5.1 ) then 1801 | A = annotate[=[ 1802 | ## The `file:setvbuf()` Method ## 1803 | 1804 | file:setvbuf( mode [, size] ) ==> boolean 1805 | ==> nil, string, integer 1806 | self: file 1807 | mode: string -- buffer strategy ("no", "full", or "line" ) 1808 | size: integer -- size of the buffer in bytes 1809 | ]=] .. file.setvbuf 1810 | if A ~= file.setvbuf then file.setvbuf = A end 1811 | end 1812 | 1813 | if check( file, "write", V >= 5.1 and V < 5.2 ) then 1814 | A = annotate[=[ 1815 | ## The `file:write()` Method ## 1816 | 1817 | file:write( ... ) ==> file -- on success 1818 | ==> nil, string, integer -- in case of error 1819 | self: file 1820 | ... : (string/number)* -- values to write to the file 1821 | ]=] .. file.write 1822 | if A ~= file.write then file.write = A end 1823 | end 1824 | 1825 | if check( file, "write", 5.2 ) then 1826 | A = annotate[=[ 1827 | ## The `file:write()` Method ## 1828 | 1829 | file:write( ... ) ==> boolean -- on success 1830 | ==> nil, string, integer -- in case of error 1831 | self: file 1832 | ... : (string/number)* -- values to write to the file 1833 | ]=] .. file.write 1834 | if A ~= file.write then file.write = A end 1835 | end 1836 | 1837 | ---------------------------------------------------------------------- 1838 | -- math library 1839 | 1840 | if check( _G, "math", V >= 5.1 and V < 5.2 ) then 1841 | A = annotate[=[ 1842 | ## Mathematical Functions ## 1843 | 1844 | The following functions/values are available in Lua's `math` library: 1845 | 1846 | * `math.abs` -- Get positive value of a number. 1847 | * `math.acos` -- Get arc cosine of a number (in radians). 1848 | * `math.asin` -- Get arc sine of a number (in radians). 1849 | * `math.atan` -- Get arc tangent of a number (in radians). 1850 | * `math.atan2` -- Get arc tangent of y/x. 1851 | * `math.ceil` -- Get nearest integer `>=` a number. 1852 | * `math.cos` -- Get cosine of a number (in radians). 1853 | * `math.cosh` -- Get hyperbolic cosine of a number (in radians). 1854 | * `math.deg` -- Convert an angle from radians to degrees. 1855 | * `math.exp` -- Calculate `e^x`. 1856 | * `math.floor` -- Get nearest integer `<=´ a number. 1857 | * `math.fmod` -- Calculate remainder of a division. 1858 | * `math.frexp` -- Get significand and exponent of a Lua number. 1859 | * `math.huge` -- Largest representable number (typically infinity). 1860 | * `math.ldexp` -- Generate Lua number from significand and exponent. 1861 | * `math.log` -- Calculate natural logarithm of a number. 1862 | * `math.log10` -- Calculate base-10 logarithm of a number. 1863 | * `math.max` -- Find maximum of a given set of numbers. 1864 | * `math.min` -- Find minimum of a given set of numbers. 1865 | * `math.modf` -- Get integral and fractional part of a Lua number. 1866 | * `math.pi` -- The number PI. 1867 | * `math.pow` -- Calculate `x^y`. 1868 | * `math.rad` -- Convert an angle from degrees to radians. 1869 | * `math.random` -- Generate pseudo-random number. 1870 | * `math.randomseed` -- Initialize pseudo-random number generator. 1871 | * `math.sin` -- Get sine of a number (in radians). 1872 | * `math.sinh` -- Get hyperbolic sine of a number (in radians). 1873 | * `math.sqrt` -- Calculate the square root of a number. 1874 | * `math.tan` -- Get tangent of a number (in radians) 1875 | * `math.tanh` -- Get hyperbolic tangent of a number (in radians). 1876 | ]=] .. math 1877 | assert( A == math, "math table modified by annotate plugin" ) 1878 | elseif check( _G, "math", 5.2 ) then 1879 | A = annotate[=[ 1880 | ## Mathematical Functions ## 1881 | 1882 | The following functions are available in Lua's `math` library: 1883 | 1884 | * `math.abs` -- Get positive value of a number. 1885 | * `math.acos` -- Get arc cosine of a number (in radians). 1886 | * `math.asin` -- Get arc sine of a number (in radians). 1887 | * `math.atan` -- Get arc tangent of a number (in radians). 1888 | * `math.atan2` -- Get arc tangent of y/x. 1889 | * `math.ceil` -- Get nearest integer `>=` a number. 1890 | * `math.cos` -- Get cosine of a number (in radians). 1891 | * `math.cosh` -- Get hyperbolic cosine of a number (in radians). 1892 | * `math.deg` -- Convert an angle from radians to degrees. 1893 | * `math.exp` -- Calculate `e^x`. 1894 | * `math.floor` -- Get nearest integer `<=´ a number. 1895 | * `math.fmod` -- Calculate remainder of a division. 1896 | * `math.frexp` -- Get significand and exponent of a Lua number. 1897 | * `math.huge` -- Largest representable number (typically infinity). 1898 | * `math.ldexp` -- Generate Lua number from significand and exponent. 1899 | * `math.log` -- Calculate logarithm of a number for a given base. 1900 | * `math.max` -- Find maximum of a given set of numbers. 1901 | * `math.min` -- Find minimum of a given set of numbers. 1902 | * `math.modf` -- Get integral and fractional part of a Lua number. 1903 | * `math.pi` -- The number PI. 1904 | * `math.pow` -- Calculate `x^y`. 1905 | * `math.rad` -- Convert an angle from degrees to radians. 1906 | * `math.random` -- Generate pseudo-random number. 1907 | * `math.randomseed` -- Initialize pseudo-random number generator. 1908 | * `math.sin` -- Get sine of a number (in radians). 1909 | * `math.sinh` -- Get hyperbolic sine of a number (in radians). 1910 | * `math.sqrt` -- Calculate the square root of a number. 1911 | * `math.tan` -- Get tangent of a number (in radians) 1912 | * `math.tanh` -- Get hyperbolic tangent of a number (in radians). 1913 | ]=] .. math 1914 | assert( A == math, "math table modified by annotate plugin" ) 1915 | end 1916 | 1917 | if check( math, "abs", 5.1 ) then 1918 | A = annotate[=[ 1919 | ## The `math.abs` Function ## 1920 | 1921 | math.abs( number ) ==> number 1922 | 1923 | ### Examples ### 1924 | 1925 | > =math.abs( 1 ), math.abs( -1 ) 1926 | 1 1 1927 | > =math.abs( 1.5 ), math.abs( -1.5 ) 1928 | 1.5 1.5 1929 | ]=] .. math.abs 1930 | if A ~= math.abs then math.abs = A end 1931 | end 1932 | 1933 | if check( math, "acos", 5.1 ) then 1934 | A = annotate[=[ 1935 | ## The `math.acos` Function ## 1936 | 1937 | math.acos( number ) ==> number 1938 | ]=] .. math.acos 1939 | if A ~= math.acos then math.acos = A end 1940 | end 1941 | 1942 | if check( math, "asin", 5.1 ) then 1943 | A = annotate[=[ 1944 | ## The `math.asin` Function ## 1945 | 1946 | math.asin( number ) ==> number 1947 | ]=] .. math.asin 1948 | if A ~= math.asin then math.asin = A end 1949 | end 1950 | 1951 | if check( math, "atan", 5.1 ) then 1952 | A = annotate[=[ 1953 | ## The `math.atan` Function ## 1954 | 1955 | math.atan( number ) ==> number 1956 | ]=] .. math.atan 1957 | if A ~= math.atan then math.atan = A end 1958 | end 1959 | 1960 | if check( math, "atan2", 5.1 ) then 1961 | A = annotate[=[ 1962 | ## The `math.atan2` Function ## 1963 | 1964 | math.atan2( x, y ) ==> number 1965 | x: number 1966 | y: number 1967 | ]=] .. math.atan2 1968 | if A ~= math.atan2 then math.atan2 = A end 1969 | end 1970 | 1971 | if check( math, "ceil", 5.1 ) then 1972 | A = annotate[=[ 1973 | ## The `math.ceil` Function ## 1974 | 1975 | math.ceil( number ) ==> integer 1976 | 1977 | ### Examples ### 1978 | 1979 | > =math.ceil( 1.4 ), math.ceil( 1.6 ) 1980 | 2 2 1981 | > =math.ceil( -1.4 ), math.ceil( -1.6 ) 1982 | -1 -1 1983 | ]=] .. math.ceil 1984 | if A ~= math.ceil then math.ceil = A end 1985 | end 1986 | 1987 | if check( math, "cos", 5.1 ) then 1988 | A = annotate[=[ 1989 | ## The `math.cos` Function ## 1990 | 1991 | math.cos( number ) ==> number 1992 | 1993 | ### Examples ### 1994 | 1995 | > function feq( a, b ) return math.abs( a-b ) < 0.00001 end 1996 | > =feq( math.cos( 0 ), 1 ) 1997 | true 1998 | > =feq( math.cos( math.pi ), -1 ) 1999 | true 2000 | > =feq( math.cos( math.pi/2 ), 0 ) 2001 | true 2002 | ]=] .. math.cos 2003 | if A ~= math.cos then math.cos = A end 2004 | end 2005 | 2006 | if check( math, "cosh", 5.1 ) then 2007 | A = annotate[=[ 2008 | ## The `math.cosh` Function ## 2009 | 2010 | math.cosh( number ) ==> number 2011 | ]=] .. math.cosh 2012 | if A ~= math.cosh then math.cosh = A end 2013 | end 2014 | 2015 | if check( math, "deg", 5.1 ) then 2016 | A = annotate[=[ 2017 | ## The `math.deg` Function ## 2018 | 2019 | math.deg( number ) ==> number 2020 | 2021 | ### Examples ### 2022 | 2023 | > function feq( a, b ) return math.abs( a-b ) < 0.00001 end 2024 | > =feq( math.deg( 0 ), 0 ) 2025 | true 2026 | > =feq( math.deg( math.pi ), 180 ) 2027 | true 2028 | > =feq( math.deg( 4*math.pi ), 720 ) 2029 | true 2030 | > =feq( math.deg( -math.pi ), -180 ) 2031 | true 2032 | ]=] .. math.deg 2033 | if A ~= math.deg then math.deg = A end 2034 | end 2035 | 2036 | if check( math, "exp", 5.1 ) then 2037 | A = annotate[=[ 2038 | ## The `math.exp` Function ## 2039 | 2040 | math.exp( number ) ==> number 2041 | 2042 | ### Examples ### 2043 | 2044 | > function feq( a, b ) return math.abs( a-b ) < 0.00001 end 2045 | > =feq( math.exp( 0 ), 1 ) 2046 | true 2047 | > =feq( math.exp( 1 ), 2.718281828459 ) 2048 | true 2049 | ]=] .. math.exp 2050 | if A ~= math.exp then math.exp = A end 2051 | end 2052 | 2053 | if check( math, "floor", 5.1 ) then 2054 | A = annotate[=[ 2055 | ## The `math.floor` Function ## 2056 | 2057 | math.floor( number ) ==> integer 2058 | 2059 | ### Examples ### 2060 | 2061 | > =math.floor( 1.4 ), math.floor( 1.6 ) 2062 | 1 1 2063 | > =math.floor( -1.4 ), math.floor( -1.6 ) 2064 | -2 -2 2065 | ]=] .. math.floor 2066 | if A ~= math.floor then math.floor = A end 2067 | end 2068 | 2069 | if check( math, "fmod", 5.1 ) then 2070 | A = annotate[=[ 2071 | ## The `math.fmod` Function ## 2072 | 2073 | math.fmod( x, y ) ==> number 2074 | x: number 2075 | y: number 2076 | ]=] .. math.fmod 2077 | if A ~= math.fmod then math.fmod = A end 2078 | end 2079 | 2080 | if check( math, "frexp", 5.1 ) then 2081 | A = annotate[=[ 2082 | ## The `math.frexp` Function ## 2083 | 2084 | math.frexp( number ) ==> number, integer 2085 | ]=] .. math.frexp 2086 | if A ~= math.frexp then math.frexp = A end 2087 | end 2088 | 2089 | if check( math, "ldexp", 5.1 ) then 2090 | A = annotate[=[ 2091 | ## The `math.ldexp` Function ## 2092 | 2093 | math.ldexp( m, e ) ==> number 2094 | m: number 2095 | e: integer 2096 | ]=] .. math.ldexp 2097 | if A ~= math.ldexp then math.ldexp = A end 2098 | end 2099 | 2100 | if check( math, "log", V >= 5.1 and V < 5.2 ) then 2101 | A = annotate[=[ 2102 | ## The `math.log` Function ## 2103 | 2104 | math.log( number ) ==> number 2105 | ]=] .. math.log 2106 | if A ~= math.log then math.log = A end 2107 | end 2108 | 2109 | if check( math, "log", 5.2 ) then 2110 | A = annotate[=[ 2111 | ## The `math.log` Function ## 2112 | 2113 | math.log( x [, base] ) ==> number 2114 | x : number 2115 | base: number -- defaults to e 2116 | ]=] .. math.log 2117 | if A ~= math.log then math.log = A end 2118 | end 2119 | 2120 | if check( math, "log10", V >= 5.1 and V < 5.3 ) then 2121 | A = annotate[=[ 2122 | ## The `math.log10` Function ## 2123 | 2124 | math.log10( number ) ==> number 2125 | ]=] .. math.log10 2126 | if A ~= math.log10 then math.log10 = A end 2127 | end 2128 | 2129 | if check( math, "max", 5.1 ) then 2130 | A = annotate[=[ 2131 | ## The `math.max` Function ## 2132 | 2133 | math.max( number, ... ) ==> number 2134 | 2135 | ### Examples ### 2136 | 2137 | > =math.max( 12, 35, -10, 69.5, 22, -1 ) 2138 | 69.5 2139 | ]=] .. math.max 2140 | if A ~= math.max then math.max = A end 2141 | end 2142 | 2143 | if check( math, "min", 5.1 ) then 2144 | A = annotate[=[ 2145 | ## The `math.min` Function ## 2146 | 2147 | math.min( number, ... ) ==> number 2148 | 2149 | ### Examples ### 2150 | 2151 | > =math.min( 12, 35, -10, 69.5, 22, -1 ) 2152 | -10 2153 | ]=] .. math.min 2154 | if A ~= math.min then math.min = A end 2155 | end 2156 | 2157 | if check( math, "modf", 5.1 ) then 2158 | A = annotate[=[ 2159 | ## The `math.modf` Function ## 2160 | 2161 | math.modf( number ) ==> integer, number 2162 | ]=] .. math.modf 2163 | if A ~= math.modf then math.modf = A end 2164 | end 2165 | 2166 | if check( math, "pow", 5.1 ) then 2167 | A = annotate[=[ 2168 | ## The `math.pow` Function ## 2169 | 2170 | math.pow( x, y ) ==> number 2171 | x: number 2172 | y: number 2173 | 2174 | ### Examples ### 2175 | 2176 | > =math.pow( 2, 0 ), math.pow( 2, 1 ), math.pow( 2, 2 ) 2177 | 1 2 4 2178 | > =math.pow( 2, 3 ), math.pow( 16, 0.5 ) 2179 | 8 4 2180 | ]=] .. math.pow 2181 | if A ~= math.pow then math.pow = A end 2182 | end 2183 | 2184 | if check( math, "rad", 5.1 ) then 2185 | A = annotate[=[ 2186 | ## The `math.rad` Function ## 2187 | 2188 | math.rad( number ) ==> number 2189 | 2190 | ### Examples ### 2191 | 2192 | > function feq( a, b ) return math.abs( a-b ) < 0.00001 end 2193 | > =feq( math.rad( 0 ), 0 ) 2194 | true 2195 | > =feq( math.rad( 180 ), math.pi ) 2196 | true 2197 | > =feq( math.rad( 720 ), 4*math.pi ) 2198 | true 2199 | > =feq( math.rad( -180 ), -math.pi ) 2200 | true 2201 | ]=] .. math.rad 2202 | if A ~= math.rad then math.rad = A end 2203 | end 2204 | 2205 | if check( math, "random", 5.1 ) then 2206 | A = annotate[=[ 2207 | ## The `math.random` Function ## 2208 | 2209 | math.random( [m [, n]] ) ==> number 2210 | ]=] .. math.random 2211 | if A ~= math.random then math.random = A end 2212 | end 2213 | 2214 | if check( math, "randomseed", 5.1 ) then 2215 | A = annotate[=[ 2216 | ## The `math.randomseed` Function ## 2217 | 2218 | math.randomseed( number ) 2219 | ]=] .. math.randomseed 2220 | if A ~= math.randomseed then math.randomseed = A end 2221 | end 2222 | 2223 | if check( math, "sin", 5.1 ) then 2224 | A = annotate[=[ 2225 | ## The `math.sin` Function ## 2226 | 2227 | math.sin( number ) ==> number 2228 | 2229 | ### Examples ### 2230 | 2231 | > function feq( a, b ) return math.abs( a-b ) < 0.00001 end 2232 | > =feq( math.sin( 0 ), 0 ) 2233 | true 2234 | > =feq( math.sin( math.pi ), 0 ) 2235 | true 2236 | > =feq( math.sin( math.pi/2 ), 1 ) 2237 | true 2238 | 2239 | ]=] .. math.sin 2240 | if A ~= math.sin then math.sin = A end 2241 | end 2242 | 2243 | if check( math, "sinh", 5.1 ) then 2244 | A = annotate[=[ 2245 | ## The `math.sinh` Function ## 2246 | 2247 | math.sinh( number ) ==> number 2248 | ]=] .. math.sinh 2249 | if A ~= math.sinh then math.sinh = A end 2250 | end 2251 | 2252 | if check( math, "sqrt", 5.1 ) then 2253 | A = annotate[=[ 2254 | ## The `math.sqrt` Function ## 2255 | 2256 | math.sqrt( number ) ==> number 2257 | 2258 | ### Examples ### 2259 | 2260 | > =math.sqrt( 4 ), math.sqrt( 9 ), math.sqrt( 16 ) 2261 | 2 3 4 2262 | > function feq( a, b ) return math.abs( a-b ) < 0.00001 end 2263 | > =feq( math.sqrt( 2 ), 1.4142135623731 ) 2264 | true 2265 | ]=] .. math.sqrt 2266 | if A ~= math.sqrt then math.sqrt = A end 2267 | end 2268 | 2269 | if check( math, "tan", 5.1 ) then 2270 | A = annotate[=[ 2271 | ## The `math.tan` Function ## 2272 | 2273 | math.tan( number ) ==> number 2274 | ]=] .. math.tan 2275 | if A ~= math.tan then math.tan = A end 2276 | end 2277 | 2278 | if check( math, "tanh", 5.1 ) then 2279 | A = annotate[=[ 2280 | ## The `math.tanh` Function ## 2281 | 2282 | math.tanh( number ) ==> number 2283 | ]=] .. math.tanh 2284 | if A ~= math.tanh then math.tanh = A end 2285 | end 2286 | 2287 | ---------------------------------------------------------------------- 2288 | -- os library 2289 | 2290 | if check( _G, "os", 5.1 ) then 2291 | A = annotate[=[ 2292 | ## Operating System Facilities ## 2293 | 2294 | Lua defines the following functions in its `os` library: 2295 | 2296 | * `os.clock` -- Calculate CPU time in seconds used by program. 2297 | * `os.date` -- Formatting of dates/times. 2298 | * `os.difftime` -- Calculate difference between two time values. 2299 | * `os.execute` -- Run external programs using the OS's shell. 2300 | * `os.exit` -- Quit currently running program. 2301 | * `os.getenv` -- Query environment variables. 2302 | * `os.remove` -- Remove a file in the file system. 2303 | * `os.rename` -- Move/Rename a file in the file system. 2304 | * `os.setlocale` -- Adapt runtime to different languages. 2305 | * `os.time` -- Get a time value for a given date (or for now). 2306 | * `os.tmpname` -- Get a file name usable as a temporary file. 2307 | ]=] .. os 2308 | assert( A == os, "os table modified by annotate plugin" ) 2309 | end 2310 | 2311 | if check( os, "clock", 5.1 ) then 2312 | A = annotate[=[ 2313 | ## The `os.clock` Function ## 2314 | 2315 | os.clock() ==> number 2316 | ]=] .. os.clock 2317 | if A ~= os.clock then os.clock = A end 2318 | end 2319 | 2320 | if check( os, "date", 5.1 ) then 2321 | A = annotate[=[ 2322 | ## The `os.date` Function ## 2323 | 2324 | os.date( [format [, time]] ) ==> string/table/nil 2325 | format: string -- format to use for output, defaults to "%c" 2326 | time : number -- time value to use, defaults to now 2327 | ]=] .. os.date 2328 | if A ~= os.date then os.date = A end 2329 | end 2330 | 2331 | if check( os, "difftime", 5.1 ) then 2332 | A = annotate[=[ 2333 | ## The `os.difftime` Function ## 2334 | 2335 | os.difftime( t1 [, t2] ) ==> number 2336 | t1: number -- a time value 2337 | t2: number -- another time value, defaults to 0 2338 | ]=] .. os.difftime 2339 | if A ~= os.difftime then os.difftime = A end 2340 | end 2341 | 2342 | if check( os, "execute", V >= 5.1 and V < 5.2 ) then 2343 | A = annotate[=[ 2344 | ## The `os.execute` Function ## 2345 | 2346 | os.execute( [command] ) ==> integer 2347 | command: string -- the command line to be passed to the shell 2348 | ]=] .. os.execute 2349 | if A ~= os.execute then os.execute = A end 2350 | end 2351 | 2352 | if check( os, "execute", 5.2 ) then 2353 | A = annotate[=[ 2354 | ## The `os.execute` Function ## 2355 | 2356 | os.execute( [command] ) ==> boolean/nil, string, integer 2357 | ==> boolean 2358 | command: string -- the command line to be passed to the shell 2359 | ]=] .. os.execute 2360 | if A ~= os.execute then os.execute = A end 2361 | end 2362 | 2363 | if check( os, "exit", V >= 5.1 and V < 5.2 ) then 2364 | A = annotate[=[ 2365 | ## The `os.exit` Function ## 2366 | 2367 | os.exit( [code] ) 2368 | code: integer -- exit code to pass to exit C function 2369 | ]=] .. os.exit 2370 | if A ~= os.exit then os.exit = A end 2371 | end 2372 | 2373 | if check( os, "exit", 5.2 ) then 2374 | A = annotate[=[ 2375 | ## The `os.exit` Function ## 2376 | 2377 | os.exit( [code [, close]] ) 2378 | code : boolean/integer -- exit code for exit C function 2379 | close: boolean -- close Lua state before exit? 2380 | ]=] .. os.exit 2381 | if A ~= os.exit then os.exit = A end 2382 | end 2383 | 2384 | if check( os, "getenv", 5.1 ) then 2385 | A = annotate[=[ 2386 | ## The `os.getenv` Function ## 2387 | 2388 | os.getenv( envname ) ==> string/nil 2389 | envname: string -- name of the environment variable 2390 | ]=] .. os.getenv 2391 | if A ~= os.getenv then os.getenv = A end 2392 | end 2393 | 2394 | if check( os, "remove", 5.1 ) then 2395 | A = annotate[=[ 2396 | ## The `os.remove` Function ## 2397 | 2398 | os.remove( filename ) ==> boolean -- on success 2399 | ==> nil, string, integer -- on error 2400 | filename: string -- name of the file to remove 2401 | ]=] .. os.remove 2402 | if A ~= os.remove then os.remove = A end 2403 | end 2404 | 2405 | if check( os, "rename", 5.1 ) then 2406 | A = annotate[=[ 2407 | ## The `os.rename` Function ## 2408 | 2409 | os.rename( oldname, newname ) ==> boolean -- on success 2410 | ==> nil, string, integer -- on error 2411 | oldname: string -- name of the file to rename 2412 | newname: string -- new file name 2413 | ]=] .. os.rename 2414 | if A ~= os.rename then os.rename = A end 2415 | end 2416 | 2417 | if check( os, "setlocale", 5.1 ) then 2418 | A = annotate[=[ 2419 | ## The `os.setlocale` Function ## 2420 | 2421 | os.setlocale( locale [, category] ) ==> string/nil 2422 | locale : string -- name of the new locale to set 2423 | category: string -- category to change the locale for 2424 | ]=] .. os.setlocale 2425 | if A ~= os.setlocale then os.setlocale = A end 2426 | end 2427 | 2428 | if check( os, "time", 5.1 ) then 2429 | A = annotate[=[ 2430 | ## The `os.time` Function ## 2431 | 2432 | os.time( [table] ) ==> number/nil 2433 | ]=] .. os.time 2434 | if A ~= os.time then os.time = A end 2435 | end 2436 | 2437 | if check( os, "tmpname", 5.1 ) then 2438 | A = annotate[=[ 2439 | ## The `os.tmpname` Function ## 2440 | 2441 | os.tmpname() ==> string 2442 | ]=] .. os.tmpname 2443 | if A ~= os.tmpname then os.tmpname = A end 2444 | end 2445 | 2446 | ---------------------------------------------------------------------- 2447 | -- package table 2448 | 2449 | if check( _G, "package", V >= 5.1 and V < 5.2 ) then 2450 | A = annotate[=[ 2451 | ## The Package Table ## 2452 | 2453 | The `package` table, which is part of Lua's base library, contains the 2454 | following fields: 2455 | 2456 | * `package.config` -- Some settings from `luaconf.h`. 2457 | * `package.cpath` -- Path template to look for C modules. 2458 | * `package.loaded` -- Cache for already loaded modules. 2459 | * `package.loaders` -- Functions used for finding/loading modules. 2460 | * `package.loadlib` -- Function for loading shared libraries. 2461 | * `package.path` -- Path template to look for Lua modules. 2462 | * `package.preload` -- Table of loader functions for modules. 2463 | * `package.seeall` -- Import global environment for modules. 2464 | ]=] .. package 2465 | assert( A == package, "package table modified by annotate plugin" ) 2466 | elseif check( _G, "package", 5.2 ) then 2467 | A = annotate[=[ 2468 | ## The Package Table ## 2469 | 2470 | The `package` table, which is part of Lua's base library, contains the 2471 | following fields: 2472 | 2473 | * `package.config` -- Some settings from `luaconf.h`. 2474 | * `package.cpath` -- Path template to look for C modules. 2475 | * `package.loaded` -- Cache for already loaded modules. 2476 | * `package.loadlib` -- Function for loading shared libraries. 2477 | * `package.path` -- Path template to look for Lua modules. 2478 | * `package.preload` -- Table of loader functions for modules. 2479 | * `package.searchers` -- Functions used for finding/loading modules. 2480 | * `package.searchpath` -- Search for a name using a path template. 2481 | ]=] .. package 2482 | assert( A == package, "package table modified by annotate plugin" ) 2483 | end 2484 | 2485 | if check( package, "loaded", 5.1 ) then 2486 | A = annotate[=[ 2487 | ## The `package.loaded` Table ## 2488 | 2489 | The `require` function caches every module it loads (or rather the 2490 | module's return value) in a table in the registry that is also 2491 | referenced by `package.loaded` to avoiding loading/running a module 2492 | more than once. Setting `package.loaded` to a new table has no effect 2493 | on `require`s behavior, since the cache table in the registry is 2494 | unchanged. `require` *will* return a module that you put there 2495 | manually, though. 2496 | 2497 | ### Examples ### 2498 | 2499 | > =package.loaded[ "annotate.help" ] 2500 | table: ... 2501 | > package.loaded[ "my.special.module" ] = "hello" 2502 | > =require( "my.special.module" ) 2503 | hello 2504 | ]=] .. package.loaded 2505 | assert( A == package.loaded, 2506 | "package.loaded modified by annotate plugin" ) 2507 | end 2508 | 2509 | if check( package, "loaders", V >= 5.1 and V < 5.2 ) then 2510 | A = annotate[=[ 2511 | ## The `package.loaders` Table ## 2512 | 2513 | `package.loaders` is a reference to an internal array of functions 2514 | that are used by `require` to find modules by a given name. The 2515 | default loaders in this table look for a field in `package.preload` 2516 | first, then try to find a Lua library via `package.path`/`LUA_PATH`, 2517 | and then resort to loading dynamic C libraries via `package.loadlib` 2518 | and `package.cpath`/`LUA_CPATH`. As it is just an alias, setting 2519 | `package.loaders` to a new table has no effect on module loading. 2520 | ]=] .. package.loaders 2521 | assert( A == package.loaders, 2522 | "package.loaders modified by annotate plugin" ) 2523 | end 2524 | 2525 | if check( package, "loadlib", V >= 5.1 and V < 5.2 ) then 2526 | A = annotate[=[ 2527 | ## The `package.loadlib` Function ## 2528 | 2529 | package.loadlib( libname, funcname ) ==> function -- on success 2530 | ==> nil, string -- on error 2531 | libname : string -- name of a DLL or shared object 2532 | funcname: string -- name of a lua_CFunction in the C library 2533 | 2534 | The `package.loadlib` function loads and links the dynamic C library 2535 | with the given name and looks for the given function symbol in the 2536 | library. On success, the symbol is returned as a function, otherwise 2537 | nil and an error message is returned. 2538 | ]=] .. package.loadlib 2539 | if A ~= package.loadlib then package.loadlib = A end 2540 | end 2541 | 2542 | if check( package, "loadlib", 5.2 ) then 2543 | A = annotate[=[ 2544 | ## The `package.loadlib` Function ## 2545 | 2546 | package.loadlib( libname, funcname ) ==> function -- on success 2547 | ==> nil, string -- on error 2548 | libname : string -- name of a DLL or shared object 2549 | funcname: string -- name of a lua_CFunction in the C library 2550 | 2551 | The `package.loadlib` function loads and links the dynamic C library 2552 | with the given name and looks for the given function symbol in the 2553 | library. On success, the symbol is returned as a function, otherwise 2554 | nil and an error message is returned. `funcname` may be `"*"` in which 2555 | case the library is linked and can serve as a prerequisite for other 2556 | dynamic C libraries, but no function is returned. 2557 | ]=] .. package.loadlib 2558 | if A ~= package.loadlib then package.loadlib = A end 2559 | end 2560 | 2561 | if check( package, "preload", 5.1 ) then 2562 | A = annotate[=[ 2563 | ## The `package.preload` Table ## 2564 | 2565 | The `package.preload` table is a table (or rather an alias for a table 2566 | in the registry) the `require` function by default looks in before 2567 | attempting to load a module from a file. The table maps module names 2568 | to loader functions, that are called by `require` to load a module. 2569 | As it is just an alias, setting `package.preload` to a new table has 2570 | no effect on module loading. 2571 | 2572 | ### Examples ### 2573 | 2574 | >package.preload[ "my.special.mod" ] = function( name ) 2575 | >> print( name ) 2576 | >> return "hello again" 2577 | >> end 2578 | > =require( "my.special.mod" ) 2579 | my.special.mod 2580 | hello again 2581 | > =require( "my.special.mod" ) 2582 | hello again 2583 | ]=] .. package.preload 2584 | assert( A == package.preload, 2585 | "package.preload modified by annotate plugin" ) 2586 | end 2587 | 2588 | if check( package, "searchers", 5.2 ) then 2589 | A = annotate[=[ 2590 | ## The `package.searchers` Table ## 2591 | 2592 | `package.searchers` is a reference to an internal array of functions 2593 | that are used by `require` to find modules by a given name. The 2594 | default searchers in this table look for a field in `package.preload` 2595 | first, then try to find a Lua library via `package.path`/`LUA_PATH`, 2596 | and then resort to loading dynamic C libraries via `package.loadlib` 2597 | and `package.cpath`/`LUA_CPATH`. As it is just an alias, setting 2598 | `package.searchers` to a new table has no effect on module loading. 2599 | ]=] .. package.searchers 2600 | assert( A == package.searchers, 2601 | "package.searchers modified by annotate plugin" ) 2602 | end 2603 | 2604 | if check( package, "searchpath", 5.2 ) then 2605 | A = annotate[=[ 2606 | ## The `package.searchpath` Function ## 2607 | 2608 | package.searchpath( name, path [, sep [, rep]] ) 2609 | ==> string 2610 | ==> nil, string 2611 | name: string -- name to look for 2612 | path: string -- path template used for searching 2613 | sep : string -- sub-string in name to replace, "." by default 2614 | rep : string -- replacement for any sep occurrences in name, 2615 | -- the platform's directory separator by default 2616 | 2617 | The `package.searchpath` function iterates the `;`-separated elements 2618 | in the `path` template, after substituting each `?` in the template 2619 | with a modified `name` where each occurrence of `sep` in `name` is 2620 | replaced by `rep`. Returns the first file that can be opened for 2621 | reading, or nil and a message listing all file paths tried. The 2622 | default value for `sep` is `"."`, the default for `rep` is the Lua 2623 | directory separator listed in `package.config` (and defined in 2624 | `luaconf.h`). 2625 | 2626 | ### Examples ### 2627 | 2628 | > =package.searchpath( "my.weird.f_name", "./?.x;?.t", ".", "/" ) 2629 | nil 2630 | no file './my/weird/f_name.x' 2631 | no file 'my/weird/f_name.t' 2632 | > =package.searchpath( "my.weird.f_name", "?.t_t", "_", "X" ) 2633 | nil 2634 | no file 'my.weird.fXname.t_t' 2635 | ]=] .. package.searchpath 2636 | if A ~= package.searchpath then package.searchpath = A end 2637 | end 2638 | 2639 | if check( package, "seeall", V >= 5.1 and V < 5.3 ) then 2640 | A = annotate[=[ 2641 | ## The `package.seeall` Function ## 2642 | 2643 | package.seeall( module ) 2644 | module: table -- the module table 2645 | 2646 | The `package.seeall` function usually is not called directly, but 2647 | passed as the second argument to the `module` function to make the 2648 | global environment available inside the module's code by setting a 2649 | metatable with an `__index` metamethod for the module table. 2650 | ]=] .. package.seeall 2651 | if A ~= package.seeall then package.seeall = A end 2652 | end 2653 | 2654 | ---------------------------------------------------------------------- 2655 | -- string library 2656 | 2657 | if check( _G, "string", 5.1 ) then 2658 | A = annotate[=[ 2659 | ## String Manipulation ## 2660 | 2661 | Lua's `string` library provides the following functions, which by 2662 | default can also be called using method syntax: 2663 | 2664 | * `string.byte` -- Convert strings to numerical character codes. 2665 | * `string.char` -- Convert numerical character codes to strings. 2666 | * `string.dump` -- Dump a functions bytecode as a string. 2667 | * `string.find` -- Find start/stop indices of a pattern match. 2668 | * `string.format` -- Generate string according to format spec. 2669 | * `string.gmatch` -- Iterate over matching sub-strings. 2670 | * `string.gsub` -- Replace parts of a string. 2671 | * `string.len` -- Get a strings length in bytes. 2672 | * `string.lower` -- Turn uppercase letters to lowercase. 2673 | * `string.match` -- Try to match a string to a pattern. 2674 | * `string.rep` -- Repeat and concatenate a string `n` times. 2675 | * `string.reverse` -- Reverse bytes in a string. 2676 | * `string.sub` -- Extract sub-string. 2677 | * `string.upper` -- Turn lowercase letters to uppercase. 2678 | ]=] .. string 2679 | assert( A == string, "string table modified by annotate plugin" ) 2680 | end 2681 | 2682 | if check( string, "byte", 5.1 ) then 2683 | A = annotate[=[ 2684 | ## The `string.byte` Function ## 2685 | 2686 | string.byte( s [, i [, j]] ) ==> integer* 2687 | s: string 2688 | i: integer -- starting index for sub-string, defaults to 1 2689 | j: integer -- end index for sub-string, defaults to i 2690 | 2691 | The `string.byte` function converts the bytes of (a sub range of) a 2692 | string into their internal numerical codes and returns them. Those 2693 | numerical codes are not necessarily portable. 2694 | 2695 | ### Examples ### 2696 | 2697 | > s = string.char( 65, 66, 67, 68, 69 ) 2698 | > =type( s ), #s 2699 | string 5 2700 | > =string.byte( s ) 2701 | 65 2702 | > =string.byte( s, 2 ) 2703 | 66 2704 | > =string.byte( s, 2, 4 ) 2705 | 66 67 68 2706 | 2707 | ]=] .. string.byte 2708 | if A ~= string.byte then string.byte = A end 2709 | end 2710 | 2711 | if check( string, "char", 5.1 ) then 2712 | A = annotate[=[ 2713 | ## The `string.char` Function ## 2714 | 2715 | string.char( ... ) ==> string 2716 | ...: integer* -- numerical character codes 2717 | 2718 | The `string.char` function converts the given numerical character 2719 | codes into bytes, merges them into a single string and returns it. 2720 | The internal numerical character codes are not necessarily portable 2721 | across different platforms. 2722 | 2723 | ### Examples ### 2724 | 2725 | > A,B,C,D,E = string.byte( "ABCDE", 1, 5 ) 2726 | > =string.char( A, B, C, D, E ) 2727 | ABCDE 2728 | > s = string.char( B, C, D ) 2729 | > =s, #s 2730 | BCD 3 2731 | ]=] .. string.char 2732 | if A ~= string.char then string.char = A end 2733 | end 2734 | 2735 | if check( string, "dump", V >= 5.1 and V < 5.2 ) then 2736 | A = annotate[=[ 2737 | ## The `string.dump` Function ## 2738 | 2739 | string.dump( function ) ==> string 2740 | 2741 | The `string.dump` function returns the bytecode of a given Lua 2742 | function as a string so it later can be loaded using `loadstring`. 2743 | The Lua function cannot have upvalues. 2744 | 2745 | ### Examples ### 2746 | 2747 | > function f() return "hello world" end 2748 | > s = string.dump( f ) 2749 | > f2 = loadstring( s ) 2750 | > =f2() 2751 | hello world 2752 | ]=] .. string.dump 2753 | if A ~= string.dump then string.dump = A end 2754 | end 2755 | 2756 | if check( string, "dump", 5.2 ) then 2757 | A = annotate[=[ 2758 | ## The `string.dump` Function ## 2759 | 2760 | string.dump( function ) ==> string 2761 | 2762 | The `string.dump` function returns the bytecode of a given Lua 2763 | function as a string so it later can be loaded using `load`. The new 2764 | Lua function will have different upvalues than the original Lua 2765 | function. 2766 | 2767 | ### Examples ### 2768 | 2769 | > function f() return "hello world" end 2770 | > s = string.dump( f ) 2771 | > f2 = load( s ) 2772 | > =f2() 2773 | hello world 2774 | ]=] .. string.dump 2775 | if A ~= string.dump then string.dump = A end 2776 | end 2777 | 2778 | if check( string, "find", 5.1 ) then 2779 | A = annotate[=[ 2780 | ## The `string.find` Function ## 2781 | 2782 | string.find( s, pattern [, init [, plain]] ) 2783 | ==> integer, integer, string* -- pattern matched 2784 | ==> nil -- no match found 2785 | s : string 2786 | pattern: string -- a pattern to find in the given string 2787 | init : integer -- starting index, default 1 2788 | plain : boolean -- turn off magic characters in pattern 2789 | ]=] .. string.find 2790 | if A ~= string.find then string.find = A end 2791 | end 2792 | 2793 | if check( string, "format", 5.1 ) then 2794 | A = annotate[=[ 2795 | ## The `string.format` Function ## 2796 | 2797 | string.format( fmt, ... ) ==> string 2798 | fmt: string -- format string specifying types of arguments 2799 | ...: any* -- arguments to insert into format string 2800 | ]=] .. string.format 2801 | if A ~= string.format then string.format = A end 2802 | end 2803 | 2804 | if check( string, "gmatch", 5.1 ) then 2805 | A = annotate[=[ 2806 | ## The `string.gmatch` Function ## 2807 | 2808 | string.gmatch( s, pattern ) ==> function, (any, any?)? 2809 | s : string 2810 | pattern: string -- pattern to find in the string 2811 | ]=] .. string.gmatch 2812 | if A ~= string.gmatch then string.gmatch = A end 2813 | end 2814 | 2815 | if check( string, "gsub", 5.1 ) then 2816 | A = annotate[=[ 2817 | ## The `string.gsub` Function ## 2818 | 2819 | string.gsub( s, pattern, repl [, n] ) ==> string, integer 2820 | s : string 2821 | pattern: string -- the pattern to replace 2822 | repl : string/table/function -- replacement value 2823 | n : integer -- replace only n occurrences 2824 | ]=] .. string.gsub 2825 | if A ~= string.gsub then string.gsub = A end 2826 | end 2827 | 2828 | if check( string, "len", 5.1 ) then 2829 | A = annotate[=[ 2830 | ## The `string.len` Function ## 2831 | 2832 | string.len( s ) ==> integer 2833 | s: string 2834 | 2835 | The `string.len` function determines and returns the length of a 2836 | string in bytes. 2837 | 2838 | ### Examples ### 2839 | 2840 | > s = "hello world" 2841 | > =string.len( s ), #s 2842 | 11 11 2843 | ]=] .. string.len 2844 | if A ~= string.len then string.len = A end 2845 | end 2846 | 2847 | if check( string, "lower", 5.1 ) then 2848 | A = annotate[=[ 2849 | ## The `string.lower` Function ## 2850 | 2851 | string.lower( s ) ==> string 2852 | s: string 2853 | 2854 | The `string.lower` function returns a copy of the given string where 2855 | all occurrences of uppercase letters are replaced by their lowercase 2856 | equivalents. What is considered an uppercase letter depends on the 2857 | currently set locale. This function only works for single-byte 2858 | encodings. 2859 | 2860 | ### Examples ### 2861 | 2862 | > =string.lower( "Hello, world!" ) 2863 | hello, world! 2864 | > =string.lower( "ABCDEFG" ) 2865 | abcdefg 2866 | ]=] .. string.lower 2867 | if A ~= string.lower then string.lower = A end 2868 | end 2869 | 2870 | if check( string, "match", 5.1 ) then 2871 | A = annotate[=[ 2872 | ## The `string.match` Function ## 2873 | 2874 | string.match( s, pattern [, init] ) ==> string, string* -- ok 2875 | ==> nil -- no match 2876 | s : string 2877 | pattern: string -- the pattern to find/match 2878 | init : integer -- where to start matching, default is 1 2879 | ]=] .. string.match 2880 | if A ~= string.match then string.match = A end 2881 | end 2882 | 2883 | if check( string, "rep", V >= 5.1 and V < 5.2 ) then 2884 | A = annotate[=[ 2885 | ## The `string.rep` Function ## 2886 | 2887 | string.rep( s, n ) ==> string 2888 | s: string 2889 | n: integer -- repetitions of s 2890 | 2891 | The `string.rep` functions returns a string that consists of `n` 2892 | repetitions of the input string. 2893 | 2894 | ### Examples ### 2895 | 2896 | > =string.rep( "#", 10 ) 2897 | ########## 2898 | > =string.rep( "ab", 5 ) 2899 | ababababab 2900 | > = "'"..string.rep( "abc", 0 ).."'" 2901 | '' 2902 | ]=] .. string.rep 2903 | if A ~= string.rep then string.rep = A end 2904 | end 2905 | 2906 | if check( string, "rep", 5.2 ) then 2907 | A = annotate[=[ 2908 | ## The `string.rep` Function ## 2909 | 2910 | string.rep( s, n [, sep] ) ==> string 2911 | s : string 2912 | n : integer -- repetitions of s 2913 | sep: string -- seperator between occurrences of s 2914 | 2915 | The `string.rep` functions returns a string that consists of `n` 2916 | repetitions of the input string delimited by the given separator. The 2917 | default separator is the empty string. 2918 | 2919 | ### Examples ### 2920 | 2921 | > =string.rep( "#", 10 ) 2922 | ########## 2923 | > =string.rep( "ab", 5 ) 2924 | ababababab 2925 | > =string.rep( "ab", 5, "," ) 2926 | ab,ab,ab,ab,ab 2927 | > = "'"..string.rep( "abc", 0 ).."'" 2928 | '' 2929 | ]=] .. string.rep 2930 | if A ~= string.rep then string.rep = A end 2931 | end 2932 | 2933 | if check( string, "reverse", 5.1 ) then 2934 | A = annotate[=[ 2935 | ## The `string.reverse` Function ## 2936 | 2937 | string.reverse( s ) ==> string 2938 | s: string 2939 | 2940 | The `string.reverse` function returns a copy of a given string, where 2941 | the order of bytes is reversed (i.e. the last byte comes first, etc.). 2942 | 2943 | ### Examples ### 2944 | 2945 | > =string.reverse( "abc" ) 2946 | cba 2947 | ]=] .. string.reverse 2948 | if A ~= string.reverse then string.reverse = A end 2949 | end 2950 | 2951 | if check( string, "sub", 5.1 ) then 2952 | A = annotate[=[ 2953 | ## The `string.sub` Function ## 2954 | 2955 | string.sub( s, i [, j] ) ==> string 2956 | s: string 2957 | i: integer -- start index 2958 | j: integer -- end index, defaults to #s 2959 | 2960 | The `string.sub` function extracts and returns a sub string of its 2961 | first argument. The start and end indices for the sub string can be 2962 | specified as optional arguments. Negative indices count from the end 2963 | of the string. 2964 | 2965 | ### Examples ### 2966 | 2967 | > =string.sub( "hello world", 1 ) 2968 | hello world 2969 | > =string.sub( "hello world", 7 ) 2970 | world 2971 | > =string.sub( "hello world", 1, 5 ) 2972 | hello 2973 | > =string.sub( "hello world", 1, -1 ) 2974 | hello world 2975 | > =string.sub( "hello world", 1, -7 ) 2976 | hello 2977 | > =string.sub( "hello world", 4, 8 ) 2978 | lo wo 2979 | ]=] .. string.sub 2980 | if A ~= string.sub then string.sub = A end 2981 | end 2982 | 2983 | if check( string, "upper", 5.1 ) then 2984 | A = annotate[=[ 2985 | ## The `string.upper` Function ## 2986 | 2987 | string.upper( s ) ==> string 2988 | s: string 2989 | 2990 | The `string.upper` function returns a copy of the given string where 2991 | all occurrences of lowercase letters are replaced by their uppercase 2992 | equivalents. What is considered an lowercase letter depends on the 2993 | currently set locale. This function only works for single-byte 2994 | encodings. 2995 | 2996 | ### Examples ### 2997 | 2998 | > =string.upper( "Hello, world!" ) 2999 | HELLO, WORLD! 3000 | > =string.upper( "abcdefg" ) 3001 | ABCDEFG 3002 | ]=] .. string.upper 3003 | if A ~= string.upper then string.upper = A end 3004 | end 3005 | 3006 | ---------------------------------------------------------------------- 3007 | -- table library 3008 | 3009 | if check( _G, "table", V >= 5.1 and V < 5.2 ) then 3010 | A = annotate[=[ 3011 | ## Table Manipulation ## 3012 | 3013 | The following functions are defined in Lua's `table` library: 3014 | 3015 | * `table.concat` -- Concatenate strings of an array int one string. 3016 | * `table.insert` -- Insert an element anywhere in an array. 3017 | * `table.maxn` -- Determine largest positive numerical integer key. 3018 | * `table.remove` -- Remove one element anywhere in an array. 3019 | * `table.sort` -- Sort the elements of an array in-place. 3020 | ]=] .. table 3021 | assert( A == table, "table table modified by annotate plugin" ) 3022 | elseif check( _G, "table", 5.2 ) then 3023 | A = annotate[=[ 3024 | ## Table Manipulation ## 3025 | 3026 | The following functions are defined in Lua's `table` library: 3027 | 3028 | * `table.concat` -- Concatenate strings of an array int one string. 3029 | * `table.insert` -- Insert an element anywhere in an array. 3030 | * `table.pack` -- Convert an argument list to an array. 3031 | * `table.remove` -- Remove one element anywhere in an array. 3032 | * `table.sort` -- Sort the elements of an array in-place. 3033 | * `table.unpack` -- Convert an array to multiple values (vararg). 3034 | ]=] .. table 3035 | assert( A == table, "table table modified by annotate plugin" ) 3036 | end 3037 | 3038 | if check( table, "concat", 5.1 ) then 3039 | A = annotate[=[ 3040 | ## The `table.concat` Function ## 3041 | 3042 | table.concat( list [, sep [, i [, j]]] ) ==> string 3043 | list: table -- an array of strings or numbers 3044 | sep : string -- a separator, defaults to "" 3045 | i : integer -- starting index, defaults to 1 3046 | j : integer -- end index, defaults to #list 3047 | 3048 | The `table.concat` function converts the elements of an array into 3049 | strings (if they are numbers) and joins them together to a single 3050 | string which is returned. An optional separator is inserted between 3051 | every element pair. Optional start and end indices allow for selecting 3052 | a sub-range of the array. If an element is encountered that is neither 3053 | number nor string, an error is raised. An empty array (or sub-range) 3054 | results in the empty string `""`. All table accesses do not trigger 3055 | metamethods. 3056 | 3057 | ### Examples ### 3058 | 3059 | > t = { 1, 2, "3", 4, 5 } 3060 | > =table.concat( t ) 3061 | 12345 3062 | > =table.concat( t, "+" ) 3063 | 1+2+3+4+5 3064 | > =table.concat( t, ",", 3 ) 3065 | 3,4,5 3066 | > =table.concat( t, "|", 2, 4 ) 3067 | 2|3|4 3068 | ]=] .. table.concat 3069 | if A ~= table.concat then table.concat = A end 3070 | end 3071 | 3072 | if check( table, "insert", 5.1 ) then 3073 | A = annotate[=[ 3074 | ## The `table.insert` Function ## 3075 | 3076 | table.insert( list, [pos,] value ) 3077 | list : table -- an array 3078 | pos : integer -- index where to insert, defaults to #list+1 3079 | value: any -- value to insert 3080 | 3081 | The `table.insert` function inserts a value at the given position into 3082 | an array, shifting all following array elements by one. If no position 3083 | is given (the function is called with two arguments), the value is 3084 | appended to the end of the array. All table accesses do not trigger 3085 | metamethods. The array must *not* contain holes! 3086 | 3087 | ### Examples ### 3088 | 3089 | > t = { 1, 2, 3 } 3090 | > table.insert( t, 4 ) 3091 | > =t[ 1 ], t[ 2 ], t[ 3 ], t[ 4 ] 3092 | 1 2 3 4 3093 | > table.insert( t, 2, 1.5 ) 3094 | > =t[ 1 ], t[ 2 ], t[ 3 ], t[ 4 ], t[ 5 ] 3095 | 1 1.5 2 3 4 3096 | ]=] .. table.insert 3097 | if A ~= table.insert then table.insert = A end 3098 | end 3099 | 3100 | if check( table, "maxn", V >= 5.1 and V < 5.3 ) then 3101 | A = annotate[=[ 3102 | ## The `table.maxn` Function ## 3103 | 3104 | table.maxn( t ) ==> number 3105 | t: table 3106 | 3107 | The `table.maxn` function traverses the whole table to look for the 3108 | largest positive numeric key and returns it. If no such key is found, 3109 | `0` is returned. The table may contain holes and non-integer numeric 3110 | keys. If it doesn't, this function is equivalent to applying the 3111 | length operator (`#`) on the table. 3112 | 3113 | ### Examples ### 3114 | 3115 | > t = { 1, 2, 3, 4 } 3116 | > =#t, table.maxn( t ) 3117 | 4 4 3118 | > =table.maxn( { 1, 2, 3, [ 10 ]=10, [ 12.5 ]=12.5 } ) 3119 | 12.5 3120 | > =table.maxn( { a=1 } ) 3121 | 0 3122 | ]=] .. table.maxn 3123 | if A ~= table.maxn then table.maxn = A end 3124 | end 3125 | 3126 | if check( table, "pack", 5.2 ) then 3127 | A = annotate[=[ 3128 | ## The `table.pack` Function ## 3129 | 3130 | table.pack( ... ) ==> table 3131 | ...: any* -- arguments/vararg to put into table 3132 | 3133 | The `table.pack` function collects all its arguments in an array and 3134 | returns it. The `n` field of the returned table is set to the number 3135 | of vararg/array elements (including `nil`s). Since varargs can contain 3136 | `nil`s, the resulting table might contain holes and thus not be a 3137 | proper array. 3138 | 3139 | ### Examples ### 3140 | 3141 | > t = table.pack( 1, 2, 3 ) 3142 | > =t[ 1 ], t[ 2 ], t[ 3 ], t.n 3143 | 1 2 3 3 3144 | > t = table.pack( "a", "b", nil, "d" ) 3145 | > =t[ 1 ], t[ 2 ], t[ 3 ], t[ 4 ], t.n 3146 | a b nil d 4 3147 | 3148 | ]=] .. table.pack 3149 | if A ~= table.pack then table.pack = A end 3150 | end 3151 | 3152 | if check( table, "remove", 5.1 ) then 3153 | A = annotate[=[ 3154 | ## The `table.remove` Function ## 3155 | 3156 | table.remove( list [, pos] ) ==> any 3157 | list: table -- an array 3158 | pos : integer -- index of value to remove, defaults to #list 3159 | 3160 | The `table.remove` function removes the value at the given position 3161 | from the array and returns it. The following array elements are 3162 | shifted by one to close the gap. If no position is given, the last 3163 | array element is removed. All table accesses do not trigger 3164 | metamethods. The array must *not* contain holes! 3165 | 3166 | ### Examples ### 3167 | 3168 | > t = { 1, 2, 3, 4, 5 } 3169 | > =table.remove( t ) 3170 | 5 3171 | > =t[ 1 ], t[ 2 ], t[ 3 ], t[ 4 ], t[ 5 ] 3172 | 1 2 3 4 nil 3173 | > =table.remove( t, 2 ) 3174 | 2 3175 | > =t[ 1 ], t[ 2 ], t[ 3 ], t[ 4 ] 3176 | 1 3 4 nil 3177 | ]=] .. table.remove 3178 | if A ~= table.remove then table.remove = A end 3179 | end 3180 | 3181 | if check( table, "sort", 5.1 ) then 3182 | A = annotate[=[ 3183 | ## The `table.sort` Function ## 3184 | 3185 | table.sort( list [, comp] ) 3186 | list: table -- an array 3187 | comp: function -- comparator function, defaults to < 3188 | 3189 | The `table.sort` function sorts the elements of an array in-place 3190 | using a comparator function to determine the intended order of the 3191 | elements. The comparator function takes two array elements as 3192 | arguments and should return a true value if the first array element 3193 | should end up *before* the second in the sorted array. If no 3194 | comparator function is given, Lua's `<`-operator is used. All table 3195 | accesses do not trigger metamethods, and the array must *not* contain 3196 | holes! The sort algorithm is not stable. 3197 | 3198 | ### Examples ### 3199 | 3200 | > t = { 3, 2, 5, 1, 2, 4 } 3201 | > table.sort( t ) 3202 | > =t[ 1 ], t[ 2 ], t[ 3 ], t[ 4 ], t[ 5 ], t[ 6 ] 3203 | 1 2 2 3 4 5 3204 | > t = { 3, 2, 5, 1, 2, 4 } 3205 | > table.sort( t, function( a, b ) return a > b end ) 3206 | > =t[ 1 ], t[ 2 ], t[ 3 ], t[ 4 ], t[ 5 ], t[ 6 ] 3207 | 5 4 3 2 2 1 3208 | ]=] .. table.sort 3209 | if A ~= table.sort then table.sort = A end 3210 | end 3211 | 3212 | if check( table, "unpack", 5.2 ) then 3213 | A = annotate[=[ 3214 | ## The `table.unpack` Function ## 3215 | 3216 | table.unpack( list [, i [, j]] ) ==> any* 3217 | list: table -- an array 3218 | i : integer -- optional start index, defaults to 1 3219 | j : integer -- optional end index, defaults to #list 3220 | 3221 | The `table.unpack` function returns the elements of the array 3222 | separately. An optional start as well as end index can be specified. 3223 | The start index defaults to `1`, the end index to the length of the 3224 | array as determined by the length operator `#`. The array may contain 3225 | holes, but in this case explicit start and end indices must be given. 3226 | 3227 | ### Examples ### 3228 | 3229 | > =table.unpack( { 1, 2, 3, 4 } ) 3230 | 1 2 3 4 3231 | > =table.unpack( { 1, 2, 3, 4 }, 2 ) 3232 | 2 3 4 3233 | > =table.unpack( { 1, 2, 3 }, 2, 3 ) 3234 | 2 3 3235 | > =table.unpack( { 1, nil, nil, 4 }, 1, 4 ) 3236 | 1 nil nil 4 3237 | ]=] .. table.unpack 3238 | if A ~= table.unpack then table.unpack = A end 3239 | end 3240 | 3241 | ---------------------------------------------------------------------- 3242 | 3243 | local M = annotate[=[ 3244 | ## The `annotate.help` Module ## 3245 | 3246 | When require'd this module returns a func table for querying the 3247 | annotations/docstrings of Lua values. 3248 | 3249 | annotate.help( v ) 3250 | v: any -- value to print help for 3251 | 3252 | If the given value has a docstring (which has been defined after this 3253 | module was require'd), the func table prints the annotation using the 3254 | standard `print` function (to the standard output). Otherwise a small 3255 | notice/error message is printed. If the value is a string and no 3256 | annotation can be found directly for it, the string is interpreted as 3257 | a combination of a module name and references in that module, so e.g. 3258 | `annotate.help( "a.b.c.d" )` will look for annotations for the 3259 | following values (in this order): 3260 | 3261 | 1. `"a.b.c.d"` 3262 | 2. `require( "a.b.c.d" )` 3263 | 3. `require( "a.b.c" ).d` 3264 | 4. `require( "a.b" ).c.d` 3265 | 5. `require( "a" ).b.c.d` 3266 | 3267 | The `annotate.help` module table also contains the following fields: 3268 | 3269 | * `annotate.help.wrap` -- Use another help function as fallback. 3270 | * `annotate.help.lookup` -- Lookup the annotation without printing. 3271 | * `annotate.help.search` -- Print any annotation matching a pattern. 3272 | * `annotate.help.iterate` -- Iterate over all values and docstrings. 3273 | ]=] .. {} 3274 | 3275 | 3276 | local function trim( s ) 3277 | return (s_gsub( s, "^%s*(.-)%s*$", "%1" )) 3278 | end 3279 | 3280 | 3281 | local function try_require( str, ... ) 3282 | local ok, v = pcall( require, str ) 3283 | if ok then 3284 | for i = 1, select( '#', ... ) do 3285 | local n = select( i, ... ) 3286 | if type( v ) == "table" then 3287 | v = v[ n ] 3288 | else 3289 | v = nil 3290 | break 3291 | end 3292 | end 3293 | end 3294 | if v ~= nil and docstring_cache[ v ] then 3295 | return trim( docstring_cache[ v ] ) 3296 | end 3297 | local s, n = s_match( str, "^([%a_][%w_%.]*)%.([%a_][%w_]*)$" ) 3298 | return s and try_require( s, n, ... ) 3299 | end 3300 | 3301 | 3302 | local function lookup( self, v ) 3303 | if self ~= M then 3304 | self, v = M, self 3305 | end 3306 | local s = docstring_cache[ v ] 3307 | if s ~= nil then 3308 | return trim( s ) 3309 | end 3310 | if type( v ) == "string" then 3311 | return try_require( v ) 3312 | end 3313 | end 3314 | 3315 | 3316 | local function wrap( self, fun, writer ) 3317 | if self ~= M then 3318 | self, fun, writer = M, self, fun 3319 | end 3320 | writer = writer or function( s ) print( s ) end 3321 | return function( ... ) 3322 | local s = lookup( self, ... ) 3323 | if s then 3324 | writer( s, ... ) 3325 | else 3326 | fun( ... ) 3327 | end 3328 | end 3329 | end 3330 | 3331 | 3332 | local delim = s_rep( "-", 70 ) 3333 | 3334 | local function search( self, s ) 3335 | if self ~= M then 3336 | self, s = M, self 3337 | end 3338 | assert( type( s ) == "string", "search term must be a string" ) 3339 | local first_match = true 3340 | for v,ds in next, docstring_cache, nil do 3341 | if s_match( ds, s ) then 3342 | if not first_match then 3343 | print( delim ) 3344 | end 3345 | print( trim( ds ) ) 3346 | first_match = false 3347 | end 3348 | end 3349 | if first_match then 3350 | print( "no result found for `"..s.."'" ) 3351 | end 3352 | end 3353 | 3354 | 3355 | local M_meta = { 3356 | __index = { 3357 | wrap = annotate[=[ 3358 | ## The `annotate.help.wrap` Function ## 3359 | 3360 | annotate.help.wrap( [self,] hfunc [, ofunc] ) ==> function 3361 | self : table -- the annotate.help table itself 3362 | hfunc: function -- fallback function for getting help 3363 | ofunc: function -- custom output function 3364 | 3365 | This function builds a new closure that first tries to find an 3366 | annotation/docstring for a given Lua value and then falls back to the 3367 | given function argument to provide interactive help for the value. 3368 | This is useful if not all of your functions follow a single approach 3369 | for online documentation. 3370 | ]=] .. wrap, 3371 | lookup = annotate[=[ 3372 | ## The `annotate.help.lookup` Function ## 3373 | 3374 | annotate.help.lookup( [self,] v ) ==> string/nil 3375 | self: table -- the annotate.help table itself 3376 | v : any -- the value to lookup the annotation for 3377 | 3378 | This function works the same way as the `annotate.help` func table 3379 | itself, but it just returns the docstring (or nil) instead of printing 3380 | it. 3381 | 3382 | ### Examples ### 3383 | 3384 | > help = require( "annotate.help" ) 3385 | > =help:lookup( help.lookup ) 3386 | ## The `annotate.help.lookup` Function ... 3387 | > =help.lookup( "annotate.help.lookup" ) 3388 | ## The `annotate.help.lookup` Function ... 3389 | ]=] .. lookup, 3390 | iterate = annotate[=[ 3391 | ## The `annotate.help.iterate` Function ## 3392 | 3393 | annotate.help.iterate( [self] ) ==> function, (any, any?)? 3394 | self: table -- the annotate.help table itself 3395 | 3396 | This function returns a for-loop iterator tuple that iterates over all 3397 | values and their docstrings. 3398 | ]=] .. function() return next, docstring_cache, nil end, 3399 | search = annotate[=[ 3400 | ## The `annotate.help.search` Function ## 3401 | 3402 | annotate.help.search( [self,] pattern ) 3403 | self : table -- the annotate.help table itself 3404 | pattern: string -- a pattern describing what to look for 3405 | 3406 | This function prints all docstrings that contain a substring matching 3407 | the given Lua string pattern (or a small notice/error message). 3408 | ]=] .. search, 3409 | }, 3410 | __call = function( _, topic ) 3411 | print( lookup( M, topic ) or 3412 | "no help available for "..tostring( topic ) ) 3413 | end, 3414 | } 3415 | setmetatable( M, M_meta ) 3416 | 3417 | ---------------------------------------------------------------------- 3418 | 3419 | -- reenable type checking 3420 | if ARG_C ~= false or RET_C ~= false then 3421 | local c = package.loaded[ "annotate.check" ] 3422 | if ARG_C ~= false then 3423 | c.arguments = ARG_C 3424 | end 3425 | if RET_C ~= false then 3426 | c.return_values = RET_C 3427 | end 3428 | end 3429 | 3430 | -- return module table 3431 | return M 3432 | 3433 | -------------------------------------------------------------------------------- /src/annotate/test.lua: -------------------------------------------------------------------------------- 1 | -- cache globals and require modules 2 | local assert = assert 3 | local require = assert( require ) 4 | local annotate = require( "annotate" ) 5 | local table = require( "table" ) 6 | local string = require( "string" ) 7 | local io = require( "io" ) 8 | local debug = require( "debug" ) 9 | local L = require( "lpeg" ) 10 | local _G = assert( _G ) 11 | local _VERSION = assert( _VERSION ) 12 | local type = assert( type ) 13 | local tostring = assert( tostring ) 14 | local select = assert( select ) 15 | local setmetatable = assert( setmetatable ) 16 | local xpcall = assert( xpcall ) 17 | local t_concat = assert( table.concat ) 18 | local s_gsub = assert( string.gsub ) 19 | local s_match = assert( string.match ) 20 | local s_rep = assert( string.rep ) 21 | local s_sub = assert( string.sub ) 22 | local io_stderr = assert( io.stderr ) 23 | local db_traceback = assert( debug.traceback ) 24 | local db_getinfo = assert( debug.getinfo ) 25 | local lpeg_match = assert( L.match ) 26 | local loadstring = assert( loadstring or load ) 27 | local unpack = assert( unpack or table.unpack ) 28 | local eof_ender = "" 29 | local setfenv = setfenv 30 | if _VERSION == "Lua 5.1" then 31 | assert( setfenv ) 32 | eof_ender = "''" 33 | end 34 | 35 | 36 | 37 | -- table to store the tests in 38 | local test_cache = {} 39 | 40 | 41 | -- grammar to identify test code in docstring 42 | local g = {} 43 | do 44 | local P,R,S,V,C,Ct,Cc = L.P,L.R,L.S,L.V,L.C,L.Ct,L.Cc 45 | local pbreak = P"\n\n" 46 | local comment = P"--" * (P( 1 ) - P"\n")^0 47 | local ws = S" \t\r\n\v\f" 48 | local _ = (ws - pbreak)^0 49 | local _2 = ((ws + comment) - pbreak)^0 50 | local letter = R( "az", "AZ" ) + P"_" 51 | local digit = R"09" 52 | local id = letter * (letter+digit)^0 53 | local indent = P" " 54 | local title = S"Ee"*S"Xx"*S"Aa"*S"Mm"*S"Pp"*S"Ll"*S"Ee"*(S"Ss"^-1) + 55 | S"Tt"*S"Ee"*S"Ss"*S"Tt"*(S"Ss"^-1) 56 | 57 | g[ 1 ] = ws^0 * Ct( (V"typespec" + (V"paragraph" - V"testspec"))^0 ) * V"testspec" * V"paragraph"^0 * P( -1 ) 58 | g.paragraph = (P( 1 ) - pbreak)^1 * ws^0 59 | -- for extracting a function signature if there is one 60 | g.typespec = C( _2 * V"funcname" * P"(" * _2 * V"arglist" * P")" ) * V"paragraph"^-1 * ws^0 61 | g.funcname = id * (P"." * id)^0 * (P":" * id)^-1 * _2 62 | g.arglist = (id+S"[],."+((ws+comment)-pbreak)^1)^0 63 | -- test specification 64 | g.testspec = V"header" * Ct( V"lua_line" * (V"lua_line" + Ct( V"out_line"^1 ) + V"empty_line")^0 ) * ws^0 65 | g.header = (title*P":" + P"#"^1*(ws-P"\n")^0*title*(ws-P"\n")^0*P"#"^0) * V"empty_line"^0 66 | g.lua_line = indent * P">" * P">"^-1 * P" "^-1 * C( (P( 1 ) - P"\n")^0 ) * P"\n" 67 | g.out_line = indent * -P">" * C( (P( 1 ) - P"\n")^0 ) * P"\n" 68 | g.empty_line = (ws - P"\n")^0 * P"\n" 69 | 70 | -- compile grammar once and for all 71 | g = P( g ) 72 | end 73 | 74 | 75 | local function output_pattern( lines ) 76 | local s = t_concat( lines, "\n" ) 77 | s = s_gsub( s, "[%]%[%^%$%%%.%*%+%-%?]", "%%%0" ) 78 | s = s_gsub( s, "%%%.%%%.%%%.", ".-" ) 79 | return "^"..(s_gsub( s, "%s+", "%%s+" )).."%s*$" 80 | end 81 | 82 | 83 | local function xp_pack( status, ... ) 84 | return status, { ... }, select( '#', ... ) 85 | end 86 | 87 | 88 | local function traceback( msg ) 89 | local t = type( msg ) 90 | if t ~= "string" and t ~= "number" then 91 | return msg 92 | end 93 | return db_traceback( msg, 2 ) 94 | end 95 | 96 | local function incomplete( msg ) 97 | return msg and s_sub( msg, -#eof_ender ) == eof_ender 98 | end 99 | 100 | 101 | local function prepare_env( f ) 102 | local env, out = {}, { n = 0 } 103 | env._G = env 104 | local function p( ... ) 105 | local n = select( '#', ... ) 106 | for i = 1, n do 107 | out[ out.n + 1 ] = tostring( select( i, ... ) ) 108 | out[ out.n + 2 ] = i == n and "\n" or "\t" 109 | out.n = out.n + 2 110 | end 111 | if n == 0 then 112 | out[ out.n + 1 ] = "\n" 113 | out.n = out.n + 1 114 | end 115 | end 116 | env.print = p 117 | env.F = f 118 | setmetatable( env, { __index = _G } ) 119 | return env, out, p 120 | end 121 | 122 | 123 | local function get_caption( v, sig ) 124 | if type( v ) == "function" then 125 | if sig then 126 | return "function " .. sig 127 | else 128 | local nfo = db_getinfo( v, "S" ) 129 | if nfo and nfo.short_src then 130 | local line = "?" 131 | if nfo.linedefined and nfo.linedefined > 0 then 132 | line = nfo.linedefined 133 | end 134 | return tostring( v ) .. " ["..nfo.short_src..":"..line.."]" 135 | end 136 | end 137 | end 138 | return tostring( v ) 139 | end 140 | 141 | 142 | local function extra_output( out, errors, t, verbosity ) 143 | local do_break = false 144 | if out.n > 0 then 145 | local s = t_concat( out, "", 1, out.n ) 146 | if out.is_error then 147 | errors[ #errors+1 ] = "### ("..t..") UNEXPECTED ERROR: "..s 148 | do_break = true 149 | else 150 | if verbosity > 1 then 151 | errors[ #errors+1 ] = "### ("..t..") UNEXPECTED OUTPUT: "..s 152 | end 153 | end 154 | out.n, out.is_error = 0, nil 155 | end 156 | return do_break 157 | end 158 | 159 | 160 | local function preamble( verbosity, caption ) 161 | if verbosity > 2 then 162 | io_stderr:write( "### TEST ", caption, "\n" ) 163 | end 164 | end 165 | 166 | local delim = s_rep( "#", 70 ) 167 | 168 | local function report( verbosity, caption, results, errors ) 169 | if #errors > 0 then 170 | io_stderr:write( delim, "\n" ) 171 | end 172 | if verbosity > 0 or #errors > 0 then 173 | io_stderr:write( "### [", results, "] ", caption, "\n" ) 174 | end 175 | if #errors > 0 then 176 | for i = 1, #errors do 177 | io_stderr:write( errors[ i ] ) 178 | end 179 | io_stderr:write( delim, "\n" ) 180 | end 181 | end 182 | 183 | 184 | local function run_test( test, totals, verbosity ) 185 | local ok, fail, n = 0, 0, 0 186 | local results, errors = "", {} 187 | local caption = get_caption( test.v, test.sig ) 188 | local env, out, p = prepare_env( test.v ) 189 | preamble( verbosity, caption ) 190 | local j, buffer, _ = 1, nil 191 | for i = 1, #test.data do 192 | local elem = test.data[ i ] 193 | if type( elem ) == "string" then -- Lua code 194 | if buffer then 195 | buffer = buffer .. "\n" .. elem 196 | else 197 | if extra_output( out, errors, j, verbosity ) then 198 | break 199 | end 200 | buffer = elem 201 | if s_sub( elem, 1, 1 ) == "=" then 202 | buffer = "return " .. s_sub( elem, 2 ) 203 | end 204 | end 205 | local f, msg = loadstring( buffer, "=stdin", "t", env ) 206 | if f then 207 | if _VERSION == "Lua 5.1" then 208 | setfenv( f, env ) 209 | end 210 | buffer = nil 211 | local st, res, n_res = xp_pack( xpcall( f, traceback ) ) 212 | if n_res > 0 then 213 | p( unpack( res, 1, n_res ) ) 214 | end 215 | out.is_error = not st 216 | else 217 | if not incomplete( msg ) then -- compilation error 218 | errors[ #errors+1 ] = "### ("..j..") COMPILATION ERROR: ".. 219 | msg.."\n" 220 | buffer, out.n = nil, 0 221 | break 222 | end 223 | end 224 | else -- output lines 225 | local s = t_concat( out, "", 1, out.n ) 226 | out.n, out.is_error = 0, nil 227 | local outp = output_pattern( elem ) 228 | if s_match( s, outp ) then 229 | ok = ok + 1 230 | results = results .. "+" 231 | else 232 | fail = fail + 1 233 | results = results .. "-" 234 | if verbosity > 1 then 235 | errors[ #errors+1 ] = "### ("..j..")\n### EXPECTED: "..outp.. 236 | "\n### GOT: >>>"..s.."<<<\n" 237 | end 238 | end 239 | n, j = n + 1, j + 1 240 | end 241 | end 242 | if buffer then -- handle incomplete Lua 243 | errors[ #errors+1 ] = "### ("..j..") INCOMPLETE CODE: "..buffer.."\n" 244 | end 245 | extra_output( out, errors, j, verbosity ) 246 | totals.ok = totals.ok + ok 247 | totals.fail = totals.fail + fail 248 | totals.n = totals.n + n 249 | report( verbosity, caption, results, errors ) 250 | end 251 | 252 | 253 | 254 | local function docstring_callback( v, docstring ) 255 | local sigs, tests = lpeg_match( g, docstring ) 256 | if sigs then 257 | local t = { v = v } 258 | if #sigs == 1 then 259 | t.sig = sigs[ 1 ] 260 | end 261 | t.data = tests 262 | test_cache[ #test_cache+1 ] = t 263 | end 264 | end 265 | annotate:register( docstring_callback ) 266 | 267 | local M = {} 268 | local M_meta = { 269 | __call = function( _, verbosity ) 270 | verbosity = type( verbosity ) == "number" and verbosity or 1 271 | local tests = test_cache 272 | test_cache = {} 273 | local totals = { ok = 0, fail = 0, n = 0 } 274 | for i = 1, #tests do 275 | run_test( tests[ i ], totals, verbosity ) 276 | end 277 | io_stderr:write( "### TOTAL: ", totals.ok, " ok, ", totals.fail, 278 | " failed, ", totals.n, " total\n") 279 | return totals.fail == 0 280 | end, 281 | } 282 | 283 | setmetatable( M, M_meta ) 284 | return M 285 | 286 | -------------------------------------------------------------------------------- /tests/annotate.check.test.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/lua 2 | 3 | -- show actual error messages (or not) 4 | local verbose = os.getenv( "VERBOSE" ) 5 | 6 | package.path = [[../src/?.lua;]] .. package.path 7 | -- for testing different lpeg versions: 8 | package.cpath = [[./?.so;./?.dll;]] .. package.cpath 9 | 10 | local annotate = require( "annotate" ) 11 | local check = require( "annotate.check" ) 12 | 13 | check.enabled = true 14 | check.arguments = true 15 | check.return_values = true 16 | 17 | -- type checking function for custom type 18 | function check.types.mytable( v ) 19 | return type( v ) == "table" and v.is_mytable 20 | end 21 | 22 | -- create values of custom type 23 | local function mytable_new() 24 | return { is_mytable = true } 25 | end 26 | 27 | 28 | -- testing functions 29 | local function succeeds( what, f, ... ) 30 | print( "", ">>>>", what ) 31 | local ok, msg = pcall( f, ... ) 32 | if not ok then 33 | error( msg:gsub( "%s*$", "" ), 0 ) 34 | elseif verbose then 35 | print( "", "", "ok." ) 36 | end 37 | end 38 | 39 | local function fails( what, epattern, f, ... ) 40 | print( "", ">>>>", what ) 41 | local ok, msg = pcall( f, ... ) 42 | if ok then 43 | error( "unexpected success", 0 ) 44 | elseif not msg:match( epattern ) then 45 | error( "unexpected error: " .. msg:gsub( "%s*$", "" ), 0 ) 46 | elseif verbose then 47 | print( "", "", (msg:gsub( "%s*$", "" )) ) 48 | end 49 | end 50 | 51 | local function test_all( what, testf ) 52 | print( ">>>> testing", what ) 53 | local ok, msg = pcall( testf ) 54 | if not ok then 55 | print( "[FAIL]", (msg:gsub( "%s*$", "" )) ) 56 | else 57 | print( "[ ok ]" ) 58 | end 59 | end 60 | 61 | local function test_error( what, epattern, testf ) 62 | print( ">>>> testing", what ) 63 | local ok, msg = pcall( testf ) 64 | if ok then 65 | print( "[FAIL] test did not raise an error at all!" ) 66 | elseif not msg:match( epattern ) then 67 | print( "[FAIL] unexpected error message:\n", msg ) 68 | elseif verbose then 69 | print( "[ ok ]", (msg:gsub( "%s*$", "" )) ) 70 | else 71 | print( "[ ok ]" ) 72 | end 73 | end 74 | 75 | 76 | 77 | -- some incorrect type specifications 78 | test_error( "missing type specification", "does not contain type spec", function() 79 | local func = annotate[=[ 80 | Some text. 81 | 82 | But no type specification! 83 | ]=] .. function() end 84 | end ) 85 | 86 | test_error( "undefined argument", "argument.*not defined", function() 87 | local func = annotate[=[ 88 | func( a ) => number 89 | ]=] .. function() end 90 | end ) 91 | 92 | test_error( "undefined return value type", "type.*is undefined", function() 93 | local func = annotate[=[ 94 | func( number ) => n 95 | ]=] .. function() end 96 | end ) 97 | 98 | test_error( "argument name reused", "argument.*multiple times", function() 99 | local func = annotate[=[ 100 | func( a, a ) => number 101 | a: number 102 | ]=] .. function() end 103 | end ) 104 | 105 | test_error( "argument type redefined", "argument.*redefined", function() 106 | local func = annotate[=[ 107 | func( a ) => number 108 | a: number 109 | a: integer 110 | ]=] .. function() end 111 | end ) 112 | 113 | test_error( "undefined argument type", "type.*is undefined", function() 114 | local func = annotate[=[ 115 | func( a ) => number 116 | a: abc 117 | ]=] .. function() end 118 | end ) 119 | 120 | 121 | -- examples from the readme 122 | test_all( "pcall example", function() 123 | local f = annotate[=[ 124 | pcall( f [, arg1, ...] ) ==> boolean, any* 125 | f : function -- the function to call in protected mode 126 | arg1: any -- first argument to f 127 | ... : any* -- remaining arguments to f 128 | ]=] .. function() end 129 | end ) 130 | test_all( "tonumber example", function() 131 | local f = annotate[=[ 132 | tonumber( any [, number] ) ==> nil/number 133 | ]=] .. function() end 134 | end ) 135 | test_all( "table.concat example", function() 136 | local f = annotate[=[ 137 | table.concat( list [, sep [, i [, j]]] ) ==> string 138 | list: table -- an array of strings 139 | sep : string -- a separator, defaults to "" 140 | i : integer -- starting index, defaults to 1 141 | j : integer -- end index, defaults to #list 142 | ]=] .. function() end 143 | end ) 144 | test_all( "table.insert example", function() 145 | local f = annotate[=[ 146 | table.insert( list, [pos,] value ) 147 | list : table -- an array 148 | pos : integer -- index where to insert (defaults to #list+1) 149 | value: any -- value to insert 150 | ]=] .. function() end 151 | end ) 152 | test_all( "io.open example", function() 153 | local f = annotate[=[ 154 | io.open( filename [, mode] ) 155 | ==> file -- on success 156 | ==> nil,string,number -- in case of error 157 | filename: string -- the name of the file 158 | mode : string -- flags similar to fopen(3) 159 | ]=] .. function() end 160 | end ) 161 | test_all( "file:read example", function() 162 | local f = annotate[=[ 163 | file:read( ... ) ==> (string/number/nil)* 164 | ...: (string/number)* -- format specifiers 165 | ]=] .. function() end 166 | end ) 167 | test_all( "file:seek example", function() 168 | local f = annotate[=[ 169 | file:seek( [whence [, offset]] ) ==> number 170 | ==> nil, string 171 | self : file -- would default to `object` 172 | whence: string 173 | offset: number 174 | ]=] .. function() end 175 | end ) 176 | test_all( "os.execute example", function() 177 | local f = annotate[=[ 178 | os.execute( [string] ) 179 | ==> boolean 180 | ==> boolean/nil, string, number 181 | ]=] .. function() end 182 | end ) 183 | test_all( "mod.obj:method example", function() 184 | local f = annotate[=[ 185 | mod.obj:method( [a [, b] [, c],] [d,] ... ) 186 | ==> boolean -- when successful 187 | ==> nil, string -- in case of error 188 | a: string/function -- a string or a function 189 | b: userdata -- a userdata 190 | -- don't break the paragraph! 191 | c: boolean -- a boolean flag 192 | d: number -- a number 193 | ...: ((table, string/number) / boolean)* 194 | ]=] .. function() end 195 | end ) 196 | 197 | 198 | -- arguments 199 | test_all( "func( number/boolean ) ==> number", function() 200 | local func = annotate[[ 201 | func( n ) ==> number 202 | n: number/boolean 203 | ]] .. 204 | function() return 1 end 205 | 206 | succeeds( "func( 12 )", func, 12 ) 207 | succeeds( "func( false )", func, false ) 208 | fails( "func( 12, 13 )", "too many arguments", func, 12, 13 ) 209 | fails( "func()", "missing argument", func ) 210 | fails( "func( 'x' )", "expected.*got string", func, "x" ) 211 | end ) 212 | 213 | 214 | -- return values 215 | test_all( "func( number ) ==> number/string, string", function() 216 | local func = annotate[[ 217 | func( number ) ==> number/string, string 218 | ]] .. 219 | function( n ) 220 | if n == 1 then 221 | return 1, "nix" 222 | elseif n == 2 then 223 | return "nix", "da" 224 | elseif n == 3 then 225 | return 1, "nix", 2 226 | elseif n == 4 then 227 | return 228 | elseif n == 5 then 229 | return false 230 | end 231 | end 232 | 233 | succeeds( "func( 1 ) ==> 1, 'nix'", func, 1 ) 234 | succeeds( "func( 2 ) ==> 'nix', 'da'", func, 2 ) 235 | fails( "func( 3 ) ==> 1, 'nix', 2", "too many return values", func, 3 ) 236 | fails( "func( 4 )", "missing return value", func, 4 ) 237 | fails( "func( 5 ) ==> false", "expected.*got boolean", func, 5 ) 238 | end ) 239 | 240 | 241 | -- optional arguments and varargs 242 | test_all( "func( [string [, userdata] [, boolean],] [number,] ... )", function() 243 | local func = annotate[=[ 244 | func( [string [, userdata] [, boolean],] [number,] ... ) 245 | ...: ((table, string/number) / boolean)* 246 | ]=] .. function() end 247 | 248 | succeeds( "func()", func ) 249 | succeeds( "func( 'a' )", func, "a" ) 250 | succeeds( "func( 'a', io.stdout )", func, "a", io.stdout ) 251 | succeeds( "func( 'a', true )", func, "a", true ) 252 | succeeds( "func( 'a', io.stdout, true )", func, "a", io.stdout, true ) 253 | succeeds( "func( 12 )", func, 12 ) 254 | succeeds( "func( 'a', 12 )", func, "a", 12 ) 255 | succeeds( "func( 12, {}, 'b', false, true, {}, 13 )", func, 12, {}, "b", false, true, {}, 13 ) 256 | fails( "func( io.stdout )", "expected.*got userdata.*too many", func, io.stdout ) 257 | fails( "func( 'a', 12, {}, false )", "expected.*got boolean", func, "a", 12, {}, false ) 258 | end ) 259 | 260 | 261 | -- methods 262 | test_all( "obj:method( number )", function() 263 | local obj = {} 264 | obj.method = annotate[[ 265 | obj:method( number ) 266 | ]] .. function() end 267 | 268 | succeeds( "obj:method( 12 )", obj.method, obj, 12 ) 269 | fails( "obj:method()", "missing.*index 1", obj.method, obj ) 270 | fails( "obj.method( 12 )", "expected.*no%. 0.*got number", obj.method, 12 ) 271 | fails( "obj.method()", "missing.*index 0", obj.method ) 272 | end ) 273 | 274 | 275 | -- custom type 276 | test_all( "func( number [, table], mytable ) ==> (table, boolean) / (mytable, number) ", function() 277 | local func = annotate[[ 278 | func( number, [table,] mytable ) ==> table, boolean 279 | ==> mytable, number 280 | ]] .. function( n ) 281 | if n == 1 then 282 | return {}, true 283 | elseif n == 2 then 284 | return mytable_new(), 2 285 | else 286 | return mytable_new(), "bla" 287 | end 288 | end 289 | 290 | succeeds( "func( 1, {}, mytable_new() )", func, 1, {}, mytable_new() ) 291 | succeeds( "func( 1, mytable_new() )", func, 1, mytable_new() ) 292 | succeeds( "func( 2, mytable_new() )", func, 2, mytable_new() ) 293 | fails( "func( 2, mytable_new(), {} )", "mytable expected.*got table.*too many arguments", func, 1, mytable_new(), {} ) 294 | fails( "func( 3, mytable_new() )", "expected.*got string.*expected.*got string", func, 3, mytable_new() ) 295 | end ) 296 | 297 | 298 | -- complex example 299 | test_all( "obj:method( a [, b [, c], ...] ) ==> boolean / (nil, string)", function() 300 | local obj = {} 301 | obj.method = annotate[=[ 302 | Some optional text (ignored)! 303 | 304 | obj:method( a [, b [, c], ...] ) 305 | ==> boolean -- when successful 306 | ==> nil, string -- in case of error 307 | a: integer -- an integer 308 | b: table/userdata -- an optional table or userdata 309 | -- comments can span several lines 310 | c: boolean -- a boolean flag 311 | ...: (number, string)* 312 | 313 | Some more text describing the function: 314 | ignored! 315 | ]=] .. function( self, i ) 316 | if i == 1 then 317 | return true 318 | elseif i == 2 then 319 | return nil, "msg" 320 | elseif i == 3 then 321 | return nil 322 | elseif i == 4 then 323 | return 17 324 | else 325 | return "abc" 326 | end 327 | end 328 | succeeds( "obj:method( 1 )", obj.method, obj, 1 ) 329 | succeeds( "obj:method( 2, {}, 4, 'four', 5, 'five' )", obj.method, obj, 2, {}, 4, "four", 5, "five" ) 330 | succeeds( "obj:method( 2, io.stdout, true )", obj.method, obj, 2, io.stdout, true ) 331 | fails( "obj.method( 1 )", "expected.*no%. 0.*got number", obj.method, 1 ) 332 | fails( "obj:method( 1.5 )", "integer expected.*got number", obj.method, obj, 1.5 ) 333 | fails( "obj:method( 2, true )", "expected.*got boolean.*too many arguments", obj.method, obj, 2, true ) 334 | fails( "obj:method( 2, 4, 'four' )", "expected.*got number.*too many arguments", obj.method, obj, 2, 4, "four" ) 335 | fails( "obj:method( 3 )", "missing return.*string", obj.method, obj, 3 ) 336 | fails( "obj:method( 4 )", "expected.*return value.*got number", obj.method, obj, 4 ) 337 | fails( "obj:method( 5 )", "expected.*return value.*got string", obj.method, obj, 5 ) 338 | end ) 339 | 340 | -------------------------------------------------------------------------------- /tests/annotate.help.test.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/lua 2 | 3 | package.path = [[../src/?.lua;]] .. package.path 4 | 5 | if _VERSION == "Lua 5.1" then 6 | bit32 = {} 7 | end 8 | 9 | local annotate = require( "annotate" ) 10 | local check = require( "annotate.check" ) 11 | local test = require( "annotate.test" ) 12 | local help = require( "annotate.help" ) 13 | 14 | -- load https://github.com/dlaurie/lua-ihelp 15 | local ldoc_help 16 | pcall( function() ldoc_help = require( "ihelp" ) end ) 17 | ldoc_help = ldoc_help and help:wrap( ldoc_help ) 18 | 19 | package.preload[ "a.b" ] = function() 20 | return { c = { d = annotate[=[help for a.b.c.d]=]..{} } } 21 | end 22 | 23 | local delim = ("="):rep( 70 ) 24 | 25 | example = annotate[=[ 26 | An `annotate` docstring for the `example` function. 27 | 28 | example( number ) 29 | ]=] .. 30 | function( a ) end 31 | 32 | --- An LDoc comment for `another` function 33 | -- Details here ... 34 | function another( a, b ) 35 | end 36 | 37 | 38 | help( example ) 39 | print( "###" ) 40 | help( another ) 41 | print( "###" ) 42 | help( "a.b.c.d" ) 43 | print( "###" ) 44 | 45 | if ldoc_help then 46 | ldoc_help( another ) 47 | print( "###" ) 48 | ldoc_help( example ) 49 | print( "###" ) 50 | ldoc_help"a.b.c.d" 51 | print( "###" ) 52 | ldoc_help"customize" 53 | print( "###" ) 54 | end 55 | 56 | print( pcall( example, "not a number" ) ) 57 | 58 | print( delim ) 59 | help( bit32 ) 60 | print( delim ) 61 | help( assert ) 62 | print( delim ) 63 | help( "table.concat" ) 64 | print( delim ) 65 | print( "searching for getfenv:" ) 66 | help:search( "getfenv" ) 67 | print( delim ) 68 | 69 | local cache = {} 70 | local pl = package.loaded 71 | local ref_types = { 72 | ["function"] = true, 73 | ["userdata"] = true, 74 | ["table"] = true, 75 | ["thread"] = true 76 | } 77 | 78 | local function check_doc( name, value ) 79 | name = name or "_G" 80 | value = value or _G 81 | local t = type( value ) 82 | if not ref_types[ t ] then 83 | return 84 | end 85 | if not help:lookup( value ) then 86 | print( "no docstring for", name ) 87 | end 88 | if t == "table" then 89 | cache[ value ] = true 90 | for k,v in pairs( value ) do 91 | if value ~= pl and type( k ) == "string" and 92 | k:match( "^[%a_][%w_]*$" ) and not cache[ v ] then 93 | check_doc( name.."."..k, v ) 94 | end 95 | end 96 | end 97 | end 98 | check_doc() 99 | 100 | --[[ 101 | for v,ds in help.iterate() do 102 | print( delim ) 103 | print( ds ) 104 | end 105 | --]] 106 | 107 | print( delim ) 108 | 109 | test( tonumber( os.getenv( "VERBOSE" ) ) ) 110 | 111 | -------------------------------------------------------------------------------- /tests/annotate.test.test.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/lua 2 | 3 | package.path = [[../src/?.lua;]] .. package.path 4 | 5 | local annotate = require( "annotate" ) 6 | local test = require( "annotate.test" ) 7 | 8 | 9 | example = annotate[=[ 10 | An `annotate` docstring for the `example` function. 11 | 12 | example( number ) 13 | 14 | Examples: 15 | 16 | > print( "hallo\nwelt" ) 17 | hallo 18 | welt 19 | > print( "ok" ) 20 | ok 21 | 22 | > a, b = 3, 4 23 | > = a + b 24 | 7 25 | 26 | > print( "[a-b]blub" ) 27 | [a-b]... 28 | 29 | Some other paragraph 30 | 31 | ]=] .. 32 | function( a ) end 33 | 34 | 35 | another = annotate[=[ 36 | ## The `another` Function ## 37 | 38 | This is just another function. 39 | 40 | ### Function Prototype ### 41 | 42 | another( a, b ) => number 43 | a: number 44 | b: number 45 | 46 | ### Examples ### 47 | 48 | > a = 2 49 | no output here 50 | > = 2+"x" 51 | ...attempt to perform arithmetic... 52 | > = F( 1, 2 ) 53 | 3 54 | > = 5 55 | 4 56 | 57 | ]=] .. 58 | function( a, b ) return a + b end 59 | 60 | 61 | third = annotate[=[ 62 | Example: 63 | > = 2+"x" 64 | 65 | Links: 66 | http://some.where.net/ 67 | ]=] .. 68 | function( x, y, z ) end 69 | 70 | 71 | fourth = annotate[=[ 72 | Examples: 73 | 74 | > = nil 75 | 76 | ]=] .. 77 | function() end 78 | 79 | fifth = annotate[=[ 80 | Test: 81 | 82 | > function f() 83 | 84 | ]=] .. 85 | function() end 86 | 87 | sixth = annotate[=[ 88 | Example: 89 | 90 | > function f() return 2; return 3 end 91 | 92 | ]=] .. 93 | function() end 94 | 95 | seventh = annotate[=[ 96 | seventh( [a,] ... ) ==> number 97 | a : number 98 | ...: string* 99 | 100 | ### EXAMPLES ### 101 | 102 | > function f( a ) 103 | >> return 2*a 104 | >> end 105 | > =f( 10 ) 106 | 20 107 | > =f( 20 ) 108 | 40 109 | 110 | ]=] .. 111 | function( a, ... ) end 112 | 113 | 114 | func = annotate[=[ 115 | This is function `func`. 116 | 117 | func( n ) ==> number 118 | n: number 119 | 120 | Examples: 121 | > return func( 1 ) 122 | 1 123 | > function f( n ) 124 | >> return func( n ) 125 | >> end 126 | > = f( 2 ) 127 | 2 128 | > = f( 2 ) -- this test will fail 129 | 3 130 | > print( "hello\nworld" ) 131 | hello 132 | world 133 | > = 2+"x" 134 | ...attempt to perform arithmetic... 135 | > (function() print( "xxx" ) end)() 136 | xxx 137 | > coroutine.wrap( function() print( "yyy" ) end )() 138 | yyy 139 | 140 | This is the end of the test code! 141 | ]=] .. 142 | function( n ) 143 | return n 144 | end 145 | 146 | 147 | test( tonumber( os.getenv( "VERBOSE" ) ) ) 148 | 149 | --------------------------------------------------------------------------------