Index: library/lib/doc-assets/attributemethod.html.tmpl =================================================================== diff -u --- library/lib/doc-assets/attributemethod.html.tmpl (revision 0) +++ library/lib/doc-assets/attributemethod.html.tmpl (revision 9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399) @@ -0,0 +1,78 @@ +
+

+ [$owning_attribute print_name -status]

+
+ [:? {[info exists :@return] && [${:@return} spec] ne ""} {<[${:@return} spec]>} ] + [:? {[$owning_attribute pinfo get -default 0 bundle incremental]} { + /obj/ ${:name} ?value?
+ /obj/ ${:name} add|assign|delete value
+ /obj/ ${:name} get
+ } - { + /obj/ ${:name} ?value? + }] +
+
+ [:? {[$owning_attribute pinfo exists validation]} { + [$owning_attribute pinfo get validation] + }] + [$owning_attribute as_text] +
+ +
+ [:? {[info exists :@parameter]} { +
+
Parameters:
+ [:for param ${:@parameter} { +
+ [$param print_name] + [:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}] + + [$param statusmark] + [$param as_text] + [$param pinfo get -default "" validation] + [:? {[$param eval {info exists :default}]} { +
+ Default Value: [$param default] +
+ }] +
+ }] +
+ }] + + [:? {[info exists :@return]} { +
+
Returns: + + [:? {[${:@return} eval {info exists :spec}] && [${:@return} spec] ne ""} {[${:@return} spec]}] +
+
[${:@return} as_text]
+
+ }] + + [:? ${:@deprecated} { +
+ Deprecated +
+ }] + +
+
Type:
+
[:pinfo get bundle type]
attribute accessor/mutator
[:? {${:@syshook}} {
+internally called, redefinable hook
+ }] +
+ +
+
Protection:
+ [:? {[:pinfo get -default 0 bundle redefine-protected]} { +
redefine-protected
+ }] +
+ + +
+ +
+
+
Index: library/lib/doc-assets/class.html.tmpl =================================================================== diff -u -r170cefa7618f2b44f91102711607fc6fa7d12c4f -r9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399 --- library/lib/doc-assets/class.html.tmpl (.../class.html.tmpl) (revision 170cefa7618f2b44f91102711607fc6fa7d12c4f) +++ library/lib/doc-assets/class.html.tmpl (.../class.html.tmpl) (revision 9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399) @@ -26,15 +26,15 @@ [:?var :@class-attribute { -[:!let class_attrs [:!get -sortedby name @class-attribute]] +[:!let class_attrs [:!get -sortedby name -with name @class-attribute]]

Per-class parameters

- [:for attr $class_attrs { + [:for attr [dict values $class_attrs] {
- [:for attr $class_attrs { + [:for attr [dict values $class_attrs] {
-

[$attr name] +

[$attr print_name -status]

+ [:? {[$attr pinfo exists validation]} { + [$attr pinfo get validation] + }] [$attr as_text]
@@ -71,9 +74,11 @@ }]
-
}] +
+
+
}] [:!let iattrs [:inherited @class-attribute]] @@ -164,12 +169,16 @@
[:for method $class_methods { + [:? {[info exists class_attrs] && [dict exists $class_attrs [$method name]]} { + [$method render -initscript [list set owning_attribute [dict get $class_attrs [$method name]]] attributemethod.html.tmpl] + } - { [$method render method.html.tmpl] + }] }]
- }] +}] [:!let imethods [:inherited @class-method]] [:? {$imethods ne ""} { @@ -198,11 +207,15 @@ }] + + + + [:?var :@method { Undocumented Methods: [:undocumented] }] - + [:?var :@object-method {
@@ -215,7 +228,6 @@
[:? {[$omethod eval {info exists :@return}]} {<[[$omethod @return] spec]>} ] [$omethod name] - [$omethod parameters]
[$omethod as_text] Index: library/lib/doc-assets/command.html.tmpl =================================================================== diff -u -r459ae500daf2a8e5012c8f59519d3adfd7e3c2e7 -r9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399 --- library/lib/doc-assets/command.html.tmpl (.../command.html.tmpl) (revision 459ae500daf2a8e5012c8f59519d3adfd7e3c2e7) +++ library/lib/doc-assets/command.html.tmpl (.../command.html.tmpl) (revision 9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399) @@ -38,7 +38,7 @@ [:? {[$sub eval {info exists :@return}] && [[$sub @return] spec] ne ""} {<[[$sub @return] spec]>} ] ${:name} [$sub name] - [$sub parameters] + [$sub pinfo get -default "" bundle parametersyntax]
[$sub as_text] Index: library/lib/doc-assets/entity.html.tmpl =================================================================== diff -u -r170cefa7618f2b44f91102711607fc6fa7d12c4f -r9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399 --- library/lib/doc-assets/entity.html.tmpl (.../entity.html.tmpl) (revision 170cefa7618f2b44f91102711607fc6fa7d12c4f) +++ library/lib/doc-assets/entity.html.tmpl (.../entity.html.tmpl) (revision 9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399) @@ -41,30 +41,32 @@ [:!let self_owned_parts [[:origin] owned_parts]] [:!let owned_parts [dict merge $project_entities $self_owned_parts]]
-
-
- [:? {[:info has type ::nx::doc::@package]} { - [:include package.html.tmpl] - } ? {[:info has type ::nx::doc::@class]} { - [:include class.html.tmpl] - } ? {[:info has type ::nx::doc::@command]} { - [:include command.html.tmpl] - } ? {[:info has type ::nx::doc::@project]} { -
- This is the API documentation for the - [:name] project. -

Choose a package, object or command name from the list for more information.

-
- [:include glossary.html.tmpl] - }] -
-
-
- [:include leftbar.html.tmpl] -
+
+
+ [:? {[:info has type ::nx::doc::@package]} { + [:include package.html.tmpl] + } ? {[:info has type ::nx::doc::@class]} { + [:include class.html.tmpl] + } ? {[:info has type ::nx::doc::@object]} { + [:include object.html.tmpl] + } ? {[:info has type ::nx::doc::@command]} { + [:include command.html.tmpl] + } ? {[:info has type ::nx::doc::@project]} { +
+ This is the API documentation for the + [:name] project. +

Choose a package, object or command name from the list for more information.

+ [:include glossary.html.tmpl] + }] +
+
+
+ [:include leftbar.html.tmpl] +
+
-
+
Copyright © [clock format [clock seconds] -format "%Y"]
Index: library/lib/doc-assets/method.html.tmpl =================================================================== diff -u -r239888ee1ee6ed6d7b9afa5e170f49c5224a186d -r9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399 --- library/lib/doc-assets/method.html.tmpl (.../method.html.tmpl) (revision 239888ee1ee6ed6d7b9afa5e170f49c5224a186d) +++ library/lib/doc-assets/method.html.tmpl (.../method.html.tmpl) (revision 9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399) @@ -1,77 +1,78 @@

[:print_name -status]

-
- [:? {[info exists :@return] && [${:@return} spec] ne ""} {<[${:@return} spec]>} ] - ${:name} - [:pinfo get -default "" bundle parametersyntax] - -
- [:as_text] -
+
+ [:? {[info exists :@return] && [${:@return} spec] ne ""} {<[${:@return} spec]>} ] + /obj/ + ${:name} + [:pinfo get -default "" bundle parametersyntax] + +
+ [:as_text] +
+ +
+ [:?var :@method { +
+ [:for sm [:get_sub_methods] { + [$sm render -initscript [list set supermethod [current]] submethod.html.tmpl] + }] + } - { + [:?var :@parameter { +
+
Parameters:
+ [:for param [:!get @parameter] { +
+ [$param print_name] + [:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}] + + [$param statusmark] + [$param as_text] + [$param pinfo get -default "" validation] + [:? {[$param eval {info exists :default}]} { +
+ Default Value: [$param default] +
+ }] +
+ }] +
+ }] + + [:?var :@return { +
+
Returns: + [:!let ret [:!get @return]] + [:? {[$ret eval {info exists :spec}] && [$ret spec] ne ""} {[$ret spec]}] +
+
[${:@return} as_text]
+
+ }] + }] + + [:? {[:!get @deprecated]} { +
+ Deprecated +
+ }] + +
+
Type:
+
[:pinfo get bundle type]
[:? {[:!get @syshook]} { +
+ internally called, redefinable hook
+ }] +
-
- [:?var :@method { -
- [:for sm [:get_sub_methods] { - [$sm render -initscript [list set supermethod [current]] submethod.html.tmpl] - }] - } - { - [:? {[info exists :@parameter]} { -
-
Parameters:
- [:for param ${:@parameter} { -
- [$param print_name] - [:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}] - - [$param statusmark] - [$param as_text] - [$param pinfo get -default "" validation] - [:? {[$param eval {info exists :default}]} { -
- Default Value: [$param default] -
- }] -
- }] -
- }] - - [:? {[info exists :@return]} { -
-
Returns: - - [:? {[${:@return} eval {info exists :spec}] && [${:@return} spec] ne ""} {[${:@return} spec]}] -
-
[${:@return} as_text]
-
- }] - }] - - [:? ${:@deprecated} { -
- Deprecated -
- }] - -
-
Type:
-
[:pinfo get bundle type]
[:? {${:@syshook}} {
-internally called, redefinable hook
- }] -
- -
-
Protection:
- [:? {[:pinfo get -default 0 bundle redefine-protected]} { -
redefine-protected
- }] -
- - -
- -
-
-
+
+
Protection:
+ [:? {[:pinfo get -default 0 bundle redefine-protected]} { +
redefine-protected
+ }] +
+ + +
+
+
+
Fisheye: Tag c4cc0944433a7cc9ae99612039aa0237ae70ec08 refers to a dead (removed) revision in file `library/lib/doc-assets/object.html.tmpl'. Fisheye: No comparison available. Pass `N' to diff? Index: library/lib/doc-assets/submethod.html.tmpl =================================================================== diff -u -r459ae500daf2a8e5012c8f59519d3adfd7e3c2e7 -r9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399 --- library/lib/doc-assets/submethod.html.tmpl (.../submethod.html.tmpl) (revision 459ae500daf2a8e5012c8f59519d3adfd7e3c2e7) +++ library/lib/doc-assets/submethod.html.tmpl (.../submethod.html.tmpl) (revision 9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399) @@ -1,24 +1,26 @@ [:!let name [:get_combined name]]
-

