ttclcheck is hosted on github as part of TclSqueak projects. Please use github to report issues.
TclSqueak - new life for Tcl.
|
tclsh ttclcheck.tcl mycode.tclOptions:
tclsh ttclcheck.tcl -html -od htmloutput -scan myprojectdir -oldstringop -w signatures.repoCheck all Tcl files in directory "myprojectdir" recursively. Generate HTML site in directory "htmloutput". Allow usage of "==" operator for string and write signatures file to "signatures.repo".
ttclcheck produces output similar to gcc compiler (file name + line number + error message). Many good programmer editors (emacs, vim, notpad++) has build in (or plugin) support for executing external programs (make, compiler) and displaying their output with line alignment. Also Eclipse for C/C++ has compiler output parser which can be used. The simplest way to setup Eclipse is to run ttclcheck from Makefile so the input will be automatically linked with source code.
You may also use TclSqueak which use intensively the syntax checker as own library.
I use Notepad++ http://notepad-plus-plus.org/ with plugin NppExec (http://sourceforge.net/projects/npp-plugins/files/NppExec/)
Ttclcheck has build in repository of all Tcl, Tk, TclOO, XOTcl and ITcl procedures and instance methods. The signatures do not include only the argument count but also the types of argument and type of return value. By analyzing code the program exchanges the signature repository. The program know the special meaning of tcl control structures as (if, foreach, while) and evaluates their arguments as scripts. Also Tcl expression are parsed and checked (expr command). The repository contains: commands, methods, class and object definition, global variables, namespaces (export and imports)
The idea of tracking types comes from new modern programming languages which uses so called type inference. The compiler can derive often the type of variable but its initialization. The haskell programming language offers even strongly typing without type declaration. Tcl was never designed for such things but it is possible to derive much types from static code analyze (70-80%).
Additional ttclcheck can derive the types from usage of variables as parameters to know procedures (methods). The tracking types is especially important to provide method check on objects (like tk widget or TclOO, XOTcl, ITcl instances) which are usually hold as references in variables.
# deriving types from initialization # $l has type list set l [list a b] # o is reference to instance of Class MyClass (XOTcl) Class create MyClass set o [MyClass new] # deriving types by usage # $l ist a list lappend l 1 2 # $b is reference to widget instance of class button set b .button button $b -text "my button" # now we can check if there is method "invoke" for class button $b invoke # x must be numeric if {$x>0} { }For more information just play with program or look at the source code.
package require XOTcl namespace import ::xotcl::* # scalar and array set a 1 puts $a(1) set arr(1) 1 puts $arr # argument check set a a a info wrong # type check set a [list 1 2 3] append a "c" set a "aaa" # type check lappend a elem # variables puts $unknown # object orientation Class create MyClass MyClass instproc foo {} { puts "foo" } set i [MyClass new] $i foo $i foo 1 2 $i bar MyClass myinst myinst foo myinst foo 1 # tk set b .b button $b -text "my button" $b invoke $b invoke 1 2 button .c -unknown "my button" button .c -text "my button" -width twofingers # recognizion of upvar proc add2 {var_ref} { upvar $var_ref var incr var 2 } puts $bv set mylist [list 1 2 3] # type check add2 mylist
project | lines | errors | errors % lines | unknown parameters types | unknown global variables types | run time | lines/sec |
---|---|---|---|---|---|---|---|
ased3.0 | 15811 | 492 | 3.11% | 25.51% | 10.27% | 00:02:35 | 101.99 |
CrowTDE | 28150 | 676 | 2.40% | 26.24% | 6.46% | 00:05:02 | 93.06 |
filerunner | 18146 | 572 | 3.15% | 35.81% | 6.17% | 00:02:37 | 115.37 |
iTclC-Rev7 | 4609 | 97 | 2.10% | 37.81% | 30.89% | 00:00:36 | 126.17 |
nagelfar1112 | 9784 | 121 | 1.24% | 18.48% | 11.27% | 00:01:39 | 98.10 |
ramdebugger | 68049 | 2490 | 3.66% | 30.70% | 7.40% | 00:10:50 | 104.59 |
scilab | 40465 | 995 | 2.46% | 21.41% | 17.31% | 00:05:51 | 115.21 |
SpecTcl | 22312 | 780 | 3.50% | 29.55% | 8.28% | 00:03:03 | 121.76 |
tcltalk | 18866 | 458 | 2.43% | 31.12% | 4.58% | 00:02:24 | 130.60 |
tkgames-1.2 | 17284 | 468 | 2.71% | 28.61% | 14.41% | 00:01:56 | 148.70 |
tloona-1.3.2 | 13911 | 403 | 2.90% | 32.84% | 8.97% | 00:02:31 | 91.56 |
vtcl-1.6.1a1 | 29416 | 1027 | 3.49% | 29.91% | 9.18% | 00:04:25 | 110.93 |
-html
is specified.
The produced html site contain not only highlighted source code but also links and backlinks to definitions.
Variables contain tool-tips of type if recognized and also marked errors.
There are also navigation package as trees. It uses java doc style.
The html output is ideal to browse bigger code and shows by the way what would be possible in advanced Tcl IDE.
HTML Site of ttclcheck source code
# ttclcheck assumes that following may be error (typical Tcl beginner error) # but is some cases it could be intended set $v 1 # ttclcheck would prefer "eq" operator for this. # if you use == also for string comparetion use option -oldstringop if {$a == "string"} { }Code that use meta programming (as OO libraris) can not be checked sucessfully. Either the checker produces errors for correct code or do not check the code parts at all. Ttclcheck has only build in support for XOTcl and ITcl. (Anyway other OO System would be possible). The checking can be also influeed by using special comments The comment need to start with #ttcl
comment | meaning |
---|---|
#ttc vartype {varname} {vartype} | add variable {varname} as {vartype} to context |
#ttc rettype {vartype} | define the type of returned value |
#ttc noerror | do not report error from this line |
#ttc varrefref | do not complain about double referencing as set $varname 1 in current proc |
no syntax check | do not check the proc which contains this string |
# example proc foo {a} { #ttcl vartype a int #ttcl vartype b int #ttcl vartype c int #ttcl rettype int foreach v {a b c} { set $v 1 } noSuchProc 1 2; #ttcl noerror puts "$a $b $c"" return $a }