Spaces:
Runtime error
Runtime error
| # git-gui simple class/object fake-alike | |
| # Copyright (C) 2007 Shawn Pearce | |
| proc class {class body} { | |
| if {[namespace exists $class]} { | |
| error "class $class already declared" | |
| } | |
| namespace eval $class " | |
| variable __nextid 0 | |
| variable __sealed 0 | |
| variable __field_list {} | |
| variable __field_array | |
| proc cb {name args} { | |
| upvar this this | |
| concat \[list ${class}::\$name \$this\] \$args | |
| } | |
| " | |
| namespace eval $class $body | |
| } | |
| proc field {name args} { | |
| set class [uplevel {namespace current}] | |
| variable ${class}::__sealed | |
| variable ${class}::__field_array | |
| switch [llength $args] { | |
| 0 { set new [list $name] } | |
| 1 { set new [list $name [lindex $args 0]] } | |
| default { error "wrong # args: field name value?" } | |
| } | |
| if {$__sealed} { | |
| error "class $class is sealed (cannot add new fields)" | |
| } | |
| if {[catch {set old $__field_array($name)}]} { | |
| variable ${class}::__field_list | |
| lappend __field_list $new | |
| set __field_array($name) 1 | |
| } else { | |
| error "field $name already declared" | |
| } | |
| } | |
| proc constructor {name params body} { | |
| set class [uplevel {namespace current}] | |
| set ${class}::__sealed 1 | |
| variable ${class}::__field_list | |
| set mbodyc {} | |
| append mbodyc {set this } $class | |
| append mbodyc {::__o[incr } $class {::__nextid]::__d} \; | |
| append mbodyc {create_this } $class \; | |
| append mbodyc {set __this [namespace qualifiers $this]} \; | |
| if {$__field_list ne {}} { | |
| append mbodyc {upvar #0} | |
| foreach n $__field_list { | |
| set n [lindex $n 0] | |
| append mbodyc { ${__this}::} $n { } $n | |
| regsub -all @$n\\M $body "\${__this}::$n" body | |
| } | |
| append mbodyc \; | |
| foreach n $__field_list { | |
| if {[llength $n] == 2} { | |
| append mbodyc \ | |
| {set } [lindex $n 0] { } [list [lindex $n 1]] \; | |
| } | |
| } | |
| } | |
| append mbodyc $body | |
| namespace eval $class [list proc $name $params $mbodyc] | |
| } | |
| proc method {name params body {deleted {}} {del_body {}}} { | |
| set class [uplevel {namespace current}] | |
| set ${class}::__sealed 1 | |
| variable ${class}::__field_list | |
| set params [linsert $params 0 this] | |
| set mbodyc {} | |
| append mbodyc {set __this [namespace qualifiers $this]} \; | |
| switch $deleted { | |
| {} {} | |
| ifdeleted { | |
| append mbodyc {if {![namespace exists $__this]} } | |
| append mbodyc \{ $del_body \; return \} \; | |
| } | |
| default { | |
| error "wrong # args: method name args body (ifdeleted body)?" | |
| } | |
| } | |
| set decl {} | |
| foreach n $__field_list { | |
| set n [lindex $n 0] | |
| if {[regexp -- $n\\M $body]} { | |
| if { [regexp -all -- $n\\M $body] == 1 | |
| && [regexp -all -- \\\$$n\\M $body] == 1 | |
| && [regexp -all -- \\\$$n\\( $body] == 0} { | |
| regsub -all \ | |
| \\\$$n\\M $body \ | |
| "\[set \${__this}::$n\]" body | |
| } else { | |
| append decl { ${__this}::} $n { } $n | |
| regsub -all @$n\\M $body "\${__this}::$n" body | |
| } | |
| } | |
| } | |
| if {$decl ne {}} { | |
| append mbodyc {upvar #0} $decl \; | |
| } | |
| append mbodyc $body | |
| namespace eval $class [list proc $name $params $mbodyc] | |
| } | |
| proc create_this {class} { | |
| upvar this this | |
| namespace eval [namespace qualifiers $this] [list proc \ | |
| [namespace tail $this] \ | |
| [list name args] \ | |
| "eval \[list ${class}::\$name $this\] \$args" \ | |
| ] | |
| } | |
| proc delete_this {{t {}}} { | |
| if {$t eq {}} { | |
| upvar this this | |
| set t $this | |
| } | |
| set t [namespace qualifiers $t] | |
| if {[namespace exists $t]} {namespace delete $t} | |
| } | |
| proc make_dialog {t w args} { | |
| upvar $t top $w pfx this this | |
| global use_ttk | |
| uplevel [linsert $args 0 make_toplevel $t $w] | |
| catch {wm attributes $top -type dialog} | |
| pave_toplevel $pfx | |
| } | |
| proc make_toplevel {t w args} { | |
| upvar $t top $w pfx this this | |
| if {[llength $args] % 2} { | |
| error "make_toplevel topvar winvar {options}" | |
| } | |
| set autodelete 1 | |
| foreach {name value} $args { | |
| switch -exact -- $name { | |
| -autodelete {set autodelete $value} | |
| default {error "unsupported option $name"} | |
| } | |
| } | |
| if {$::root_exists || [winfo ismapped .]} { | |
| regsub -all {::} $this {__} w | |
| set top .$w | |
| set pfx $top | |
| toplevel $top | |
| set ::root_exists 1 | |
| } else { | |
| set top . | |
| set pfx {} | |
| } | |
| if {$autodelete} { | |
| wm protocol $top WM_DELETE_WINDOW " | |
| [list delete_this $this] | |
| [list destroy $top] | |
| " | |
| } | |
| } | |
| ## auto_mkindex support for class/constructor/method | |
| ## | |
| auto_mkindex_parser::command class {name body} { | |
| variable parser | |
| variable contextStack | |
| set contextStack [linsert $contextStack 0 $name] | |
| $parser eval [list _%@namespace eval $name] $body | |
| set contextStack [lrange $contextStack 1 end] | |
| } | |
| auto_mkindex_parser::command constructor {name args} { | |
| variable index | |
| variable scriptFile | |
| append index [list set auto_index([fullname $name])] \ | |
| [format { [list source [file join $dir %s]]} \ | |
| [file split $scriptFile]] "\n" | |
| } | |