Index: TODO =================================================================== diff -u -r496f49d15463c79323454495e356de52137b46bd -r925485d2ec3b626277037d5fd3154172cc989f7a --- TODO (.../TODO) (revision 496f49d15463c79323454495e356de52137b46bd) +++ TODO (.../TODO) (revision 925485d2ec3b626277037d5fd3154172cc989f7a) @@ -4645,17 +4645,26 @@ it is replaced now by introspection. - extended regression test +nsf.c +- fixed a potental crash on destroy for objects having a + wrapperless alias defined +- removed obsolete function AssertionAppendPrePost() +- removed obsolete function NsfNSCopyCmdsCmd() + and ::nsf::nscopycmd (handled now more general on + scripting level in the "copy" method) + +nx.tcl: +- "copy" method: fixed copying of class-level per-object methods +- extended regression tests + +serializer.tcl +- added flag -objmap to Serialzer.deepSerialize + to make serialzer usable for copying (-map is to coarse) +- extended regression test + ======================================================================== TODO: -- copycmds is obsolete, copyNSVarsAndCmds should be renamed -- methods.test: test case object+class-copy: - after copy, the following command lists "__a" etc as well - #? {lsort [::D info object methods -path]} "{oa b} {oa c} ofoo ofwd set" -- methods.test: when method "exists" is required in test case - object+class-copy, cleanup leads to a crash -- nx.tcl: cleanup of XXX cmds - Stefan: API-related items * the introspection interface uses "-type" for "class" or "instanceof", but the intercession interface refers to "-class", e.g. Index: library/serialize/serializer.tcl =================================================================== diff -u -r2f6bcca3537584c8ef1f9fc71b230e79d1560504 -r925485d2ec3b626277037d5fd3154172cc989f7a --- library/serialize/serializer.tcl (.../serializer.tcl) (revision 2f6bcca3537584c8ef1f9fc71b230e79d1560504) +++ library/serialize/serializer.tcl (.../serializer.tcl) (revision 925485d2ec3b626277037d5fd3154172cc989f7a) @@ -156,6 +156,9 @@ } } } + :public method objmap {map} { + array set :objmap $map + } :method init {} { # Never serialize the (volatile) serializer object @@ -194,6 +197,17 @@ set o [::nsf::dispatch $o ::nsf::methods::object::info::parent] } } + + :public method getTargetName {sourceName} { + # TODO: make more efficent; + set targetName $sourceName + if {[array exists :objmap]} { + foreach {source target} [array get :objmap] { + regsub ^$source $targetName $target targetName + } + } + return $targetName + } :method topoSort {set all} { if {[array exists :s]} {array unset :s} @@ -245,7 +259,7 @@ set result "" foreach l [lsort -integer [array names :level]] { foreach i [set :level($l)] { - #.warn "serialize $i" + #:warn "serialize $i" #append result "# Stratum $l\n" set oss [set :serializer($i)] append result [$oss serialize $i [::nsf::current object]] \n @@ -446,15 +460,15 @@ return $result } - :public object method deepSerialize {-ignoreVarsRE -ignore -map args} { + :public object method deepSerialize {-ignoreVarsRE -ignore -map -objmap args} { :resetPattern set s [:new -childof [::nsf::current object] -volatile] #$s volatile if {[info exists ignoreVarsRE]} {$s ignoreVarsRE $ignoreVarsRE} if {[info exists ignore]} {$s ignore $ignore} - + if {[info exists objmap]} {$s objmap $objmap} foreach o $args { - append r [$s deepSerialize [$o]] + append r [$s deepSerialize [::nsf::directdispatch $o -frame method ::nsf::current]] } if {[info exists map]} {return [string map $map $r]} return $r @@ -590,7 +604,7 @@ set v [$cmd $o $relation] if {$v eq ""} {return ""} if {[info exists unless] && $v eq $unless} {return ""} - return [list $cmd $o $relation $v]\n + return [list $cmd ${:targetName} $relation $v]\n } :method serializeExportedMethods {s} { @@ -620,6 +634,7 @@ ############################### :public method serialize {objectOrClass s} { + set :targetName [$s getTargetName $objectOrClass] :[:classify $objectOrClass]-serialize $objectOrClass $s } @@ -756,7 +771,9 @@ set def "" } else { set def [$o info {*}$modifier method definition $m] - set handle [$o info {*}$modifier method registrationhandle $m] + if {${:targetName} ne $o} { + set def [lreplace $def 0 0 ${:targetName}] + } } return $def } @@ -775,16 +792,17 @@ set isSlotContainer [::nx::isSlotContainer $objectName] if {$isSlotContainer} { append cmd [list ::nx::slotObj -container [namespace tail $objectName] \ - [$o ::nsf::methods::object::info::parent]]\n + [$s getTargetName [$objectName ::nsf::methods::object::info::parent]]]\n } else { - append cmd [list [$o info class] create $objectName -noinit]\n + #puts stderr "CREATE targetName '${:targetName}'" + append cmd [list [$o info class] create ${:targetName} -noinit]\n foreach i [lsort [$o ::nsf::methods::object::info::methods -callprotection all -path]] { append cmd [:method-serialize $o $i "object"] "\n" } } set vars [:collectVars $o $s] - if {[llength $vars]>0} {append cmd [list $o eval [join $vars "\n "]]\n} + if {[llength $vars]>0} {append cmd [list ${:targetName} eval [join $vars "\n "]]\n} append cmd \ [:frameWorkCmd ::nsf::relation $o object-mixin] \ @@ -795,7 +813,7 @@ if {[$o info has type ::nx::Slot]} { # Slots needs to be initialized to ensure # __invalidateobjectparameter to be called - append cmd [list $o eval :init] \n + append cmd [list ${:targetName} eval :init] \n } $s addPostCmd [:frameWorkCmd ::nsf::relation $o object-filter] @@ -809,6 +827,7 @@ :object method Class-serialize {o s} { set cmd [:Object-serialize $o $s] + foreach i [lsort [$o ::nsf::methods::class::info::methods -callprotection all -path]] { append cmd [:method-serialize $o $i ""] "\n" } @@ -898,7 +917,7 @@ #puts "... [list $o info ${prefix}default $m $v x] returned 1, x?[info exists x] level=[info level]" lappend arglist [list $v $x] } {lappend arglist $v} } - lappend r $o ${prefix}proc $m \ + lappend r ${:targetName} ${prefix}proc $m \ [concat [$o info ${prefix}nonposargs $m] $arglist] \ [$o info ${prefix}body $m] foreach p {pre post} { @@ -913,19 +932,19 @@ :object method Object-serialize {o s} { :collect-var-traces $o $s - append cmd [list [$o info class] create [::nsf::directdispatch $o -frame method ::nsf::current object]] + append cmd [list [$o info class] create ${:targetName}] append cmd " -noinit\n" foreach i [$o ::nsf::methods::object::info::methods -type scripted -callprotection all] { append cmd [:method-serialize $o $i ""] "\n" } foreach i [$o ::nsf::methods::object::info::methods -type forward -callprotection all] { - append cmd [concat [list $o] forward $i [$o info forward -definition $i]] "\n" + append cmd [concat [list ${:targetName}] forward $i [$o info forward -definition $i]] "\n" } foreach i [$o ::nsf::methods::object::info::methods -type setter -callprotection all] { - append cmd [list $o parametercmd $i] "\n" + append cmd [list ${:targetName} parametercmd $i] "\n" } append cmd \ - [list $o eval [join [:collectVars $o $s] "\n "]] \n \ + [list ${:targetName} eval [join [:collectVars $o $s] "\n "]] \n \ [:frameWorkCmd ::nsf::relation $o object-mixin] \ [:frameWorkCmd ::nsf::method::assertion $o object-invar] @@ -943,15 +962,15 @@ append cmd [:method-serialize $o $i inst] "\n" } foreach i [$o info instforward] { - append cmd [concat [list $o] instforward $i [$o info instforward -definition $i]] "\n" + append cmd [concat [list ${:targetName}] instforward $i [$o info instforward -definition $i]] "\n" } foreach i [$o info instparametercmd] { - append cmd [list $o instparametercmd $i] "\n" + append cmd [list ${:targetName} instparametercmd $i] "\n" } # provide limited support for exporting aliases for XOTcl objects foreach i [$o ::nsf::methods::class::info::methods -type alias -callprotection all] { set nxDef [$o ::nsf::methods::class::info::method definition $i] - append cmd [list ::nsf::method::alias $o {*}[lrange $nxDef 3 end]]\n + append cmd [list ::nsf::method::alias ${:targetName} {*}[lrange $nxDef 3 end]]\n } append cmd \ [:frameWorkCmd ::nsf::relation $o superclass -unless ${:rootClass}] \ Index: tests/methods.test =================================================================== diff -u -r6b5a68878186b49871d420ee8e8d5c0f2c073222 -r925485d2ec3b626277037d5fd3154172cc989f7a --- tests/methods.test (.../methods.test) (revision 6b5a68878186b49871d420ee8e8d5c0f2c073222) +++ tests/methods.test (.../methods.test) (revision 925485d2ec3b626277037d5fd3154172cc989f7a) @@ -1029,8 +1029,8 @@ return $target } - #? {::C COPY ::E} ::E ? {::C copy ::D} ::D + ? {::C COPY ::E} ::E ? {lsort [::D info methods -path]} "{a b} {a c} foo fwd set" ? {lsort [::D info object methods -path]} "exists {oa b} {oa c} ofoo ofwd set" @@ -1039,10 +1039,47 @@ ? {::D oa c} "oa c" ? {::D set y} "100" - ::D create d1 - + ? {::D create d1} ::d1 ? {::d1 a b} "a b" ? {::d1 a c} "a c" - ? {::d1 set x 2} 2 + + ? {::E oa b} "oa b" + ? {::E oa c} "oa c" + ? {::E set y} "100" + + ? {::E create e1} ::e1 + ? {::e1 a b} "a b" + ? {::e1 a c} "a c" + ? {::e1 set x 2} 2 + +} + +nx::Test case xotcl-COPY { + package req XOTcl + xotcl::Class create C + C proc foo {} {return foo} + C instproc bar {} {return bar} + C set x 1 + + ::xotcl::Object instproc COPY {target} { + set code [::Serializer deepSerialize -objmap [list [self] $target] [self]] + #puts CODE=$code + eval $code + return $target + } + + ? {C set x} 1 + C copy D + C COPY E + + ? {D set x} 1 + ? {D foo} foo + ? {D create d1} ::d1 + ? {d1 bar} bar + + ? {E set x} 1 + ? {E foo} foo + ? {E create e1} ::e1 + ? {e1 bar} bar } \ No newline at end of file