Index: generic/predefined.h =================================================================== diff -u -r0c8c36d48b1a146780b7ba8966196ad1b7075dda -r6fa467e12f7a039c928b3096175a73414b5f26ff --- generic/predefined.h (.../predefined.h) (revision 0c8c36d48b1a146780b7ba8966196ad1b7075dda) +++ generic/predefined.h (.../predefined.h) (revision 6fa467e12f7a039c928b3096175a73414b5f26ff) @@ -51,7 +51,7 @@ "lappend methods $name}\n" "return \"valid options are: [join [lsort $methods] {, }]\"}\n" "objectInfo method unknown {method args} {\n" -"error \"unknown info option \\\"$method\\\"; [.info info]\"}\n" +"error \"[::xotcl::self] unknown info option \\\"$method\\\"; [.info info]\"}\n" "classInfo method info {cl} {\n" "set methods [list]\n" "foreach m [::info commands ::xotcl::classInfo::*] {\n" @@ -60,132 +60,8 @@ "lappend methods $name}\n" "return \"valid options are: [join [lsort $methods] {, }]\"}\n" "classInfo method unknown {method args} {\n" -"error \"unknown info option \\\"$method\\\"; [.info info]\"}\n" +"error \"[::xotcl::self] unknown info option \\\"$method\\\"; [.info info]\"}\n" "namespace export Object Class}\n" -"namespace eval ::xotcl {\n" -"::xotcl::createobjectsystem ::xotcl::Object ::xotcl::Class\n" -"foreach cmd [info command ::xotcl::cmd::Object::*] {\n" -"::xotcl::alias Object [namespace tail $cmd] $cmd}\n" -"foreach cmd {array append eval incr lappend set subst unset trace} {\n" -"::xotcl::alias Object $cmd -objscope ::$cmd}\n" -"foreach cmd [info command ::xotcl::cmd::Class::*] {\n" -"::xotcl::alias Class [namespace tail $cmd] $cmd}\n" -"unset cmd\n" -"::xotcl::methodproperty Object destroy static true\n" -"::xotcl::methodproperty Class alloc static true\n" -"::xotcl::methodproperty Class dealloc static true\n" -"::xotcl::methodproperty Class create static true\n" -"Class method unknown {args} {\n" -"eval my create $args}\n" -"Object method unknown {m args} {\n" -"if {![self isnext]} {\n" -"error \"[self]: unable to dispatch method '$m'\"}}\n" -"Object method init args {}\n" -"Object method objectparameter {} {;}\n" -"Class create ::xotcl::ParameterType\n" -"foreach cmd [info command ::xotcl::cmd::ParameterType::*] {\n" -"::xotcl::alias ::xotcl::ParameterType [namespace tail $cmd] $cmd}\n" -"::xotcl::alias ::xotcl::ParameterType type=switch ::xotcl::cmd::ParameterType::type=boolean\n" -"::xotcl::ParameterType create ::xotcl::parameterType\n" -"Object create ::xotcl::objectInfo\n" -"Object create ::xotcl::classInfo\n" -"foreach cmd [info command ::xotcl::cmd::ObjectInfo::*] {\n" -"::xotcl::alias ::xotcl::objectInfo [namespace tail $cmd] $cmd\n" -"::xotcl::alias ::xotcl::classInfo [namespace tail $cmd] $cmd}\n" -"foreach cmd [info command ::xotcl::cmd::ClassInfo::*] {\n" -"::xotcl::alias ::xotcl::classInfo [namespace tail $cmd] $cmd}\n" -"unset cmd\n" -"::xotcl::alias ::xotcl::objectInfo is ::xotcl::is\n" -"::xotcl::alias ::xotcl::classInfo is ::xotcl::is\n" -"::xotcl::alias ::xotcl::classInfo classparent ::xotcl::cmd::ObjectInfo::parent\n" -"::xotcl::alias ::xotcl::classInfo classchildren ::xotcl::cmd::ObjectInfo::children\n" -"Object instforward info -onerror ::xotcl::infoError ::xotcl::objectInfo %1 {%@2 %self}\n" -"Class instforward info -onerror ::xotcl::infoError ::xotcl::classInfo %1 {%@2 %self}\n" -"proc ::xotcl::infoError msg {\n" -"regsub -all \" \" $msg \"\" msg\n" -"regsub -all \" \" $msg \"\" msg\n" -"regsub {\\\"} $msg \"\\\"info \" msg\n" -"error $msg \"\"}\n" -"objectInfo method info {obj} {\n" -"set methods [list]\n" -"foreach m [::info commands ::xotcl::objectInfo::*] {\n" -"set name [namespace tail $m]\n" -"if {$name eq \"unknown\"} continue\n" -"lappend methods $name}\n" -"return \"valid options are: [join [lsort $methods] {, }]\"}\n" -"objectInfo method unknown {method args} {\n" -"error \"unknown info option \\\"$method\\\"; [.info info]\"}\n" -"classInfo method info {cl} {\n" -"set methods [list]\n" -"foreach m [::info commands ::xotcl::classInfo::*] {\n" -"set name [namespace tail $m]\n" -"if {$name eq \"unknown\"} continue\n" -"lappend methods $name}\n" -"return \"valid options are: [join [lsort $methods] {, }]\"}\n" -"classInfo method unknown {method args} {\n" -"error \"unknown info option \\\"$method\\\"; [.info info]\"}\n" -"# info instargs\n" -"# istype\n" -"proc ::xotcl::info_args {inst o method} {\n" -"set result [list]\n" -"foreach \\\n" -"argName [::xotcl::classInfo ${inst}params $o $method -varNames] \\\n" -"flag [::xotcl::classInfo ${inst}params $o $method] {\n" -"if {[string match -* $flag]} continue\n" -"lappend result $argName}\n" -"return $result}\n" -"proc ::xotcl::info_nonposargs {inst o method} {\n" -"set result [list]\n" -"foreach flag [::xotcl::classInfo ${inst}params $o $method] {\n" -"if {![string match -* $flag]} continue\n" -"lappend result $flag}\n" -"return $result}\n" -"proc ::xotcl::info_default {inst o method arg varName} {\n" -"foreach \\\n" -"argName [::xotcl::classInfo ${inst}params $o $method -varNames] \\\n" -"flag [::xotcl::classInfo ${inst}params $o $method] {\n" -"if {$argName eq $arg} {\n" -"upvar 3 $varName default\n" -"if {[llength $flag] == 2} {\n" -"set default [lindex $flag 1]\n" -"return 1}\n" -"set default \"\"\n" -"return 0}}\n" -"error \"procedure \\\"$method\\\" doesn't have an argument \\\"$varName\\\"\"}\n" -"classInfo method instargs {o method} {::xotcl::info_args inst $o $method}\n" -"classInfo method args {o method} {::xotcl::info_args \"\" $o $method}\n" -"objectInfo method args {o method} {::xotcl::info_args \"\" $o $method}\n" -"classInfo method instnonposargs {o method} {::xotcl::info_nonposargs inst $o $method}\n" -"classInfo method nonposargs {o method} {::xotcl::info_nonposargs \"\" $o $method}\n" -"objectInfo method nonposargs {o method} {::xotcl::info_nonposargs \"\" $o $method}\n" -"classInfo method instdefault {o method arg var} {::xotcl::info_default inst $o $method $arg $var}\n" -"classInfo method default {o method arg var} {::xotcl::info_default \"\" $o $method $arg $var}\n" -"objectInfo method default {o method arg var} {::xotcl::info_default \"\" $o $method $arg $var}\n" -"Object method isobject {{object:substdefault \"[self]\"}} {::xotcl::is $object object}\n" -"Object method isclass {{class:substdefault \"[self]\"}} {::xotcl::is $class class}\n" -"Object method ismetaclass {{class:substdefault \"[self]\"}} {::xotcl::is $class metaclass}\n" -"Object method ismixin {class} {::xotcl::is [self] mixin $class}\n" -"Object method istype {class} {::xotcl::is [self] type $class}\n" -"Object method proc {name arglist body precondition:optional postcondition:optional} {\n" -"set cmd [list my method $name $arglist $body]\n" -"if {[info exists precondition]} {lappend cmd -precondition $precondition}\n" -"if {[info exists postcondition]} {lappend cmd -postcondition $postcondition}\n" -"eval $cmd}\n" -"Class method proc {name arglist body precondition:optional postcondition:optional} {\n" -"set cmd [list my method -per-object $name $arglist $body]\n" -"if {[info exists precondition]} {lappend cmd -precondition $precondition}\n" -"if {[info exists postcondition]} {lappend cmd -postcondition $postcondition}\n" -"eval $cmd}\n" -"Class method instproc {name arglist body precondition:optional postcondition:optional} {\n" -"set cmd [list my method $name $arglist $body]\n" -"if {[info exists precondition]} {lappend cmd -precondition $precondition}\n" -"if {[info exists postcondition]} {lappend cmd -postcondition $postcondition}\n" -"eval $cmd}\n" -"Object create ::xotcl::@\n" -"@ method unknown args {}\n" -"proc myproc {args} {linsert $args 0 [::xotcl::self]}\n" -"proc myvar {var} {.requireNamespace; return [::xotcl::self]::$var}\n" -"namespace export Object Class @ myproc myvar Attribute}\n" "::xotcl2::Class create ::xotcl::MetaSlot\n" "::xotcl::relation ::xotcl::MetaSlot superclass ::xotcl2::Class\n" "::xotcl::MetaSlot method new args {\n" @@ -217,10 +93,6 @@ "unset arg}\n" "lappend parameterdefinitions $parameterdefinition}\n" "return $parameterdefinitions}\n" -"::xotcl::Object method objectparameter {} {\n" -"set parameterdefinitions [::xotcl::parametersFromSlots [self]]\n" -"lappend parameterdefinitions args\n" -"return $parameterdefinitions}\n" "::xotcl2::Object method objectparameter {} {\n" "set parameterdefinitions [::xotcl::parametersFromSlots [self]]\n" "if {[::xotcl::is [self] class]} {\n" @@ -240,16 +112,13 @@ "foreach att $definitions {\n" "if {[llength $att]>1} {foreach {att default} $att break}\n" "if {[info exists default]} {\n" -"foreach i [$class info instances] {\n" +"foreach i [::xotcl::dispatch $class ::xotcl::cmd::ClassInfo::instances $class] {\n" "if {![$i exists $att]} {\n" "if {[string match {*[*]*} $default]} {\n" "set default [::xotcl::dispatch $i -objscope ::eval subst $default]}\n" "::xotcl::setinstvar $i $att $default}}\n" "unset default}}\n" "$class invalidateobjectparameter}\n" -"createBootstrapAttributeSlots ::xotcl::Class {\n" -"{__default_superclass ::xotcl::Object}\n" -"{__default_metaclass ::xotcl::Class}}\n" "createBootstrapAttributeSlots ::xotcl::Slot {\n" "{name \"[namespace tail [::xotcl::self]]\"}\n" "{domain \"[lindex [regexp -inline {^(.*)::slot::[^:]+$} [::xotcl::self]] 1]\"}\n" @@ -287,9 +156,9 @@ "::xotcl::Slot method init {args} {\n" "set forwarder [expr {${.per-object} ? \"forward\" : \"instforward\"}]\n" "if {${.domain} eq \"\"} {\n" -"set .domain [::xotcl::self callingobject]} else {\n" -"${.domain} invalidateobjectparameter}\n" +"set .domain [::xotcl::self callingobject]}\n" "if {${.domain} ne \"\"} {\n" +"${.domain} invalidateobjectparameter\n" "${.domain} $forwarder ${.name} -default [${.manager} defaultmethods] ${.manager} %1 %self %proc}}\n" "::xotcl::MetaSlot create ::xotcl::InfoSlot\n" "createBootstrapAttributeSlots ::xotcl::InfoSlot {\n" @@ -325,7 +194,7 @@ "if {![set .multivalued]} {\n" "error \"Property $prop of ${.domain}->$obj ist not multivalued\"}\n" "$obj $prop [linsert [$obj info $prop -guards] $pos $value]}\n" -"foreach os {::xotcl ::xotcl2} {\n" +"proc ::xotcl::register_system_slots {os} {\n" "${os}::Object alloc ${os}::Class::slot\n" "${os}::Object alloc ${os}::Object::slot\n" "::xotcl::InfoSlot create ${os}::Class::slot::superclass -type relation\n" @@ -341,9 +210,9 @@ "::xotcl::InterceptorSlot create ${os}::Class::slot::instfilter \\\n" "-elementtype \"\" \\\n" "-type relation}\n" +"::xotcl::register_system_slots ::xotcl2\n" "::xotcl::MetaSlot invalidateobjectparameter\n" "::xotcl::MetaSlot create ::xotcl::Attribute -superclass ::xotcl::Slot\n" -"::xotcl::relation ::xotcl::Attribute superclass ::xotcl::Slot\n" "createBootstrapAttributeSlots ::xotcl::Attribute {\n" "{value_check once}\n" "initcmd\n" @@ -437,23 +306,6 @@ "namespace eval $object $cmds}}\n" "::xotcl2::Class instforward slots %self contains \\\n" "-object {%::xotcl::dispatch [::xotcl::self] -objscope ::subst [::xotcl::self]::slot}\n" -"::xotcl::Object method contains {\n" -"{-withnew:boolean true}\n" -"-object\n" -"{-class ::xotcl2::Object}\n" -"cmds} {\n" -"if {![info exists object]} {set object [::xotcl::self]}\n" -"if {![::xotcl::is $object object]} {$class create $object}\n" -"$object requireNamespace\n" -"if {$withnew} {\n" -"set m [::xotcl::ScopedNew new \\\n" -"-inobject $object -withclass $class -volatile]\n" -"::xotcl2::Class instmixin add $m end\n" -"namespace eval $object $cmds\n" -"::xotcl2::Class instmixin delete $m} else {\n" -"namespace eval $object $cmds}}\n" -"::xotcl::Class instforward slots %self contains \\\n" -"-object {%::xotcl::dispatch [::xotcl::self] -objscope ::subst [::xotcl::self]::slot}\n" "::xotcl2::Class method parameter arglist {\n" "if {![::xotcl::is [::xotcl::self]::slot object]} {\n" "::xotcl2::Object create [::xotcl::self]::slot}\n" @@ -505,39 +357,11 @@ "$po unset -nocomplain $instvar}} else {\n" ".instparametercmd $name}}}\n" "::xotcl::setinstvar [::xotcl::self]::slot __parameter $arglist}\n" -"::xotcl::Object method self {} {::xotcl::self}\n" -"::xotcl::Object method defaultmethod {} {\n" -"return [::xotcl::self]}\n" -"::xotcl::Object method hasclass cl {\n" -"if {[::xotcl::is [self] mixin $cl]} {return 1}\n" -"::xotcl::is [self] type $cl}\n" -"::xotcl::Class method allinstances {} {\n" -"return [.info instances -closure]}\n" -"::xotcl::alias ::xotcl::Class parameter ::xotcl::classes::xotcl2::Class::parameter\n" -"::xotcl::alias ::xotcl2::Object defaultmethod ::xotcl::classes::xotcl::Object::defaultmethod\n" -"::xotcl::Object method -per-object unsetExitHandler {} {\n" -"::xotcl::Object method -per-object __exitHandler {} {\n" -";}}\n" -"::xotcl::Object unsetExitHandler\n" -"::xotcl::Object method -per-object setExitHandler {newbody} {\n" -"::xotcl::Object method -per-object __exitHandler {} $newbody}\n" -"::xotcl::Object method -per-object getExitHandler {} {\n" -"::xotcl::Object info body __exitHandler}\n" -"proc ::xotcl::__exitHandler {} {\n" -"::xotcl::Object __exitHandler}\n" -"::xotcl::Object method abstract {methtype methname arglist} {\n" -"if {$methtype ne \"proc\" && $methtype ne \"instproc\" && $methtype ne \"method\"} {\n" -"error \"invalid method type '$methtype', \\\n" -"must be either 'proc', 'instproc' or 'method'.\"}\n" -".$methtype $methname $arglist \"\n" -"if {!\\[::xotcl::self isnextcall\\]} {\n" -"error \\\"Abstract method $methname $arglist called\\\"} else {::xotcl::next}\n" -"\"}\n" -"::xotcl2::Class create ::xotcl::Object::CopyHandler -parameter {\n" +"::xotcl2::Class create ::xotcl::CopyHandler -parameter {\n" "{targetList \"\"}\n" "{dest \"\"}\n" "objLength}\n" -"::xotcl::Object::CopyHandler method makeTargetList t {\n" +"::xotcl::CopyHandler method makeTargetList t {\n" "lappend .targetList $t\n" "if {[::xotcl::is $t object]} {\n" "if {[$t info hasnamespace]} {\n" @@ -548,13 +372,13 @@ "lappend children [namespace children $t]}}\n" "foreach c $children {\n" ".makeTargetList $c}}\n" -"::xotcl::Object::CopyHandler method copyNSVarsAndCmds {orig dest} {\n" +"::xotcl::CopyHandler method copyNSVarsAndCmds {orig dest} {\n" "::xotcl::namespace_copyvars $orig $dest\n" "::xotcl::namespace_copycmds $orig $dest}\n" -"::xotcl::Object::CopyHandler method getDest origin {\n" +"::xotcl::CopyHandler method getDest origin {\n" "set tail [string range $origin [set .objLength] end]\n" "return ::[string trimleft [set .dest]$tail :]}\n" -"::xotcl::Object::CopyHandler method copyTargets {} {\n" +"::xotcl::CopyHandler method copyTargets {} {\n" "foreach origin [set .targetList] {\n" "set dest [.getDest $origin]\n" "if {[::xotcl::is $origin object]} {\n" @@ -596,14 +420,191 @@ "set newslot ${dest}::slot::[namespace tail $oldslot]\n" "if {[$oldslot domain] eq $origin} {$newslot domain $cl}\n" "if {[$oldslot manager] eq $oldslot} {$newslot manager $newslot}}}}}\n" -"::xotcl::Object::CopyHandler method copy {obj dest} {\n" +"::xotcl::CopyHandler method copy {obj dest} {\n" "set .objLength [string length $obj]\n" "set .dest $dest\n" ".makeTargetList $obj\n" ".copyTargets}\n" +"namespace eval ::xotcl {\n" +"::xotcl::createobjectsystem ::xotcl::Object ::xotcl::Class\n" +"foreach cmd [info command ::xotcl::cmd::Object::*] {\n" +"::xotcl::alias Object [namespace tail $cmd] $cmd}\n" +"foreach cmd {array append eval incr lappend set subst unset trace} {\n" +"::xotcl::alias Object $cmd -objscope ::$cmd}\n" +"foreach cmd [info command ::xotcl::cmd::Class::*] {\n" +"::xotcl::alias Class [namespace tail $cmd] $cmd}\n" +"unset cmd\n" +"::xotcl::methodproperty Object destroy static true\n" +"::xotcl::methodproperty Class alloc static true\n" +"::xotcl::methodproperty Class dealloc static true\n" +"::xotcl::methodproperty Class create static true\n" +"Class method unknown {args} {\n" +"eval my create $args}\n" +"Object method unknown {m args} {\n" +"if {![self isnext]} {\n" +"error \"[self]: unable to dispatch method '$m'\"}}\n" +"Object method init args {}\n" +"Object method objectparameter {} {;}\n" +"Class create ::xotcl::ParameterType\n" +"foreach cmd [info command ::xotcl::cmd::ParameterType::*] {\n" +"::xotcl::alias ::xotcl::ParameterType [namespace tail $cmd] $cmd}\n" +"::xotcl::alias ::xotcl::ParameterType type=switch ::xotcl::cmd::ParameterType::type=boolean\n" +"::xotcl::ParameterType create ::xotcl::parameterType\n" +"::xotcl::Object method objectparameter {} {\n" +"set parameterdefinitions [::xotcl::parametersFromSlots [self]]\n" +"lappend parameterdefinitions args\n" +"return $parameterdefinitions}\n" +"createBootstrapAttributeSlots ::xotcl::Class {\n" +"{__default_superclass ::xotcl::Object}\n" +"{__default_metaclass ::xotcl::Class}}\n" +"::xotcl::register_system_slots ::xotcl\n" +"Object create ::xotcl::objectInfo\n" +"Object create ::xotcl::classInfo\n" +"foreach cmd [::info command ::xotcl::cmd::ObjectInfo::*] {\n" +"::xotcl::alias ::xotcl::objectInfo [namespace tail $cmd] $cmd\n" +"::xotcl::alias ::xotcl::classInfo [namespace tail $cmd] $cmd}\n" +"foreach cmd [::info command ::xotcl::cmd::ClassInfo::*] {\n" +"::xotcl::alias ::xotcl::classInfo [namespace tail $cmd] $cmd}\n" +"unset cmd\n" +"::xotcl::alias ::xotcl::objectInfo is ::xotcl::is\n" +"::xotcl::alias ::xotcl::classInfo is ::xotcl::is\n" +"::xotcl::alias ::xotcl::classInfo classparent ::xotcl::cmd::ObjectInfo::parent\n" +"::xotcl::alias ::xotcl::classInfo classchildren ::xotcl::cmd::ObjectInfo::children\n" +"Object instforward info -onerror ::xotcl::infoError ::xotcl::objectInfo %1 {%@2 %self}\n" +"Class instforward info -onerror ::xotcl::infoError ::xotcl::classInfo %1 {%@2 %self}\n" +"proc ::xotcl::infoError msg {\n" +"regsub -all \" \" $msg \"\" msg\n" +"regsub -all \" \" $msg \"\" msg\n" +"regsub {\\\"} $msg \"\\\"info \" msg\n" +"error $msg \"\"}\n" +"objectInfo method info {obj} {\n" +"set methods [list]\n" +"foreach m [::info commands ::xotcl::objectInfo::*] {\n" +"set name [namespace tail $m]\n" +"if {$name eq \"unknown\"} continue\n" +"lappend methods $name}\n" +"return \"valid options are: [join [lsort $methods] {, }]\"}\n" +"objectInfo method unknown {method args} {\n" +"error \"[::xotcl::self] unknown info option \\\"$method\\\"; [.info info]\"}\n" +"classInfo method info {cl} {\n" +"set methods [list]\n" +"foreach m [::info commands ::xotcl::classInfo::*] {\n" +"set name [namespace tail $m]\n" +"if {$name eq \"unknown\"} continue\n" +"lappend methods $name}\n" +"return \"valid options are: [join [lsort $methods] {, }]\"}\n" +"classInfo method unknown {method args} {\n" +"error \"[::xotcl::self] unknown info option \\\"$method\\\"; [.info info]\"}\n" +"# info instargs\n" +"# istype\n" +"proc ::xotcl::info_args {inst o method} {\n" +"set result [list]\n" +"foreach \\\n" +"argName [::xotcl::classInfo ${inst}params $o $method -varNames] \\\n" +"flag [::xotcl::classInfo ${inst}params $o $method] {\n" +"if {[string match -* $flag]} continue\n" +"lappend result $argName}\n" +"return $result}\n" +"proc ::xotcl::info_nonposargs {inst o method} {\n" +"set result [list]\n" +"foreach flag [::xotcl::classInfo ${inst}params $o $method] {\n" +"if {![string match -* $flag]} continue\n" +"lappend result $flag}\n" +"return $result}\n" +"proc ::xotcl::info_default {inst o method arg varName} {\n" +"foreach \\\n" +"argName [::xotcl::classInfo ${inst}params $o $method -varNames] \\\n" +"flag [::xotcl::classInfo ${inst}params $o $method] {\n" +"if {$argName eq $arg} {\n" +"upvar 3 $varName default\n" +"if {[llength $flag] == 2} {\n" +"set default [lindex $flag 1]\n" +"return 1}\n" +"set default \"\"\n" +"return 0}}\n" +"error \"procedure \\\"$method\\\" doesn't have an argument \\\"$varName\\\"\"}\n" +"classInfo method instargs {o method} {::xotcl::info_args inst $o $method}\n" +"classInfo method args {o method} {::xotcl::info_args \"\" $o $method}\n" +"objectInfo method args {o method} {::xotcl::info_args \"\" $o $method}\n" +"classInfo method instnonposargs {o method} {::xotcl::info_nonposargs inst $o $method}\n" +"classInfo method nonposargs {o method} {::xotcl::info_nonposargs \"\" $o $method}\n" +"objectInfo method nonposargs {o method} {::xotcl::info_nonposargs \"\" $o $method}\n" +"classInfo method instdefault {o method arg var} {::xotcl::info_default inst $o $method $arg $var}\n" +"classInfo method default {o method arg var} {::xotcl::info_default \"\" $o $method $arg $var}\n" +"objectInfo method default {o method arg var} {::xotcl::info_default \"\" $o $method $arg $var}\n" +"Object method isobject {{object:substdefault \"[self]\"}} {::xotcl::is $object object}\n" +"Object method isclass {{class:substdefault \"[self]\"}} {::xotcl::is $class class}\n" +"Object method ismetaclass {{class:substdefault \"[self]\"}} {::xotcl::is $class metaclass}\n" +"Object method ismixin {class} {::xotcl::is [self] mixin $class}\n" +"Object method istype {class} {::xotcl::is [self] type $class}\n" +"::xotcl::Object method contains {\n" +"{-withnew:boolean true}\n" +"-object\n" +"{-class ::xotcl2::Object}\n" +"cmds} {\n" +"if {![info exists object]} {set object [::xotcl::self]}\n" +"if {![::xotcl::is $object object]} {$class create $object}\n" +"$object requireNamespace\n" +"if {$withnew} {\n" +"set m [::xotcl::ScopedNew new \\\n" +"-inobject $object -withclass $class -volatile]\n" +"::xotcl2::Class instmixin add $m end\n" +"namespace eval $object $cmds\n" +"::xotcl2::Class instmixin delete $m} else {\n" +"namespace eval $object $cmds}}\n" +"::xotcl::Class instforward slots %self contains \\\n" +"-object {%::xotcl::dispatch [::xotcl::self] -objscope ::subst [::xotcl::self]::slot}\n" +"Object method proc {name arglist body precondition:optional postcondition:optional} {\n" +"set cmd [list my method $name $arglist $body]\n" +"if {[info exists precondition]} {lappend cmd -precondition $precondition}\n" +"if {[info exists postcondition]} {lappend cmd -postcondition $postcondition}\n" +"eval $cmd}\n" +"Class method proc {name arglist body precondition:optional postcondition:optional} {\n" +"set cmd [list my method -per-object $name $arglist $body]\n" +"if {[info exists precondition]} {lappend cmd -precondition $precondition}\n" +"if {[info exists postcondition]} {lappend cmd -postcondition $postcondition}\n" +"eval $cmd}\n" +"Class method instproc {name arglist body precondition:optional postcondition:optional} {\n" +"set cmd [list my method $name $arglist $body]\n" +"if {[info exists precondition]} {lappend cmd -precondition $precondition}\n" +"if {[info exists postcondition]} {lappend cmd -postcondition $postcondition}\n" +"eval $cmd}\n" +"Object create ::xotcl::@\n" +"@ method unknown args {}\n" +"proc myproc {args} {linsert $args 0 [::xotcl::self]}\n" +"proc myvar {var} {.requireNamespace; return [::xotcl::self]::$var}\n" +"namespace export Object Class @ myproc myvar Attribute}\n" +"::xotcl::Object method self {} {::xotcl::self}\n" +"::xotcl2::Object method defaultmethod {} {\n" +"return [::xotcl::self]}\n" +"::xotcl::Object method hasclass cl {\n" +"if {[::xotcl::is [self] mixin $cl]} {return 1}\n" +"::xotcl::is [self] type $cl}\n" +"::xotcl::Class method allinstances {} {\n" +"return [.info instances -closure]}\n" +"::xotcl::alias ::xotcl::Class parameter ::xotcl::classes::xotcl2::Class::parameter\n" +"::xotcl::alias ::xotcl::Object defaultmethod ::xotcl::classes::xotcl2::Object::defaultmethod\n" +"::xotcl::Object method -per-object unsetExitHandler {} {\n" +"::xotcl::Object method -per-object __exitHandler {} {\n" +";}}\n" +"::xotcl::Object unsetExitHandler\n" +"::xotcl::Object method -per-object setExitHandler {newbody} {\n" +"::xotcl::Object method -per-object __exitHandler {} $newbody}\n" +"::xotcl::Object method -per-object getExitHandler {} {\n" +"::xotcl::Object info body __exitHandler}\n" +"proc ::xotcl::__exitHandler {} {\n" +"::xotcl::Object __exitHandler}\n" +"::xotcl::Object method abstract {methtype methname arglist} {\n" +"if {$methtype ne \"proc\" && $methtype ne \"instproc\" && $methtype ne \"method\"} {\n" +"error \"invalid method type '$methtype', \\\n" +"must be either 'proc', 'instproc' or 'method'.\"}\n" +".$methtype $methname $arglist \"\n" +"if {!\\[::xotcl::self isnextcall\\]} {\n" +"error \\\"Abstract method $methname $arglist called\\\"} else {::xotcl::next}\n" +"\"}\n" "::xotcl::Object method copy newName {\n" "if {[string compare [string trimleft $newName :] [string trimleft [::xotcl::self] :]]} {\n" -"[[::xotcl::self class]::CopyHandler new -volatile] copy [::xotcl::self] $newName}}\n" +"[::xotcl::CopyHandler new -volatile] copy [::xotcl::self] $newName}}\n" "::xotcl::Object method move newName {\n" "if {[string trimleft $newName :] ne [string trimleft [::xotcl::self] :]} {\n" "if {$newName ne \"\"} {\n" Index: generic/predefined.xotcl =================================================================== diff -u -r9cec079eb9f4ce69a8ecad865ea6ca12fff0bd45 -r6fa467e12f7a039c928b3096175a73414b5f26ff --- generic/predefined.xotcl (.../predefined.xotcl) (revision 9cec079eb9f4ce69a8ecad865ea6ca12fff0bd45) +++ generic/predefined.xotcl (.../predefined.xotcl) (revision 6fa467e12f7a039c928b3096175a73414b5f26ff) @@ -16,7 +16,7 @@ ::xotcl::alias Object [namespace tail $cmd] $cmd } - # provide some Tcl-commands as methods for ::xotcl::Object + # provide some Tcl-commands as methods for ::xotcl2::Object #foreach cmd {array append eval incr lappend set subst unset trace} { # ::xotcl::alias Object $cmd -objscope ::$cmd #} @@ -99,7 +99,7 @@ return "valid options are: [join [lsort $methods] {, }]" } objectInfo method unknown {method args} { - error "unknown info option \"$method\"; [.info info]" + error "[::xotcl::self] unknown info option \"$method\"; [.info info]" } classInfo method info {cl} { @@ -112,261 +112,12 @@ return "valid options are: [join [lsort $methods] {, }]" } classInfo method unknown {method args} { - error "unknown info option \"$method\"; [.info info]" + error "[::xotcl::self] unknown info option \"$method\"; [.info info]" } namespace export Object Class } -namespace eval ::xotcl { - # - # Perform the basic setup of XOTcl 1.x. First, let us allocate the - # basic classes of XOTcl. This call creates the classes - # ::xotcl::Object and ::xotcl::Class and defines these as root class - # of the object system and as root meta class. - # - ::xotcl::createobjectsystem ::xotcl::Object ::xotcl::Class - - # provide the standard command set for ::xotcl::Object - foreach cmd [info command ::xotcl::cmd::Object::*] { - ::xotcl::alias Object [namespace tail $cmd] $cmd - } - - # provide some Tcl-commands as methods for ::xotcl::Object - foreach cmd {array append eval incr lappend set subst unset trace} { - ::xotcl::alias Object $cmd -objscope ::$cmd - } - - # provide the standard command set for ::xotcl::Class - foreach cmd [info command ::xotcl::cmd::Class::*] { - ::xotcl::alias Class [namespace tail $cmd] $cmd - } - unset cmd - - # protect some methods against redefinition - ::xotcl::methodproperty Object destroy static true - ::xotcl::methodproperty Class alloc static true - ::xotcl::methodproperty Class dealloc static true - ::xotcl::methodproperty Class create static true - - Class method unknown {args} { - #puts stderr "use '[self] create $args', not '[self] $args'" - eval my create $args - } - - Object method unknown {m args} { - if {![self isnext]} { - error "[self]: unable to dispatch method '$m'" - } - } - - # "init" must exist on Object. per default it is empty. - Object method init args {} - - # provide a placeholder for the bootup process. The real definition - # is based on slots, which are not available at this point. - Object method objectparameter {} {;} - - # - # create class and object for nonpositional argument processing - Class create ::xotcl::ParameterType - foreach cmd [info command ::xotcl::cmd::ParameterType::*] { - ::xotcl::alias ::xotcl::ParameterType [namespace tail $cmd] $cmd - } - # register type boolean as checker for "switch" - ::xotcl::alias ::xotcl::ParameterType type=switch ::xotcl::cmd::ParameterType::type=boolean - # create an object for dispatching - ::xotcl::ParameterType create ::xotcl::parameterType - - ######################## - # Info definition - ######################## - Object create ::xotcl::objectInfo - Object create ::xotcl::classInfo - - foreach cmd [info command ::xotcl::cmd::ObjectInfo::*] { - ::xotcl::alias ::xotcl::objectInfo [namespace tail $cmd] $cmd - ::xotcl::alias ::xotcl::classInfo [namespace tail $cmd] $cmd - } - foreach cmd [info command ::xotcl::cmd::ClassInfo::*] { - ::xotcl::alias ::xotcl::classInfo [namespace tail $cmd] $cmd - } - unset cmd - ::xotcl::alias ::xotcl::objectInfo is ::xotcl::is - ::xotcl::alias ::xotcl::classInfo is ::xotcl::is - ::xotcl::alias ::xotcl::classInfo classparent ::xotcl::cmd::ObjectInfo::parent - ::xotcl::alias ::xotcl::classInfo classchildren ::xotcl::cmd::ObjectInfo::children - - Object instforward info -onerror ::xotcl::infoError ::xotcl::objectInfo %1 {%@2 %self} - Class instforward info -onerror ::xotcl::infoError ::xotcl::classInfo %1 {%@2 %self} - - # TODO: the following method is defined redundantly - proc ::xotcl::infoError msg { - #puts stderr "INFO ERROR: <$msg>\n$::errorInfo" - regsub -all " " $msg "" msg - regsub -all " " $msg "" msg - regsub {\"} $msg "\"info " msg - error $msg "" - } - objectInfo method info {obj} { - set methods [list] - foreach m [::info commands ::xotcl::objectInfo::*] { - set name [namespace tail $m] - if {$name eq "unknown"} continue - lappend methods $name - } - return "valid options are: [join [lsort $methods] {, }]" - } - objectInfo method unknown {method args} { - error "unknown info option \"$method\"; [.info info]" - } - - classInfo method info {cl} { - set methods [list] - foreach m [::info commands ::xotcl::classInfo::*] { - set name [namespace tail $m] - if {$name eq "unknown"} continue - lappend methods $name - } - return "valid options are: [join [lsort $methods] {, }]" - } - classInfo method unknown {method args} { - error "unknown info option \"$method\"; [.info info]" - } - - # - # Backward compatibility info subcommands; - # - # TODO: should go finally into a library. - # - # Obsolete methods - # - # already emulated: - # - # => info params .... replaces - # info args - # info nonposargs - # info default - # - # => info instparams .... replaces - # info instargs - # info instnonposargs - # info instdefault - # - # => maybe instead of "info params" and "info instparams" - # info params ?-per-object? - # - # => TODO: use "params" in serializer, and all other occurances - # - # TODO: not yet emulated: - # - # => info is (bzw. ::xotcl::is) replaces - # isobject - # isclass - # ismetaclass - # ismixin - # istype - # - # => method (should get pre- and postconditions via positional params) - # proc - # instproc - # - # TODO mark all absolete calls at least as deprecated in library - # - # TODO move unknown handler for Class into a library, make sure that - # regression test and library function use explicit "creates". - # - - proc ::xotcl::info_args {inst o method} { - set result [list] - foreach \ - argName [::xotcl::classInfo ${inst}params $o $method -varNames] \ - flag [::xotcl::classInfo ${inst}params $o $method] { - if {[string match -* $flag]} continue - lappend result $argName - } - #puts stderr "+++ get ${inst}args for $o $method => $result" - return $result - } - - proc ::xotcl::info_nonposargs {inst o method} { - set result [list] - foreach flag [::xotcl::classInfo ${inst}params $o $method] { - if {![string match -* $flag]} continue - lappend result $flag - } - #puts stderr "+++ get ${inst}nonposargs for $o $method => $result" - return $result - } - proc ::xotcl::info_default {inst o method arg varName} { - foreach \ - argName [::xotcl::classInfo ${inst}params $o $method -varNames] \ - flag [::xotcl::classInfo ${inst}params $o $method] { - if {$argName eq $arg} { - upvar 3 $varName default - if {[llength $flag] == 2} { - set default [lindex $flag 1] - #puts stderr "--- get ${inst}default for $o $method $arg => $default" - return 1 - } - #puts stderr "--- get ${inst}default for $o $method $arg fails" - set default "" - return 0 - } - } - error "procedure \"$method\" doesn't have an argument \"$varName\"" - } - - classInfo method instargs {o method} {::xotcl::info_args inst $o $method} - classInfo method args {o method} {::xotcl::info_args "" $o $method} - objectInfo method args {o method} {::xotcl::info_args "" $o $method} - - classInfo method instnonposargs {o method} {::xotcl::info_nonposargs inst $o $method} - classInfo method nonposargs {o method} {::xotcl::info_nonposargs "" $o $method} - objectInfo method nonposargs {o method} {::xotcl::info_nonposargs "" $o $method} - - classInfo method instdefault {o method arg var} {::xotcl::info_default inst $o $method $arg $var} - classInfo method default {o method arg var} {::xotcl::info_default "" $o $method $arg $var} - objectInfo method default {o method arg var} {::xotcl::info_default "" $o $method $arg $var} - - # emulation of isobject, ... - Object method isobject {{object:substdefault "[self]"}} {::xotcl::is $object object} - Object method isclass {{class:substdefault "[self]"}} {::xotcl::is $class class} - Object method ismetaclass {{class:substdefault "[self]"}} {::xotcl::is $class metaclass} - Object method ismixin {class} {::xotcl::is [self] mixin $class} - Object method istype {class} {::xotcl::is [self] type $class} - - # - Object method proc {name arglist body precondition:optional postcondition:optional} { - set cmd [list my method $name $arglist $body] - if {[info exists precondition]} {lappend cmd -precondition $precondition} - if {[info exists postcondition]} {lappend cmd -postcondition $postcondition} - eval $cmd - } - Class method proc {name arglist body precondition:optional postcondition:optional} { - set cmd [list my method -per-object $name $arglist $body] - if {[info exists precondition]} {lappend cmd -precondition $precondition} - if {[info exists postcondition]} {lappend cmd -postcondition $postcondition} - eval $cmd - } - Class method instproc {name arglist body precondition:optional postcondition:optional} { - set cmd [list my method $name $arglist $body] - if {[info exists precondition]} {lappend cmd -precondition $precondition} - if {[info exists postcondition]} {lappend cmd -postcondition $postcondition} - eval $cmd - } - - # documentation stub object -> just ignore per default. - # if xoDoc is loaded, documentation will be activated - Object create ::xotcl::@ - @ method unknown args {} - - proc myproc {args} {linsert $args 0 [::xotcl::self]} - proc myvar {var} {.requireNamespace; return [::xotcl::self]::$var} - - namespace export Object Class @ myproc myvar Attribute -} - ################## # Slot definitions ################## @@ -431,12 +182,6 @@ return $parameterdefinitions } -::xotcl::Object method objectparameter {} { - set parameterdefinitions [::xotcl::parametersFromSlots [self]] - lappend parameterdefinitions args - #puts stderr "*** parameter definition for [self]: $parameterdefinitions" - return $parameterdefinitions -} ::xotcl2::Object method objectparameter {} { set parameterdefinitions [::xotcl::parametersFromSlots [self]] if {[::xotcl::is [self] class]} { @@ -473,7 +218,8 @@ if {[llength $att]>1} {foreach {att default} $att break} if {[info exists default]} { # checking subclasses is not required during bootstrap - foreach i [$class info instances] { + # todo: do we really need $class twice? + foreach i [::xotcl::dispatch $class ::xotcl::cmd::ClassInfo::instances $class] { if {![$i exists $att]} { if {[string match {*[*]*} $default]} { #set default [$i eval subst $default] @@ -491,22 +237,6 @@ # -# TODO: -# - are createBootstrapAttributeSlots for ::xotcl::Class still needed? -# - Defaults for objectparameter seem more natural. -# - no definition yet for xotcl2::Class -# - -# We provide a default value for superclass (when no superclass is specified explicitely) -# for defining the top-level class of the object system, such that different -# object systems might co-exist. - -createBootstrapAttributeSlots ::xotcl::Class { - {__default_superclass ::xotcl::Object} - {__default_metaclass ::xotcl::Class} -} - -# # Define slots for slots # createBootstrapAttributeSlots ::xotcl::Slot { @@ -568,10 +298,9 @@ set forwarder [expr {${.per-object} ? "forward" : "instforward"}] if {${.domain} eq ""} { set .domain [::xotcl::self callingobject] - } else { - ${.domain} invalidateobjectparameter } if {${.domain} ne ""} { + ${.domain} invalidateobjectparameter ${.domain} $forwarder ${.name} -default [${.manager} defaultmethods] ${.manager} %1 %self %proc } } @@ -639,11 +368,10 @@ ###################### # system slots ###################### -# register the system slots on both, xotcl and xotcl2 -foreach os {::xotcl ::xotcl2} { +proc ::xotcl::register_system_slots {os} { ${os}::Object alloc ${os}::Class::slot ${os}::Object alloc ${os}::Object::slot - + ::xotcl::InfoSlot create ${os}::Class::slot::superclass -type relation ::xotcl::alias ${os}::Class::slot::superclass assign ::xotcl::relation ::xotcl::InfoSlot create ${os}::Object::slot::class -type relation @@ -659,18 +387,13 @@ -elementtype "" \ -type relation } +::xotcl::register_system_slots ::xotcl2 # +# Attribute slots # -# Attribute -# -# TODO: why does -superclass not work here? -# before, the subsequent ::xotcl::relation was not needed. - ::xotcl::MetaSlot invalidateobjectparameter - ::xotcl::MetaSlot create ::xotcl::Attribute -superclass ::xotcl::Slot -::xotcl::relation ::xotcl::Attribute superclass ::xotcl::Slot createBootstrapAttributeSlots ::xotcl::Attribute { {value_check once} @@ -760,7 +483,7 @@ } } -# mixin class for decativating all checks +# mixin class for decativating all value checks in slots ::xotcl2::Class create ::xotcl::Slot::Nocheck { .method check_single_value args {;} .method check_multiple_values args {;} @@ -834,28 +557,6 @@ ::xotcl2::Class instforward slots %self contains \ -object {%::xotcl::dispatch [::xotcl::self] -objscope ::subst [::xotcl::self]::slot} -# this will go into the optional xotcl block -::xotcl::Object method contains { - {-withnew:boolean true} - -object - {-class ::xotcl2::Object} - cmds - } { - if {![info exists object]} {set object [::xotcl::self]} - if {![::xotcl::is $object object]} {$class create $object} - $object requireNamespace - if {$withnew} { - set m [::xotcl::ScopedNew new \ - -inobject $object -withclass $class -volatile] - ::xotcl2::Class instmixin add $m end - namespace eval $object $cmds - ::xotcl2::Class instmixin delete $m - } else { - namespace eval $object $cmds - } -} -::xotcl::Class instforward slots %self contains \ - -object {%::xotcl::dispatch [::xotcl::self] -objscope ::subst [::xotcl::self]::slot} # # define parameter for backward compatibility and convenience # @@ -933,79 +634,18 @@ ::xotcl::setinstvar [::xotcl::self]::slot __parameter $arglist } -# -# utilities -# -::xotcl::Object method self {} {::xotcl::self} -::xotcl::Object method defaultmethod {} { - return [::xotcl::self] -} -# support for XOTcl specific convenience routines -::xotcl::Object method hasclass cl { - if {[::xotcl::is [self] mixin $cl]} {return 1} - ::xotcl::is [self] type $cl -} -::xotcl::Class method allinstances {} { - # TODO: mark it deprecated - return [.info instances -closure] -} - -# reuse definitions from xotcl in xotcl2 -# TODO: can this be done with interp aliases? -::xotcl::alias ::xotcl::Class parameter ::xotcl::classes::xotcl2::Class::parameter -#::xotcl::alias ::xotcl::Object contains ::xotcl::classes::xotcl2::Object::contains -::xotcl::alias ::xotcl2::Object defaultmethod ::xotcl::classes::xotcl::Object::defaultmethod - -#interp alias {} ::xotcl::classes::xotcl::Class::parameter {} ::xotcl::classes::xotcl2::Class::parameter -#interp alias {} ::xotcl::classes::xotcl::Object::defaultmethod {} ::xotcl::classes::xotcl2::Object::defaultmethod - # -# TODO remainder should move from ::xotcl::Object -> xotcl2::* -# - -# Exit Handler -::xotcl::Object method -per-object unsetExitHandler {} { - ::xotcl::Object method -per-object __exitHandler {} { - # clients should append exit handlers to this proc body - ; - } -} -# pre-defined as empty method -::xotcl::Object unsetExitHandler -::xotcl::Object method -per-object setExitHandler {newbody} { - ::xotcl::Object method -per-object __exitHandler {} $newbody -} -::xotcl::Object method -per-object getExitHandler {} { - ::xotcl::Object info body __exitHandler -} -# provide a global handler to avoid a proc on the global object. -proc ::xotcl::__exitHandler {} { - ::xotcl::Object __exitHandler -} -::xotcl::Object method abstract {methtype methname arglist} { - if {$methtype ne "proc" && $methtype ne "instproc" && $methtype ne "method"} { - error "invalid method type '$methtype', \ - must be either 'proc', 'instproc' or 'method'." - } - .$methtype $methname $arglist " - if {!\[::xotcl::self isnextcall\]} { - error \"Abstract method $methname $arglist called\" - } else {::xotcl::next} - " -} - -# # copy/move implementation # -::xotcl2::Class create ::xotcl::Object::CopyHandler -parameter { +::xotcl2::Class create ::xotcl::CopyHandler -parameter { {targetList ""} {dest ""} objLength } # targets are all namspaces and objs part-of the copied obj -::xotcl::Object::CopyHandler method makeTargetList t { +::xotcl::CopyHandler method makeTargetList t { lappend .targetList $t # if it is an object without namespace, it is a leaf if {[::xotcl::is $t object]} { @@ -1032,18 +672,18 @@ } } -::xotcl::Object::CopyHandler method copyNSVarsAndCmds {orig dest} { +::xotcl::CopyHandler method copyNSVarsAndCmds {orig dest} { ::xotcl::namespace_copyvars $orig $dest ::xotcl::namespace_copycmds $orig $dest } # construct destination obj name from old qualified ns name -::xotcl::Object::CopyHandler method getDest origin { +::xotcl::CopyHandler method getDest origin { set tail [string range $origin [set .objLength] end] return ::[string trimleft [set .dest]$tail :] } -::xotcl::Object::CopyHandler method copyTargets {} { +::xotcl::CopyHandler method copyTargets {} { #puts stderr "COPY will copy targetList = [set .targetList]" foreach origin [set .targetList] { set dest [.getDest $origin] @@ -1111,17 +751,387 @@ } } -::xotcl::Object::CopyHandler method copy {obj dest} { +::xotcl::CopyHandler method copy {obj dest} { #puts stderr "[::xotcl::self] copy <$obj> <$dest>" set .objLength [string length $obj] set .dest $dest .makeTargetList $obj .copyTargets } + + +####################################################################### +namespace eval ::xotcl { + # + # Perform the basic setup of XOTcl 1.x. First, let us allocate the + # basic classes of XOTcl. This call creates the classes + # ::xotcl::Object and ::xotcl::Class and defines these as root class + # of the object system and as root meta class. + # + ::xotcl::createobjectsystem ::xotcl::Object ::xotcl::Class + + # provide the standard command set for ::xotcl::Object + foreach cmd [info command ::xotcl::cmd::Object::*] { + ::xotcl::alias Object [namespace tail $cmd] $cmd + } + + # provide some Tcl-commands as methods for ::xotcl::Object + foreach cmd {array append eval incr lappend set subst unset trace} { + ::xotcl::alias Object $cmd -objscope ::$cmd + } + + # provide the standard command set for ::xotcl::Class + foreach cmd [info command ::xotcl::cmd::Class::*] { + ::xotcl::alias Class [namespace tail $cmd] $cmd + } + unset cmd + + # protect some methods against redefinition + ::xotcl::methodproperty Object destroy static true + ::xotcl::methodproperty Class alloc static true + ::xotcl::methodproperty Class dealloc static true + ::xotcl::methodproperty Class create static true + + Class method unknown {args} { + #puts stderr "use '[self] create $args', not '[self] $args'" + eval my create $args + } + + Object method unknown {m args} { + if {![self isnext]} { + error "[self]: unable to dispatch method '$m'" + } + } + + # "init" must exist on Object. per default it is empty. + Object method init args {} + + # provide a placeholder for the bootup process. The real definition + # is based on slots, which are not available at this point. + Object method objectparameter {} {;} + + # + # create class and object for nonpositional argument processing + Class create ::xotcl::ParameterType + foreach cmd [info command ::xotcl::cmd::ParameterType::*] { + ::xotcl::alias ::xotcl::ParameterType [namespace tail $cmd] $cmd + } + # register type boolean as checker for "switch" + ::xotcl::alias ::xotcl::ParameterType type=switch ::xotcl::cmd::ParameterType::type=boolean + # create an object for dispatching + ::xotcl::ParameterType create ::xotcl::parameterType + + # + # object-parameter definition, backwards compatible + # + ::xotcl::Object method objectparameter {} { + set parameterdefinitions [::xotcl::parametersFromSlots [self]] + lappend parameterdefinitions args + #puts stderr "*** parameter definition for [self]: $parameterdefinitions" + return $parameterdefinitions + } + + # + # TODO: + # - are createBootstrapAttributeSlots for ::xotcl::Class still needed? + # - Defaults for objectparameter seem more natural. + # - no definition yet for xotcl2::Class + # + + # We provide a default value for superclass (when no superclass is specified explicitely) + # for defining the top-level class of the object system, such that different + # object systems might co-exist. + + createBootstrapAttributeSlots ::xotcl::Class { + {__default_superclass ::xotcl::Object} + {__default_metaclass ::xotcl::Class} + } + + ::xotcl::register_system_slots ::xotcl + + ######################## + # Info definition + ######################## + Object create ::xotcl::objectInfo + Object create ::xotcl::classInfo + + foreach cmd [::info command ::xotcl::cmd::ObjectInfo::*] { + ::xotcl::alias ::xotcl::objectInfo [namespace tail $cmd] $cmd + ::xotcl::alias ::xotcl::classInfo [namespace tail $cmd] $cmd + } + foreach cmd [::info command ::xotcl::cmd::ClassInfo::*] { + ::xotcl::alias ::xotcl::classInfo [namespace tail $cmd] $cmd + } + unset cmd + ::xotcl::alias ::xotcl::objectInfo is ::xotcl::is + ::xotcl::alias ::xotcl::classInfo is ::xotcl::is + ::xotcl::alias ::xotcl::classInfo classparent ::xotcl::cmd::ObjectInfo::parent + ::xotcl::alias ::xotcl::classInfo classchildren ::xotcl::cmd::ObjectInfo::children + + Object instforward info -onerror ::xotcl::infoError ::xotcl::objectInfo %1 {%@2 %self} + Class instforward info -onerror ::xotcl::infoError ::xotcl::classInfo %1 {%@2 %self} + + # TODO: the following method is defined redundantly + proc ::xotcl::infoError msg { + #puts stderr "INFO ERROR: <$msg>\n$::errorInfo" + regsub -all " " $msg "" msg + regsub -all " " $msg "" msg + regsub {\"} $msg "\"info " msg + error $msg "" + } + objectInfo method info {obj} { + set methods [list] + foreach m [::info commands ::xotcl::objectInfo::*] { + set name [namespace tail $m] + if {$name eq "unknown"} continue + lappend methods $name + } + return "valid options are: [join [lsort $methods] {, }]" + } + objectInfo method unknown {method args} { + error "[::xotcl::self] unknown info option \"$method\"; [.info info]" + } + + classInfo method info {cl} { + set methods [list] + foreach m [::info commands ::xotcl::classInfo::*] { + set name [namespace tail $m] + if {$name eq "unknown"} continue + lappend methods $name + } + return "valid options are: [join [lsort $methods] {, }]" + } + classInfo method unknown {method args} { + error "[::xotcl::self] unknown info option \"$method\"; [.info info]" + } + + # + # Backward compatibility info subcommands; + # + # TODO: should go finally into a library. + # + # Obsolete methods + # + # already emulated: + # + # => info params .... replaces + # info args + # info nonposargs + # info default + # + # => info instparams .... replaces + # info instargs + # info instnonposargs + # info instdefault + # + # => maybe instead of "info params" and "info instparams" + # info params ?-per-object? + # + # => TODO: use "params" in serializer, and all other occurances + # + # TODO: not yet emulated: + # + # => info is (bzw. ::xotcl::is) replaces + # isobject + # isclass + # ismetaclass + # ismixin + # istype + # + # => method (should get pre- and postconditions via positional params) + # proc + # instproc + # + # TODO mark all absolete calls at least as deprecated in library + # + # TODO move unknown handler for Class into a library, make sure that + # regression test and library function use explicit "creates". + # + + proc ::xotcl::info_args {inst o method} { + set result [list] + foreach \ + argName [::xotcl::classInfo ${inst}params $o $method -varNames] \ + flag [::xotcl::classInfo ${inst}params $o $method] { + if {[string match -* $flag]} continue + lappend result $argName + } + #puts stderr "+++ get ${inst}args for $o $method => $result" + return $result + } + + proc ::xotcl::info_nonposargs {inst o method} { + set result [list] + foreach flag [::xotcl::classInfo ${inst}params $o $method] { + if {![string match -* $flag]} continue + lappend result $flag + } + #puts stderr "+++ get ${inst}nonposargs for $o $method => $result" + return $result + } + proc ::xotcl::info_default {inst o method arg varName} { + foreach \ + argName [::xotcl::classInfo ${inst}params $o $method -varNames] \ + flag [::xotcl::classInfo ${inst}params $o $method] { + if {$argName eq $arg} { + upvar 3 $varName default + if {[llength $flag] == 2} { + set default [lindex $flag 1] + #puts stderr "--- get ${inst}default for $o $method $arg => $default" + return 1 + } + #puts stderr "--- get ${inst}default for $o $method $arg fails" + set default "" + return 0 + } + } + error "procedure \"$method\" doesn't have an argument \"$varName\"" + } + + classInfo method instargs {o method} {::xotcl::info_args inst $o $method} + classInfo method args {o method} {::xotcl::info_args "" $o $method} + objectInfo method args {o method} {::xotcl::info_args "" $o $method} + + classInfo method instnonposargs {o method} {::xotcl::info_nonposargs inst $o $method} + classInfo method nonposargs {o method} {::xotcl::info_nonposargs "" $o $method} + objectInfo method nonposargs {o method} {::xotcl::info_nonposargs "" $o $method} + + classInfo method instdefault {o method arg var} {::xotcl::info_default inst $o $method $arg $var} + classInfo method default {o method arg var} {::xotcl::info_default "" $o $method $arg $var} + objectInfo method default {o method arg var} {::xotcl::info_default "" $o $method $arg $var} + + # emulation of isobject, ... + Object method isobject {{object:substdefault "[self]"}} {::xotcl::is $object object} + Object method isclass {{class:substdefault "[self]"}} {::xotcl::is $class class} + Object method ismetaclass {{class:substdefault "[self]"}} {::xotcl::is $class metaclass} + Object method ismixin {class} {::xotcl::is [self] mixin $class} + Object method istype {class} {::xotcl::is [self] type $class} + + + # todo: it should be possible to use an alias for the xotcl2 implementation + ::xotcl::Object method contains { + {-withnew:boolean true} + -object + {-class ::xotcl2::Object} + cmds + } { + if {![info exists object]} {set object [::xotcl::self]} + if {![::xotcl::is $object object]} {$class create $object} + $object requireNamespace + if {$withnew} { + set m [::xotcl::ScopedNew new \ + -inobject $object -withclass $class -volatile] + ::xotcl2::Class instmixin add $m end + namespace eval $object $cmds + ::xotcl2::Class instmixin delete $m + } else { + namespace eval $object $cmds + } + } + ::xotcl::Class instforward slots %self contains \ + -object {%::xotcl::dispatch [::xotcl::self] -objscope ::subst [::xotcl::self]::slot} + + # + Object method proc {name arglist body precondition:optional postcondition:optional} { + set cmd [list my method $name $arglist $body] + if {[info exists precondition]} {lappend cmd -precondition $precondition} + if {[info exists postcondition]} {lappend cmd -postcondition $postcondition} + eval $cmd + } + Class method proc {name arglist body precondition:optional postcondition:optional} { + set cmd [list my method -per-object $name $arglist $body] + if {[info exists precondition]} {lappend cmd -precondition $precondition} + if {[info exists postcondition]} {lappend cmd -postcondition $postcondition} + eval $cmd + } + Class method instproc {name arglist body precondition:optional postcondition:optional} { + set cmd [list my method $name $arglist $body] + if {[info exists precondition]} {lappend cmd -precondition $precondition} + if {[info exists postcondition]} {lappend cmd -postcondition $postcondition} + eval $cmd + } + + # documentation stub object -> just ignore per default. + # if xoDoc is loaded, documentation will be activated + Object create ::xotcl::@ + @ method unknown args {} + + proc myproc {args} {linsert $args 0 [::xotcl::self]} + proc myvar {var} {.requireNamespace; return [::xotcl::self]::$var} + + namespace export Object Class @ myproc myvar Attribute +} +####################################################################### + + + +# +# utilities +# +::xotcl::Object method self {} {::xotcl::self} +::xotcl2::Object method defaultmethod {} { + return [::xotcl::self] +} + +# support for XOTcl specific convenience routines +::xotcl::Object method hasclass cl { + if {[::xotcl::is [self] mixin $cl]} {return 1} + ::xotcl::is [self] type $cl +} +::xotcl::Class method allinstances {} { + # TODO: mark it deprecated + return [.info instances -closure] +} + +# reuse definitions from xotcl in xotcl2 +# TODO: can this be done with interp aliases? +::xotcl::alias ::xotcl::Class parameter ::xotcl::classes::xotcl2::Class::parameter +#::xotcl::alias ::xotcl::Object contains ::xotcl::classes::xotcl2::Object::contains +::xotcl::alias ::xotcl::Object defaultmethod ::xotcl::classes::xotcl2::Object::defaultmethod + +#interp alias {} ::xotcl::classes::xotcl::Class::parameter {} ::xotcl::classes::xotcl2::Class::parameter +#interp alias {} ::xotcl::classes::xotcl::Object::defaultmethod {} ::xotcl::classes::xotcl2::Object::defaultmethod + +# +# TODO remainder should move from ::xotcl::Object -> xotcl2::* +# + +# Exit Handler +::xotcl::Object method -per-object unsetExitHandler {} { + ::xotcl::Object method -per-object __exitHandler {} { + # clients should append exit handlers to this proc body + ; + } +} +# pre-defined as empty method +::xotcl::Object unsetExitHandler +::xotcl::Object method -per-object setExitHandler {newbody} { + ::xotcl::Object method -per-object __exitHandler {} $newbody +} +::xotcl::Object method -per-object getExitHandler {} { + ::xotcl::Object info body __exitHandler +} +# provide a global handler to avoid a proc on the global object. +proc ::xotcl::__exitHandler {} { + ::xotcl::Object __exitHandler +} +::xotcl::Object method abstract {methtype methname arglist} { + if {$methtype ne "proc" && $methtype ne "instproc" && $methtype ne "method"} { + error "invalid method type '$methtype', \ + must be either 'proc', 'instproc' or 'method'." + } + .$methtype $methname $arglist " + if {!\[::xotcl::self isnextcall\]} { + error \"Abstract method $methname $arglist called\" + } else {::xotcl::next} + " +} + + ::xotcl::Object method copy newName { if {[string compare [string trimleft $newName :] [string trimleft [::xotcl::self] :]]} { - [[::xotcl::self class]::CopyHandler new -volatile] copy [::xotcl::self] $newName + [::xotcl::CopyHandler new -volatile] copy [::xotcl::self] $newName } }