Tcl has no types and and this is good. One disadvantage is that ugly syntax errors (typically typos) crash your program the first time you run it. Therefore you must care about running every piece of your code through interpreter by writing special test procedures. Syntax checking with XOTclIDE can find most of these errors (syntax errors) at editing time by simulating the interpreter. The syntax checker can parse and interpret code without running it.
XOTclIDE implements a static syntax checker. It parses Tcl/XOTcl procedures and finds errors that normally appear only at run time. Because XOTclIDE does not manage source code but manages a Tcl/XOTcl interpreter it always checks a method in the actual interpreter context. You cannot check your Tcl files without loading (source $your_file) the procedures into the interpreter. The following syntax checks are processed.
check all called procedures
check the count of arguments
simulate quote and command substitution
simulate evaluation of control structure commands (if, for, foreach, ...)
check variable visibility
check XOTcl self method calls. (my callMe; [self] callMe)
Syntax Checking can be used in two ways
Syntax check while editing or accepting code.
Run the syntax checker on projects, so you can check existing Tcl/XOTcl sources.
procs example {a} { set b [lindex $a 0] puts "$a $c" set e [lindex $a end dummy] foreach d $a { if {$d==a} { putd $d } } }
The syntax checker will find the following errors:
procs example {a} { set b [lindex $a 0] puts "$a $c" # unknown variable c set e [lindex $a end dummy] # await (2,2) arguments foreach d $a { if {$d==a} { putd $d # unknown proc } } }
Class Test -parameter {par1} Test instproc foo1 {a {b 1}} { puts "[self] $a $b" } # Method to check Test instproc foo2 {b} { my foo1 test my foo1 test 1 2 # await (1,2) arguments foreach elem $b { puts "[my par1] $elem" my par1 $elem my foo3 # unknown instproc } set c $d # unknown variable d }
To enable syntax checking while editing, click on the check-box in menu Figure 4.4, “Syntax Checker Dialog”)
-> . All accepted (saved) code will be syntax-checked. If errors are found a new window with syntax messages are displayed. You can see the corresponding code in the editor by clicking on the list items. (seeIf the errors shown by the syntax checker are not really errors or you have already corrected the errors you can press the button
. The code shown in the editor will be accepted without syntax checking.If you want to force syntax checking without accepting choose menu
-> -> .
You can launch this tool from the menu Check Selected. You can browse the errors by clicking the other two lists.
-> . Choose the components you will check and run the check with buttonYou can produce a protocol of checking as text file with menu
-> .The XOTclIDE syntax checker works by using its Tcl parser programmed in XOTcl (see component IDETclParser). It produces a parser tree that can also be used for other purposes. At this time the syntax highlighting is also based on this parser.
Other ways of using Tcl parser in Tcl.
Normalize source code (pretty print)
convert source codes from or to another object oriented Tcl. (ITcl)
Refactoring tools in the manner of Smalltalk.
See the PrsContext>checkTclCommand method. The syntax of all Tcl control command are coded as simple pieces of code.
# while proc [$command getElem 1] substituteContents [$command getElem 2] evalContents # set proc if {$count==2} { my addVariableFrom [$command getElem 1] } else { my checkVariableFrom [$command getElem 1] $notifier }
It should not be difficult to extend the semantics for more commands.
The syntax checker cannot simulate the full power of a Tcl interpreter. For example, it interprets double substitution as:
set a putd $a hallo set a c set $a 2 puts $c
"$a hallo" will be not reported as an error but "puts $c" will report the error "unknown variable c".
If you want to avoid syntax checking for one method place the string "no syntax check" in the method (probably as a comment).
If you want to force the checker to accept a variable use "add variables (varName varName2)"
# add variables (c) set a c set $a 3 puts $c
It is also not possible to check referenced object calls:
set a [MyClass new] $a doJob # also direct call by object name MyClass myObject myObject doJob
The first method call will be not checked. The checker has no information about what is $a. The second method call will be reported with the error "no such proc" (myObject). This second type of call should be very rare in XOTcl programs (besides global singleton objects).
To solve the problem the checker would need more type information. Type information could be coded as meta information in the class. For example:
Class A A addMetaVariable drawContext DrawContext A instproc draw {} { my instvar drawContext $drawContext drawLine 0 2 0 50 }
In this case the Syntax Checker would know that "drawContext" references an object of class "DrawContext". The same thing could be done for method arguments or even all variables by using special in-line directives
set a [MyClass new] # variableType a MyClass $a doJob
This could be a back door to make Tcl type-safe if you want. In fact, the meta type information could be collected by doing analysis of a running system (for example by using XOTcl filters). This type informations could also be used to build XOTcl assertions.
There is a chance of making a very powerful Tcl development system even with type safe syntax checking.