$name +

$name[:statusmark]

[:? {[info exists :@return] && [${:@return} spec] ne ""} {<[${:@return} spec]>} ] - [$supermethod name] + /obj/ $name - [:parameters] + [:pinfo get -default "" bundle parametersyntax]
[:as_text] [:? {[info exists :@parameter]} {
-
Submethod parameters:
+
Parameters:
[:for param ${:@parameter} {
[$param name] [:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}] + [$param statusmark] [$param as_text] + [$param pinfo get -default "" validation]
}]
Index: library/lib/doc-tools.tcl =================================================================== diff -u -rcc94b154709f9bd3393fbbdb9af982a30b57dee0 -r9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399 --- library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision cc94b154709f9bd3393fbbdb9af982a30b57dee0) +++ library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision 9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399) @@ -384,7 +384,7 @@ Class create PartTag -superclass Tag { :public method id {partof_name scope name} { - next [list -partof_name $partof_name -scope $scope $name] + next [list -partof_name $partof_name -scope $scope -- $name] } :public method new { @@ -428,6 +428,7 @@ :method init args { :defaultmethods [list get append] :multivalued true + :allowempty true set :incremental true # TODO: setting a default value leads to erratic behaviour; # needs to be verified -> @author returns "" @@ -576,7 +577,7 @@ return [concat {*}$path] } - :attribute @doc:multivalued {set :incremental 1} + :attribute @doc:0..* {set :incremental 1} :attribute @see -slotclass ::nx::doc::PartAttribute :attribute @deprecated:boolean -slotclass ::nx::doc::SwitchAttribute { @@ -684,7 +685,9 @@ Class create StructuredEntity -superclass Entity { :public method part_attributes {} { - set slots [:info lookup slots] + #set slots [:info lookup slots] + set slots [::nsf::dispatch [::nsf::self] ::nsf::methods::object::info::lookupslots -type ::nx::Slot] + set attrs [list] foreach s $slots { if {![$s info has type ::nx::doc::PartAttribute] || ![$s eval {info exists :part_class}]} continue; @@ -708,7 +711,11 @@ dict for {s entities} [:owned_parts] { foreach e $entities { - $e [current method] + # TODO: for now, it is sufficient to escape @use chains + # here. review later ... + if {![$e eval {info exists :@use}]} { + $e [current method] + } } } } @@ -922,19 +929,6 @@ } set :part_class ::nx::doc::@command } - :public method parameters {} { - set params [list] - if {[info exists :@parameter]} { - foreach p [:@parameter] { - set value [$p name] - if {[$p eval {info exists :default}] || [$p name] eq "args" } { - set value "?[$p name]?" - } - lappend params $value - } - } - return $params - } } QualifierTag create @object \ @@ -1121,89 +1115,9 @@ return ::nsf::${scope}::[string trimleft [[:partof] name] :]::${:name} } - :public method parameters {} { - set params [list] - if {[info exists :@parameter]} { - foreach p [:@parameter] { - set value [$p name] - if {[$p eval {info exists :default}] || [$p name] eq "args" } { - set value "?[$p name]?" - } - lappend params $value - } - } - if {1} { - # documentaion quality check: is documentation in sync with implementation? - # TODO: make me conditional, MARKUP should be in templates - set object [${:partof} name] - if {[::nsf::isobject $object]} { - if {[$object info methods -callprotection all ${:name}] ne ""} { - set actualParams "" - if {[$object info method type ${:name}] eq "forward"} { - set cmd "" - foreach w [lrange [$object info method definition ${:name}] 2 end] { - if {[string match ::* $w]} { - set cmd $w - break - } - } - if {$cmd ne "" && [string match ::nsf::* $cmd]} { - # TODO: we assume here, the cmd is a primitive - # command and we intend only to handle cases from - # predefined or xotcl2. Make sure this is working - # reasonable for other cases, such as forwards to - # other objects, as well - if {![catch {set actualParams [::nx::Object info method parameter $cmd]}]} { - # drop usual object - set actualParams [lrange $actualParams 1 end] - # drop per object ; TODO: always? - if {[lindex $actualParams 0] eq "-per-object"} { - set actualParams [lrange $actualParams 1 end] - set syntax [lrange [::nx::Object info method parametersyntax $cmd] 2 end] - } else { - set syntax [lrange [::nx::Object info method parametersyntax $cmd] 1 end] - } - } - } - set comment "Defined as a forwarder, can't check" - #set handle ::nsf::signature($object-class-${:name}) - #if {[info exists $handle]} {append comment
[set $handle]} - } else { - # TODO: requesting the param spec of an ensemble - # object (info) does not work right now? How to deal - # with it? - if {($object eq "::nx::Object" || $object eq "::nx::Class") && ${:name} eq "info"} { - set actualParams "" - set syntax "" - } else { - set actualParams [$object info method parameter ${:name}] - set syntax [$object info method parametersyntax ${:name}] - } - } - if {$actualParams eq $params} { - set comment "Perfect match" - } else { - set comment "actual parameter: $actualParams" - if {[info exists :pdata]} { - lappend :pdata status mismatch - } - } - append comment "
Syntax: obj ${:name} $syntax" - } else { - set comment "Method '${:name}' not defined on $object" - } - } else { - set comment "cannot check object, probably not instantiated" - } - return [concat $params
$comment] - } - return $params - } - :public method validate {} { set partof [:get_owning_partof] - if {[:pinfo get -default complete status] ne "missing"} { - next + if {[info exists :pdata] && [:pinfo get -default complete status] ne "missing"} { # # Note: Some information on methods cannot be retrieved from # within the tracers as they might not be set local to the @@ -1252,9 +1166,14 @@ if {![:pinfo exists bundle parametersyntax]} { :pinfo set bundle parametersyntax $params } + + # Note: [next] will cause the missing parameter created to + # be validated and will have the appropriate status + # upstream! + next } else { # the method is missing -> this makes the owning object a mismatch - $partof pinfo set status mismatch + ${:partof} pinfo propagate status mismatch } } @@ -1335,6 +1254,7 @@ # @param -partof # @param -name # @param args + :public class-object method new { -part_attribute -partof:required @@ -1354,11 +1274,25 @@ } + :public method get_fqn_command_name {} { + # ::nx::Object::slot::class + if {[${:partof} info has type ::nx::doc::@object]} { + return "[${:partof} name]::slot::${:name}" + } else { + next + } + } + + + :public method validate {} { - if {[:pinfo get -default complete status] ne "missing"} { - if {[info exists :spec] && ${:spec} ne [:pinfo get bundle spec]} { + if {[info exists :pdata] && [:pinfo get -default complete status] ne "missing"} { + # valid for both object and method parameters + set pspec [:pinfo get -default "" bundle spec] + if {[info exists :spec] && \ + ${:spec} ne $pspec} { :pinfo propagate status mismatch - :pinfo set validation "Specification mismatch: [:pinfo get bundle spec]" + :pinfo set validation "Specification mismatch. Expected: '${:spec}' Got: '$pspec'." } } else { ${:partof} pinfo propagate status mismatch @@ -1468,12 +1402,23 @@ return } - :method !get {-sortedby varname} { + :public method !get {-sortedby -with varname} { + if {![[:origin] eval [list info exists :$varname]]} return; if {[info exists sortedby]} { - uplevel 1 [list sorted [[:origin] eval [list ::set :$varname]] $sortedby] + set r [uplevel 1 [list sorted [[:origin] eval [list ::set :$varname]] $sortedby]] } else { - uplevel 1 [list [:origin] eval [list ::set :$varname] ] + set r [uplevel 1 [list [:origin] eval [list ::set :$varname] ]] } + + if {[info exists with]} { + set l [list] + foreach item $r { + lappend l [$item eval [list set :$with]] $item + } + set r $l + } + + return $r } :method for {var list body} { @@ -1491,7 +1436,7 @@ "\[$obj eval {info exists :$varname}\]" {*}$args] } - :method ?var {varname args} { + :public method ?var {varname args} { set cmd [expr {[string match ":*" $varname]?"\[[:origin] eval {info exists $varname}\]":"\[info exists $varname\]"}] uplevel 1 [list :? -ops [list [::nsf::current method] -] \ $cmd {*}$args] @@ -1637,14 +1582,18 @@ # Make sure that the @project entity is processed last. # lappend values [current object] + + # Note: We trigger the validation of entities according to + # their pdata once for the entire entity hierarchy, starting + # from the root, i.e. the project entity. + :validate foreach e $values { # # TODO: For now, in templates we (silently) assume that we act # upon structured entities only ... # if {![$e info has type ::nx::doc::StructuredEntity]} continue; $e current_project [current object] - $e validate set content [$e render -initscript $init $tmpl] :write_data $content [file join $project_path "[$e filename].$ext"] puts stderr "$e written to [file join $project_path [$e filename].$ext]" @@ -2069,7 +2018,7 @@ } :protected attribute {current_packages "*"} - :attribute {permissive_pkgs:multivalued "*"} { + :attribute {permissive_pkgs:1..* "*"} { set :incremental 1 } @@ -2322,41 +2271,124 @@ set ::nx::doc::rootns [namespace qualifier $rootmclass] $rootmclass $sysmeths(-class.create) ${::nx::doc::rootns}::__Tracer ::nsf::method ${::nx::doc::rootns}::__Tracer \ - -public $sysmeths(-class.create) {name args} { - set obj [::nsf::next]; + -public $sysmeths(-class.create) {name args} { + set obj [::nsf::next]; + set bundle [dict create] + if {[info commands "::nx::Class"] ne ""} { + if {[::nsf::dispatch $obj ::nsf::methods::object::info::hastype ::nx::Slot]} { + dict set bundle objtype slot + dict set bundle incremental [expr {[::nsf::dispatch $obj ::nsf::methods::object::info::hastype ::nx::ObjectParameterSlot] || ([::nsf::dispatch $obj ::nsf::methods::object::info::hastype ::nx::Attribute] && [::nsf::existsvar $obj incremental] && [::nsf::setvar $obj incremental])}] + } + if {[::nsf::dispatch $obj ::nsf::methods::object::info::hastype ::nx::EnsembleObject]} { + dict set bundle objtype ensemble + } + } set cmdtype [expr {[::nsf::is class $obj]?"@class":"@object"}] ::nx::doc::__at_register_command $obj \ ->cmdtype $cmdtype \ ->source [file normalize [info script]] \ ->nsexported [::nx::doc::is_exported $obj] \ + ->bundle $bundle \ {*}[expr {[::nsf::existsvar $obj __initcmd] && [::nsf::setvar $obj __initcmd] ne ""?[list ->docstring [::nsf::setvar $obj __initcmd]]:[list]}] return $obj } - # ISSUE: yields -> bad relationtype "mixin": must be # object-mixin, class-mixin, object-filter, # class-filter, class, superclass, or rootclass # -> ::nsf::mixin defaults to "mixin" instead of "class-mixin" # ::nsf::mixin $rootmclass ::nsf::__Tracer ::nsf::relation $rootmclass class-mixin ${::nx::doc::rootns}::__Tracer - + + if {[info commands "::nx::Object"] ne ""} { + $rootmclass $sysmeths(-class.create) ${::nx::doc::rootns}::__ObjTracer + ::nsf::method ${::nx::doc::rootns}::__ObjTracer \ + -public __resolve_method_path { + -per-object:switch + -verbose:switch + path + } { + array set "" [::nsf::next] + set l [llength $path] + if {$l > 1} { + set target $(object) + set objects [list] + for {set j 1} {$j < [expr {$l-1}]} {incr j} { + set target [namespace qualifiers $target] + lappend objects $target + } + lappend objects [::nsf::current object] + set first 1 + foreach leg [lrange $path 0 end-1] obj [lreverse $objects] { + if {$first} { + set scope [expr {${per-object}?"object":"class"}] + set first 0 + } else { + set scope object + } + + set handle [::nsf::dispatch $obj \ + ::nsf::methods::${scope}::info::method \ + handle $leg] + if {![::nsf::existsvar [::nsf::current class] handles] || ![[::nsf::current class] eval [concat dict exists \${:handles} $handle]]} { + dict set bundle handle $handle + dict set bundle handleinfo [::nx::doc::handleinfo $handle] + dict set bundle type [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::${scope}::info::method type $handle] + if {![catch {set pa [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::${scope}::info::method parameter $handle]} _]} { + foreach pspec $pa { + dict set bundle parameter {*}[::nx::doc::paraminfo {*}$pspec] + } + } + if {![catch {set psyn [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::${scope}::info::method parametersyntax $handle]} _]} { + dict set bundle parametersyntax $psyn + } + ::nx::doc::__at_register_command $handle \ + ->cmdtype @method \ + ->source [file normalize [info script]] \ + ->bundle $bundle + [::nsf::current class] eval [list dict set :handles $handle _] + } + } + } + + return [array get ""] + } + ::nsf::relation $rootclass class-mixin ${::nx::doc::rootns}::__ObjTracer + } + ::interp invokehidden "" proc ::nx::doc::handleinfo {handle} { set definition [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::object::info::method definition $handle] if {$definition ne ""} { set obj [lindex $definition 0] set modifier [lindex $definition 2] - if {$modifier eq "class-object"} { + if {[lindex $definition 1] eq "create"} { + set obj $modifier + set scope "" + set name "" + } elseif {$modifier eq "class-object"} { set scope $modifier set name [lindex $definition 4] } else { set scope "" set name [lindex $definition 3] } } + if {$scope eq ""} { + set is_method 0 + set obj [concat {*}[split [string trimleft $obj :] "::"]] + foreach label $obj { + if {$label eq "slot"} {set is_method 1; continue;} + if {$is_method} { + lappend method_name [string trimleft $label _] + } else { + lappend obj_name $label + } + } + set name [lappend method_name {*}$name] + set obj ::[join $obj_name "::"] + } return [list $obj $scope $name] } - ::interp invokehidden "" proc ::nx::doc::paraminfo { value {default ""} } { @@ -2382,7 +2414,6 @@ set bundle [dict create] dict set bundle handle $handle dict set bundle handleinfo [::nx::doc::handleinfo $handle] -# dict set bundle parameter [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::object::info::method parameter $handle] foreach pspec [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::object::info::method parameter $handle] { dict set bundle parameter {*}[::nx::doc::paraminfo {*}$pspec] } @@ -2406,6 +2437,14 @@ dict set bundle handle $handle dict set bundle handleinfo [::nx::doc::handleinfo $handle] dict set bundle type [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::object::info::method type $handle] + if {![catch {set pa [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::object::info::method parameter $handle]} _]} { + foreach pspec $pa { + dict set bundle parameter {*}[::nx::doc::paraminfo {*}$pspec] + } + } + if {![catch {set psyn [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::object::info::method parametersyntax $handle]} _]} { + dict set bundle parametersyntax $psyn + } ::nx::doc::__at_register_command $handle \ ->cmdtype @method \ @@ -2415,11 +2454,57 @@ return $handle } + # if {[$object info method type ${:name}] eq "forward"} { + # set cmd "" + # foreach w [lrange [$object info method definition ${:name}] 2 end] { + # if {[string match ::* $w]} { + # set cmd $w + # break + # } + # } + # if {$cmd ne "" && [string match ::nsf::* $cmd]} { + # # TODO: we assume here, the cmd is a primitive + # # command and we intend only to handle cases from + # # predefined or xotcl2. Make sure this is working + # # reasonable for other cases, such as forwards to + # # other objects, as well + # if {![catch {set actualParams [::nx::Object info method parameter $cmd]}]} { + # # drop usual object + # set actualParams [lrange $actualParams 1 end] + # # drop per object ; TODO: always? + # if {[lindex $actualParams 0] eq "-per-object"} { + # set actualParams [lrange $actualParams 1 end] + # set syntax [lrange [::nx::Object info method parametersyntax $cmd] 2 end] + # } else { + # set syntax [lrange [::nx::Object info method parametersyntax $cmd] 1 end] + # } + # } + # } + # } + + rename ::nsf::forward ::nsf::_%&forward ::interp invokehidden "" proc ::nsf::forward { + args + } { + set handle [uplevel [list ::nsf::_%&forward {*}$args]] + if {$handle ne ""} { + dict set bundle handle $handle + dict set bundle handleinfo [::nx::doc::handleinfo $handle] + dict set bundle type [::nsf::dispatch ${::nx::doc::rootns}::__Tracer ::nsf::methods::object::info::method type $handle] + + ::nx::doc::__at_register_command $handle \ + ->cmdtype @method \ + ->source [file normalize [info script]] \ + ->bundle $bundle + } + } + + rename ::nsf::setter ::nsf::_%&setter + ::interp invokehidden "" proc ::nsf::setter { args } { - set handle [uplevel [list ::nsf::_%&forward {*}$args]] + set handle [uplevel [list ::nsf::_%&setter {*}$args]] if {$handle ne ""} { dict set bundle handle $handle dict set bundle handleinfo [::nx::doc::handleinfo $handle] @@ -2655,6 +2740,28 @@ } } + Mixin create [current]::@method -superclass [current]::Entity { + :method init args { + next + set scope [expr {[${:part_attribute} scope] eq "class"?"class":"object"}] + set obj [:get_owning_object] + set method_name [:get_combined name] + set prj [:current_project] + if {$prj ne ""} { + set box [$prj sandbox] + #puts stderr "--- ::nsf::dispatch $obj ::nsf::methods::${scope}::info::method handle $method_name" + set script "array set \"\" \[$obj eval {:__resolve_method_path \"$method_name\"}\]; ::nsf::dispatch \$(object) ::nsf::methods::${scope}::info::method handle \$(methodName)" + set cmdname [$box do $script] + if {$cmdname ne "" && [$box eval [concat dict exists \${:registered_commands} $cmdname]]} { + #puts stderr "--- SETTING PDATA for [current] -> $cmdname" + #puts stderr "[$box eval [concat dict get \${:registered_commands} $cmdname]]" + :pdata [$box eval [concat dict get \${:registered_commands} $cmdname]] + } + } + + } + } + Mixin create [current]::@param -superclass [current]::Entity { :public method init args { next @@ -2760,44 +2867,83 @@ # output # 1. absent entities (doc[yes]->program[no]) # => all doc entities without pdata - # puts stderr "--- $provided_entities" - set present_entities [::nx::doc::filtered $provided_entities {[info exists :pdata]}] + # ::nx::doc::entities::method::nx::Class::class::info + # ::nsf::classes::nx::Class::info + #puts stderr "--- $provided_entities" + set present_entities [::nx::doc::filtered $provided_entities {[[:origin] eval {info exists :pdata}]}] # TODO: the nspatterns should be consumed from the source # specification and should not be hardcoded here ... review # later ... - #set generated_commands [$box get_registered_commands [list ::nsf ::nx]] - set generated_commands [dict merge [$box get_registered_commands -exported -types {@object @class @command}] [$box get_registered_commands -types @method]] + # set generated_commands [$box get_registered_commands [list ::nsf ::nx]] + # ISSUE: -exported turns out to be a weak filter criterion, it + # excludes slot objects from being processed + set generated_commands [dict merge [$box get_registered_commands -types {@object @class @command}] [$box get_registered_commands -types @method]] set map [dict create] foreach pe $present_entities { - set fqn [$pe get_fqn_command_name] + if {[$pe pinfo exists bundle handle]} { + set fqn [$pe pinfo get bundle handle] + } else { + set fqn [$pe get_fqn_command_name] + } dict unset generated_commands $fqn dict set map $fqn $pe } -# puts stderr "PRESENT $present_entities" -# puts stderr "ABSENT [::nx::doc::filtered $provided_entities {![info exists :pdata]}]" + # 2. generated entities (doc[no]->program[yes]) # => all registered_commands without doc entity #puts stderr "== TO GENERATE == [join [dict keys $generated_commands] \n]" dict for {cmd info} $generated_commands { - #if {[string match ::nsf::classes::* $cmd]} continue; - #if {[string match ::nsf::objects::* $cmd]} continue; - if {[string match *::slot::* $cmd]} continue; dict with info { # # TODO: for now, we assume objects beyond this point # ... relax later! # if {$cmdtype ni [list @command @object @class @method]} continue; - if {$cmdtype eq "@method"} { + if {$cmdtype eq "@object" && [string match *::slot::* $cmd]} { + if {[dict exists $info bundle objtype] && [dict get $info bundle objtype] eq "ensemble"} continue; + set name [namespace tail $cmd] + set scope "" + set obj [namespace qualifiers [namespace qualifiers $cmd]] + if {![dict exists $map $obj]} continue; + set partof_entity [dict get $map $obj] + set entity [$partof_entity @[join [list {*}${scope} attribute] -] $name] + } elseif {$cmdtype eq "@method"} { lassign [dict get $bundle handleinfo] obj scope name # ! we assume the partof entity is present or has been generated if {![dict exists $map $obj]} continue; set partof_entity [dict get $map $obj] - set entity [$partof_entity @[join [list {*}${scope} method] -] $name] + if {![$partof_entity info has type ::nx::doc::@object]} continue; + set owning_entity $partof_entity + foreach subm $name { + # + # TODO: [info info] causes an issue because in terms of + # doc entities, it overwrites the info alias for the doc + # entity object ... verify: + # ::nx::doc::entities::method::nx::Object::class::info::info: unable to dispatch method '::nx::doc::entities::method::nx::Object::class::info' + # ::nx::doc::entities::method::nx::Object::class::info->info + # invoked from within + # ":info class" + # (procedure "make_link" line 4) + # ::nx::doc::entities::method::nx::Object::class::info ::nx::doc::NxDocRenderer::Entity->make_link + # invoked from within + # "$src make_link [current]" + + # + if {[$partof_entity name] eq "info" && $subm eq "info"} break; + set en [$partof_entity @[join [list {*}${scope} method] -] id $subm] + if {$en ni $provided_entities} { + set partof_entity [$partof_entity @[join [list {*}${scope} method] -] $subm] + } else { + set partof_entity $en + } + + } + # ISSUE: the following line is part of the [info info] fix, review later ... + if {$partof_entity in $provided_entities} continue; + set entity $partof_entity if {[dict exists $info bundle parameter]} { dict for {pname paraminfo} [dict get $info bundle parameter] { lassign $paraminfo spec default - set paramid [@parameter id $entity "" $pname] set ppdata [list bundle [list spec $spec default $default]] if {$paramid ni $provided_entities} { @@ -2810,23 +2956,11 @@ } else { set entity [@ $cmdtype $cmd] } - #-> ::nsf::classes::nx::CopyHandler::targetList - # @class.method {::nx::CopyHandler targetList} - #:process=$cmdtype $project $entity + #puts stderr "SETTING missing PDATA $entity $cmd" $entity pdata [lappend info status missing] dict set map [$entity get_fqn_command_name] $entity } - - :method generate_parameter {value} { - set colon_pos [string first : $value] - if {$colon_pos == -1} { - set name $value - } else { - set properties [string range $value [expr {$colonPos+1}] end] - set name [string range $value 0 [expr {$colonPos -1}]] - } - } } } Index: library/nx/nx.nxd =================================================================== diff -u -r239888ee1ee6ed6d7b9afa5e170f49c5224a186d -r9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399 --- library/nx/nx.nxd (.../nx.nxd) (revision 239888ee1ee6ed6d7b9afa5e170f49c5224a186d) +++ library/nx/nx.nxd (.../nx.nxd) (revision 9e98d057e87eb5d9bf8cd3a25dc679ed02cd6399) @@ -465,6 +465,9 @@ # Tests whether the class passed as the argument is a type of the # object, i.e., whether the object is an instance of the given class # or of one of the class's superclasses. +# +# @parameter class hallo +# @parameter class2 helo # @class.method {Object "info methods"} # @@ -523,7 +526,7 @@ # # @superclass ::nx::doc::entities::class::nx::Slot -# @class.attribute {Slot name} +# @class.attribute {Slot name:string} # # Name of the <<@gls slot>> which can be used to access the <<@gls # slot>> data from an object @@ -592,9 +595,6 @@ # **** '''superclass''' changes the list # of superclasses. When used as a getter, the method returns the # current superclasses. -# -# @return :list If called as a getter (without arguments), -# '''superclass''' returns the current superclasses of the object # @class.attribute {Object class} # @@ -606,7 +606,7 @@ # @return If called as a getter (without arguments), '''class''' # returns the current <<@gls class>> of the object -# @class.attribute {Object mixin} +# class.attribute {Object mixin} # # As a setter, '''mixin''' specifies a list of <<@glspl mixincls>> to # set. Every mixin must be an existing class. In getter mode, you can