Index: generic/predefined.nxd =================================================================== diff -u --- generic/predefined.nxd (revision 0) +++ generic/predefined.nxd (revision 25f4f3c883ff0021b8564377f6658afb69c346c8) @@ -0,0 +1,295 @@ +# @command assertion +# +# @parameter object:object +# @parameter assertionsubcmd:required +# @parameter arg + +# @command existsvar +# +# @parameter object:object +# @parameter var + +# @command methodproperty +# +# @parameter object:object +# @parameter -per-object:switch +# @parameter methodName +# @parameter methodproperty Accepts one of: {{{protected}}}, +# {{{redefine-protected}}}, {{{returns}}}, {{{slotobj}}} +# @parameter value + +# @command setter +# +# @parameter object:object +# @parameter -per-object:switch +# @parameter parameter + +# @command createobjectsystem +# +# @parameter rootClass +# @parameter rootMetaClass +# @parameter systemMethods:optional + +# @command dispatch +# +# @parameter object:object +# @parameter -objscope +# @parameter command +# @parameter args + +# @command deprecated +# +# @parameter what +# @parameter oldCmd +# @parameter newCmd:optional + +# @command objectproperty +# +# @parameter object:object +# @parameter objectkind Accepts one of: {{{type}}}, {{{object}}}, +# {{{class}}}, {{{baseclass}}}, {{{metaclass}}}, {{{hasmixin}}} +# @parameter value:optional + +# @command importvar +# +# @parameter object:object +# @parameter args + +# @command parametercheck +# +# @parameter -nocomplain +# @parameter param +# @parameter value:optional + +# @command forward +# +# @parameter object:object +# @parameter -per-object:switch +# @parameter method +# @parameter -default +# @parameter -earlybinding:switch +# @parameter -methodprefix +# @parameter -objscope:switch +# @parameter -onerror +# @parameter -verbose:switch +# @parameter target +# @parameter args + +# @command setvar +# +# @parameter object:object +# @parameter variable +# @parameter value + +# @command method +# +# @parameter object:object +# @parameter -inner-namespace +# @parameter -per-object +# @parameter -public +# @parameter name +# @parameter args +# @parameter body +# @parameter -percondition +# @parameter -postcondition + +# @command next +# +# Invokes the shadowed (i.e, same-named) method which is next along +# the precedence path and returns the results of this invocation. If +# {{{next}}} is called without arguments, the arguments of the current +# method (i.e., the arguments as present at the current callframe) are +# passed through to the shadowed method. If next is invoked with the +# flag --noArgs, the shadowed method is called without the active +# callframe arguments. If other arguments are specified for {{{next}}} +# explicitly, these will be passed instead. +# +# @parameter --noArgs:optional Deactivates the forward-passing of the current callframe's arguments +# @parameter args Explicitly declared arguments to pass to shadowed methods + + +# @command current +# +# An introspective command which allows you to explore the "Next" +# callstack from within the scope of a method (or procif bound to an +# object via {{{alias}}}). {{{current}}} computes callstack related +# information. If executed without specifying a subcommand, +# i.e. {{{[current]}}}, returns the name of the object, which is +# currently in execution. If called from outside a proc, it returns +# the error message "No current object". +# +# It comes with a variety of subcommands to query different bits of +# callstack information. See below. +# +# @sub-command class Returns the name of the class holding the +# currently executing per-class method, if and only if called from +# within a per-class method. Note, that this method-owning class may +# be different to the class of the current object. If called from +# within a per-object method, it returns an empty string. +# +# @sub-command proc Returns the name of the currently executing method. +# +# @sub-command callingclass Returns the name of the class which is +# calling into the executing method. +# +# @sub-command callingobject Returns the name of the object which is +# calling into the executing method. +# +# @sub-command calledclass Returns the name of the class that holds +# the originally (and now shadowed) target method (applicable in +# mixin classes and filters). +# +# @sub-command calledproc Returns the name of the target method +# (applicable in a filter only). +# +# @sub-command isnextcall Returns 1 if the executing method was +# invoked via {{@command ::nx::next}}, 0 otherwise. +# +# @sub-command next Returns the name of the method next on the +# precedence path as a string. +# +# @sub-command filterreg In a method serving as active filter, +# returns the name of the object (class) on which the method is +# registered as a filter. +# +# @sub-command callinglevel Returns the "original" callstack level +# calling into the executing method. Intermediary {{{next}}} calls +# are ignored in this computation. The level is returned in a form +# so that it can be used as first argument in {{@method ::nx::Object +# class uplevel}} or {{@method ::nx::Object class upvar}}. +# +# @sub-command activelevel Returns the actual callstack level calling +# into the executing method. The active might correspond the +# {{{callinglevel}}}, but this is not necessarily the case. The +# {{{activelevel}}} counts {{@command ::nx::next}} call. The level +# is returned in a form so that it can be used as first argument in +# {{@method ::nx::Object class uplevel}} or {{@method ::nx::Object +# class upvar}}. + +# @command configure +# +# A top-level configuration facility which allows you modify +# properties of the "Next" object system for the scope of an entire +# {{{interp}}}. + +# @command.sub-command {configure filter} +# +# Allows turning on or off filters globally for the current +# interpreter. By default, the filter state is turned off. This +# function returns the old filter state. This filterless {{{interp}}} +# state is needed for the serializer which should introspect and stream the +# objects and classes without being affected by active filter. +# +# @parameter toggle Accepts either "on" or "off" +# @return The current filter activation state + +# @command.sub-command {configure softrecreate} +# +# Allows controlling the scheme applied when recreating an object or a +# class. By default, it is set to {{{off}}}. This means that the +# object/class is destroyed and all relations +# (e.g. subclass/superclass) to other objects/classes are revoked as +# well. If softrecreate is set to {{{on}}}, the object is re-set, but not +# destroyed, the relations are +# kept. +# +# A "soft" recreation is important for e.g. reloading a file with +# class definitions (e.g. when used in OpenACS with file watching and +# reloading). With softrecreate set, it is not necessary to recreate +# dependent subclasses etc. Consider the example of a class hierarchy +# {{{A <- B <- C}}}. Without {{{softrecreate}}} set, a reload of +# {{{B}}} means first a destroy of B, leading to {{{A <- C}}}, and +# instances of {{{B}}} are re-classed to {{@object +# ::nx::Object}}. When softrecreate is set, the class hierarchy +# remains untouched. +# +# @parameter toggle Accepts either "on" or "off" +# @return The current toggle value + + +# @command.sub-command {configure objectsystems} +# +# A mere introspection subcommand. It gives you the top level of the +# current object system, i.e., the ruling root class and root +# meta-class. For "Next": +# +# {{{ +# configure objectsystems; # returns "::nx::Object ::nx::Class" +# }}} +# +# @return The active pair of root class and root meta-class + +# @command.sub-command {configure keepinitcmd} +# +# Usually, initcmd scripts are discarded by the {{{interp}}} once +# having been evaluated (in contrast to {{{proc}}} and {{{method}}} +# bodies). If you need them preserved for later introspection and +# processing (as in the "Next" documentation system), set this option +# to {{{true}}}. Then, the initcmd scripts are retained as a +# particular object variable ({{{__initcmd}}}) of classes and +# objects. It defaults to {{{false}}}. +# +# @parameter value:boolean Either {{{true}}} or {{{false}}} +# @return The current setting + +# @command alias +# +# @parameter object:object The target object which becomes the owner of +# the aliased command (method, object or command). +# +# @parameter -per-object:switch If the target object is a class, one can +# specify the binding scope (i.e., per-object or per-class) of the +# aliased command +# +# @parameter methodName The name of the alias. +# @parameter -nonleaf:switch ... +# @parameter -objscope:switch ... +# @parameter cmdName The alias source as a command handle (as returned by ...) + +# @command finalize + +# @command interp +# +# @parameter name +# @parameter args + +# @command is +# +# @parameter value +# @parameter constraint +# @parameter -hasmixin +# @parameter -type +# @parameter arg + +# @command my +# +# @parameter -local +# @parameter method +# @parameter args + +# @command relation +# +# @parameter object +# @parameter relationtype +# @parameter value + +# @command provide_method +# +# @parameter require_name +# @parameter definition +# @parameter script:optional + +# @command require_method +# +# @parameter object +# @parameter name +# @parameter per_object + +# @command mixin +# +# @parameter object +# @parameter args + +# @command tmpdir +# +# @return The platform-specific path name to the system-wide temporary directory \ No newline at end of file Index: generic/predefined.tcl =================================================================== diff -u -rfee959816f9851be0afd54905e906854680fccb2 -r25f4f3c883ff0021b8564377f6658afb69c346c8 --- generic/predefined.tcl (.../predefined.tcl) (revision fee959816f9851be0afd54905e906854680fccb2) +++ generic/predefined.tcl (.../predefined.tcl) (revision 25f4f3c883ff0021b8564377f6658afb69c346c8) @@ -4,305 +4,21 @@ # # Symbols reused in the next scripting language - # @command assertion - # - # @param object:object - # @param assertionsubcmd:required - # @param arg - - # @command existsvar - # - # @param object:object - # @param var - - # @command methodproperty - # - # @param object:object - # @param -per-object:switch - # @param methodName - # @param methodproperty Accepts one of: {{{protected}}}, - # {{{redefine-protected}}}, {{{returns}}}, {{{slotobj}}} - # @param value - # @command setter - # - # @param object:object - # @param -per-object:switch - # @param parameter - - # @command createobjectsystem - # - # @param rootClass - # @param rootMetaClass - # @param systemMethods:optional - - # @command dispatch - # - # @param object:object - # @param -objscope - # @param command - # @param args - - # @command deprecated - # - # @param what - # @param oldCmd - # @param newCmd:optional - - # @command objectproperty - # - # @param object:object - # @param objectkind Accepts one of: {{{type}}}, {{{object}}}, - # {{{class}}}, {{{baseclass}}}, {{{metaclass}}}, {{{hasmixin}}} - # @param value:optional - - # @command importvar - # - # @param object:object - # @param args - - # @command parametercheck - # - # @param -nocomplain - # @param param - # @param value:optional - - # @command forward - # - # @param object:object - # @param -per-object:switch - # @param method - # @param -default - # @param -earlybinding:switch - # @param -methodprefix - # @param -objscope:switch - # @param -onerror - # @param -verbose:switch - # @param target - # @param args - - # @command setvar - # - # @param object:object - # @param variable - # @param value - - # @command method - # - # @param object:object - # @param -inner-namespace - # @param -per-object - # @param -public - # @param name - # @param args - # @param body - # @param -percondition - # @param -postcondition - - # @command next - # - # Invokes the shadowed (i.e, same-named) method which is next along - # the precedence path and returns the results of this invocation. If - # {{{next}}} is called without arguments, the arguments of the current - # method (i.e., the arguments as present at the current callframe) are - # passed through to the shadowed method. If next is invoked with the - # flag --noArgs, the shadowed method is called without the active - # callframe arguments. If other arguments are specified for {{{next}}} - # explicitly, these will be passed instead. - # - # @param --noArgs:optional Deactivates the forward-passing of the current callframe's arguments - # @param args Explicitly declared arguments to pass to shadowed methods - - - # @command current - # - # An introspective command which allows you to explore the "Next" - # callstack from within the scope of a method (or procif bound to an - # object via {{{alias}}}). {{{current}}} computes callstack related - # information. If executed without specifying a subcommand, - # i.e. {{{[current]}}}, returns the name of the object, which is - # currently in execution. If called from outside a proc, it returns - # the error message "No current object". - # - # It comes with a variety of subcommands to query different bits of - # callstack information. See below. - # - # @sub-command class Returns the name of the class holding the - # currently executing per-class method, if and only if called from - # within a per-class method. Note, that this method-owning class may - # be different to the class of the current object. If called from - # within a per-object method, it returns an empty string. - # - # @sub-command proc Returns the name of the currently executing method. - # - # @sub-command callingclass Returns the name of the class which is - # calling into the executing method. - # - # @sub-command callingobject Returns the name of the object which is - # calling into the executing method. - # - # @sub-command calledclass Returns the name of the class that holds - # the originally (and now shadowed) target method (applicable in - # mixin classes and filters). - # - # @sub-command calledproc Returns the name of the target method - # (applicable in a filter only). - # - # @sub-command isnextcall Returns 1 if the executing method was - # invoked via {{@command ::nx::next}}, 0 otherwise. - # - # @sub-command next Returns the name of the method next on the - # precedence path as a string. - # - # @sub-command filterreg In a method serving as active filter, - # returns the name of the object (class) on which the method is - # registered as a filter. - # - # @sub-command callinglevel Returns the "original" callstack level - # calling into the executing method. Intermediary {{{next}}} calls - # are ignored in this computation. The level is returned in a form - # so that it can be used as first argument in {{@method ::nx::Object - # class uplevel}} or {{@method ::nx::Object class upvar}}. - # - # @sub-command activelevel Returns the actual callstack level calling - # into the executing method. The active might correspond the - # {{{callinglevel}}}, but this is not necessarily the case. The - # {{{activelevel}}} counts {{@command ::nx::next}} call. The level - # is returned in a form so that it can be used as first argument in - # {{@method ::nx::Object class uplevel}} or {{@method ::nx::Object - # class upvar}}. - namespace export next current + # Symbols reused in XOTcl - # @command configure - # - # A top-level configuration facility which allows you modify - # properties of the "Next" object system for the scope of an entire - # {{{interp}}}. - - # @command.sub-command {configure filter} - # - # Allows turning on or off filters globally for the current - # interpreter. By default, the filter state is turned off. This - # function returns the old filter state. This filterless {{{interp}}} - # state is needed for the serializer which should introspect and stream the - # objects and classes without being affected by active filter. - # - # @param toggle Accepts either "on" or "off" - # @return The current filter activation state - - # @command.sub-command {configure softrecreate} - # - # Allows controlling the scheme applied when recreating an object or a - # class. By default, it is set to {{{off}}}. This means that the - # object/class is destroyed and all relations - # (e.g. subclass/superclass) to other objects/classes are revoked as - # well. If softrecreate is set to {{{on}}}, the object is re-set, but not - # destroyed, the relations are - # kept. - # - # A "soft" recreation is important for e.g. reloading a file with - # class definitions (e.g. when used in OpenACS with file watching and - # reloading). With softrecreate set, it is not necessary to recreate - # dependent subclasses etc. Consider the example of a class hierarchy - # {{{A <- B <- C}}}. Without {{{softrecreate}}} set, a reload of - # {{{B}}} means first a destroy of B, leading to {{{A <- C}}}, and - # instances of {{{B}}} are re-classed to {{@object - # ::nx::Object}}. When softrecreate is set, the class hierarchy - # remains untouched. - # - # @param toggle Accepts either "on" or "off" - # @return The current toggle value - - - # @command.sub-command {configure objectsystems} - # - # A mere introspection subcommand. It gives you the top level of the - # current object system, i.e., the ruling root class and root - # meta-class. For "Next": - # - # {{{ - # configure objectsystems; # returns "::nx::Object ::nx::Class" - # }}} - # - # @return The active pair of root class and root meta-class - - # @command.sub-command {configure keepinitcmd} - # - # Usually, initcmd scripts are discarded by the {{{interp}}} once - # having been evaluated (in contrast to {{{proc}}} and {{{method}}} - # bodies). If you need them preserved for later introspection and - # processing (as in the "Next" documentation system), set this option - # to {{{true}}}. Then, the initcmd scripts are retained as a - # particular object variable ({{{__initcmd}}}) of classes and - # objects. It defaults to {{{false}}}. - # - # @param value:boolean Either {{{true}}} or {{{false}}} - # @return The current setting - - # @command alias - # - # @param object:object The target object which becomes the owner of - # the aliased command (method, object or command). - # - # @param -per-object:switch If the target object is a class, one can - # specify the binding scope (i.e., per-object or per-class) of the - # aliased command - # - # @param methodName The name of the alias. - # @param -nonleaf:switch ... - # @param -objscope:switch ... - # @param cmdName The alias source as a command handle (as returned by ...) - - # @command finalize - - # @command interp - # - # @param name - # @param args - - # @command is - # - # @param value - # @param constraint - # @param -hasmixin - # @param -type - # @param arg - - # @command my - # - # @param -local - # @param method - # @param args - - # @command relation - # - # @param object - # @param relationtype - # @param value - namespace export alias configure finalize interp is my relation # # support for method provide and method require # - # @command provide_method - # - # @param require_name - # @param definition - # @param script:optional - proc ::nsf::provide_method {require_name definition {script ""}} { set ::nsf::methodIndex($require_name) [list definition $definition script $script] } - # @command require_method - # - # @param object - # @param name - # @param per_object proc ::nsf::require_method {object name {per_object 0}} { set key ::nsf::methodIndex($name) if {[info exists $key]} { @@ -322,15 +38,11 @@ } # - # nsf::mixin + # ::nsf::mixin # # provide a similar interface as for ::nsf::method, ::nsf::alias, ... # - # @command mixin - # - # @param object - # @param args proc ::nsf::mixin {object args} { if {[lindex $args 0] eq "-per-object"} { set rel "object-mixin" @@ -377,10 +89,6 @@ # determine platform aware temp directory # - # @command tmpdir - # - # @return The platform-specific path name to the system-wide temporary directory - proc tmpdir {} { foreach e [list TMPDIR TEMP TMP] { if {[info exists ::env($e)] \ Index: library/lib/doc-assets/class.html.tmpl =================================================================== diff -u -rfee959816f9851be0afd54905e906854680fccb2 -r25f4f3c883ff0021b8564377f6658afb69c346c8 --- library/lib/doc-assets/class.html.tmpl (.../class.html.tmpl) (revision fee959816f9851be0afd54905e906854680fccb2) +++ library/lib/doc-assets/class.html.tmpl (.../class.html.tmpl) (revision 25f4f3c883ff0021b8564377f6658afb69c346c8) @@ -29,9 +29,9 @@
[$param name]
[:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}]
Index: library/lib/doc-assets/method.html.tmpl
===================================================================
diff -u -rfee959816f9851be0afd54905e906854680fccb2 -r25f4f3c883ff0021b8564377f6658afb69c346c8
--- library/lib/doc-assets/method.html.tmpl (.../method.html.tmpl) (revision fee959816f9851be0afd54905e906854680fccb2)
+++ library/lib/doc-assets/method.html.tmpl (.../method.html.tmpl) (revision 25f4f3c883ff0021b8564377f6658afb69c346c8)
@@ -24,10 +24,10 @@
[$sm render -initscript [list set supermethod [current]] submethod.html.tmpl]
}]
} - {
- [:? {[info exists :@param]} {
+ [:? {[info exists :@parameter]} {
- Method parameters:
- [:for param ${:@param} {
+ [:for param ${:@parameter} {
-
[$param name]
[:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}]
Index: library/lib/doc-assets/submethod.html.tmpl
===================================================================
diff -u -rfee959816f9851be0afd54905e906854680fccb2 -r25f4f3c883ff0021b8564377f6658afb69c346c8
--- library/lib/doc-assets/submethod.html.tmpl (.../submethod.html.tmpl) (revision fee959816f9851be0afd54905e906854680fccb2)
+++ library/lib/doc-assets/submethod.html.tmpl (.../submethod.html.tmpl) (revision 25f4f3c883ff0021b8564377f6658afb69c346c8)
@@ -10,10 +10,10 @@
[:as_text]
- [:? {[info exists :@param]} {
+ [:? {[info exists :@parameter]} {
- Submethod parameters:
- [:for param ${:@param} {
+ [:for param ${:@parameter} {
-
[$param name]
[:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}]
Index: library/lib/doc-tools.tcl
===================================================================
diff -u -rfee959816f9851be0afd54905e906854680fccb2 -r25f4f3c883ff0021b8564377f6658afb69c346c8
--- library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision fee959816f9851be0afd54905e906854680fccb2)
+++ library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision 25f4f3c883ff0021b8564377f6658afb69c346c8)
@@ -549,7 +549,7 @@
}
QualifierTag create @command -superclass StructuredEntity {
- :attribute @param -slotclass ::nx::doc::PartAttribute {
+ :attribute @parameter -slotclass ::nx::doc::PartAttribute {
set :part_class @param
}
:attribute @return -slotclass ::nx::doc::PartAttribute {
@@ -567,8 +567,8 @@
}
:method parameters {} {
set params [list]
- if {[info exists :@param]} {
- foreach p [:@param] {
+ 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]?"
@@ -617,8 +617,9 @@
set :part_class @method
}
- :forward @param %self @object-param
- :attribute @object-param -slotclass ::nx::doc::PartAttribute {
+ :forward @attribute %self @object-attribute
+ #:forward @param %self @object-param
+ :attribute @object-attribute -slotclass ::nx::doc::PartAttribute {
set :part_class @param
}
@@ -640,8 +641,8 @@
-superclass @object {
:attribute @superclass -slotclass ::nx::doc::PartAttribute
- :forward @param %self @class-param
- :attribute @class-param -slotclass ::nx::doc::PartAttribute {
+ :forward @attribute %self @class-attribute
+ :attribute @class-attribute -slotclass ::nx::doc::PartAttribute {
set :part_class @param
}
@@ -693,7 +694,7 @@
PartTag create @method \
-superclass StructuredEntity {
:attribute {@modifier public} -slotclass ::nx::doc::PartAttribute
- :attribute @param -slotclass ::nx::doc::PartAttribute {
+ :attribute @parameter -slotclass ::nx::doc::PartAttribute {
set :part_class @param
}
:attribute @return -slotclass ::nx::doc::PartAttribute {
@@ -753,8 +754,8 @@
:method parameters {} {
set params [list]
- if {[info exists :@param]} {
- foreach p [:@param] {
+ 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]?"
@@ -912,8 +913,15 @@
}
}
+ #
+ # Provide two interp-wide aliases for @param. This is mere syntactic
+ # sugar!
+ #
+ interp alias {} ::nx::doc::@attribute {} ::nx::doc::@param
+ interp alias {} ::nx::doc::@parameter {} ::nx::doc::@param
+
namespace export CommentBlockParser @command @object @class @package @project @method \
- @param @
+ @attribute @parameter @
}
@@ -1339,19 +1347,34 @@
return $i
} elseif {[file isfile $thing]} {
# 3) alien script file
+ set script ""
if {[file readable $thing]} {
+ # a) process the target file
set fh [open $thing r]
- if {[catch {set script [read $fh]} msg]} {
+ if {[catch {append script [read $fh]} msg]} {
catch {close $fh}
:log "error reading the file '$thing', i.e.: '$msg'"
}
- close $fh
- doc analyze -noeval $noeval $script {*}$args
- puts stderr SCRIPT=$thing--[file readable $thing]-ANALYZED-[string length $script]bytes
- #doc process -noeval $noeval $script {*}$args
- } else {
- :log "file '$thing' not readable"
+ catch {close $fh}
}
+ # b) verify the existence of an *.nxd companion file
+ set rootname [file rootname $thing]
+ set companion $rootname.nxd
+ if {[file isfile $companion] && [file readable $companion]} {
+ set fh [open $companion r]
+ if {[catch {append script "\n\n" [read $fh]} msg]} {
+ catch {close $fh}
+ :log "error reading the file '$thing', i.e.: '$msg'"
+ }
+ catch {close $fh}
+ }
+
+ if {$script eq ""} {
+ :log "script empty, probaly file '$thing' is not readable"
+ }
+
+ doc analyze -noeval $noeval $script {*}$args
+ puts stderr FILE=$thing--[file readable $thing]-COMPANION=$companion--[file readable $companion]-ANALYZED-[string length $script]bytes
} else {
# 4) we assume a string block, e.g., to be fed into eval
set i [interp create]
@@ -1365,7 +1388,7 @@
return $i
}
}
-
+
:method analyze {{-noeval false} script {additions ""}} {
# NOTE: This method is to be executed in a child/ slave
# interpreter.
@@ -1532,7 +1555,7 @@
foreach {line_offset block} $blocks {
if {$line_offset > 1} break;
set scope [expr {[$slot per-object]?"object":"class"}]
- set id [$entity @${scope}-param [$slot name]]
+ set id [$entity @${scope}-attribute [$slot name]]
CommentBlockParser process \
-parsing_level 2 \
-partof_entity $entity \
Index: library/nx/nx.nxd
===================================================================
diff -u
--- library/nx/nx.nxd (revision 0)
+++ library/nx/nx.nxd (revision 25f4f3c883ff0021b8564377f6658afb69c346c8)
@@ -0,0 +1,690 @@
+# @package ::nx
+#
+# The Next Scripting Language is a compact and expressive object-oriented language
+# extension for Tcl. The object system model is highly influenced by
+# CLOS. This package provides the basic object system for the Next
+# language. It defines the basic language entities {{@class ::nx::Object}} and
+# {{@class ::nx::Class}}, as well as essential language primitives
+# (e.g., {{@command ::nx::next}} and {{@command ::nx::self}}).
+#
+# @require Tcl
+# @version 1.0.0a
+# @namespace ::nx
+
+# @class Object
+#
+# Next Scripting Language (NSL) programs are constructed out of
+# objects. This class describes common structural and behavioural
+# features for all NSL objects. It is the root object-class in the
+# NSL object system.
+
+# @class Class
+#
+# A class defines a family of object types which own a common set of
+# attributes (see {{@class ::nx::Attribute}}) and methods. Classes
+# are organised according to their similarities and differences in
+# classification hierarchies. This object represents the root
+# meta-class in the "Next" object system.
+#
+# @superclass ::nx::doc::entities::class::nx::Object
+
+# @class.method {Class alloc}
+#
+# Creates a bare object or class which is not
+# fully initialized. {{{alloc}}} is used by {{@method ::nx::Class class create}} to
+# request a memory object storage. In subsequent steps,
+# {{{create}}} invokes {{{configure}}} and {{{init}}} to further
+# set up the object. Only in rare situations, you may consider
+# bypassing the overall {{{create}}} mechanism by just allocating
+# uninitialized objects using {{{alloc}}}.
+#
+# @properties interally-called
+# @parameter name The object identifier assigned to the object storage to be allocated.
+# @return The name of the allocated, uninitialized object
+
+# @class.method {Class create}
+#
+# Provides for creating application-level classes and objects. If
+# the method receiver is a meta-class, a class will be
+# created. Otherwise, {{{create}}} yields an object. {{{create}}}
+# is responsible a multi-phase object creation scheme. This
+# creation scheme involves three major steps:
+# {{{
+# [Object create anObject] (1)
+# ---------------. .--------------.
+# -------------->|Class->create()|-->|Class->alloc()|
+# `---------------' `--------------'
+# | | (2) .-------------------.
+# | .----->|Object->configure()|
+# | `-------------------'
+# | (3) .------.
+# .........>|init()|
+# `------'
+# }}}
+# (1) A call to {{@method ::nx::Class class alloc}} to create a raw,
+# uninitalized object.
+#
+# (2) The newly allocated object receives a method call upon
+# {{@method ::nx::Object class configure}}. This will establish the
+# object's initial state, by applying object parameter values
+# provided at object creation time and default values defined at
+# object definition time.
+#
+# (3) Finally, {{{create}}} emits a call to the initialization
+# method {{{init}}} (i.e., the actual "constructor"), if
+# available. An {{{init}}} method can be defined by a class on
+# behalf of its objects, to lay out class-specific initialisation
+# behaviour. Alternatively, each single object may define an
+# {{{init}}} method on its own.
+#
+# By overloading the method in a meta-class, you can refine or
+# replace this default object creation scheme (e.g., for applying
+# application-specific naming schemes).
+#
+# For creating an object or a class, you must name {{{create}}}
+# explicitly, i.e.:
+# {{{
+# ::nx::Object create anObject
+# ::nx::Class create AClass
+# ::nx::Class AnotherClass; # This fails: "Method 'AnotherClass' unknown for ::nx::Class."
+# }}}
+#
+# @parameter name The designated identifier on the class or the object to be created.
+# @parameter args arguments to be passed down to the object creation
+# procedure used to initialize the object.
+# @return The name of the created, fully initialized object.
+
+# @class.method {Class dealloc}
+#
+# Marks objects for physical deletion in memory. Beware the fact
+# that calling {{{dealloc}}} does not necessarily cause the object
+# to be deleted immediately. Depending on the lifecycle of the the
+# object's environment (e.g., the {{{interp}}}, the containing
+# namespace) and on call references down the callstack, the actual
+# memory freeing operation may occur time-shifted (that is,
+# later). While {{{dealloc}}} itself cannot be redefined for
+# {{{::nx::Class}}}, you may consider refining it in a subclass or
+# mixin class for customizing the destruction process.
+#
+# @properties interally-called
+# @parameter object The name of the object to be scheduled for deletion.
+
+# @class.method {Class recreate}
+#
+# This method is called upon recreating an object. Recreation is the
+# scheme for resolving object naming conflicts in the dynamic and
+# scripted programming environment of "Next": An object or class is
+# created while an object or class with an identical object identifier
+# already exists. The method {{{recreate}}} performs standard object
+# initialization, per default, after re-setting the state and
+# relationships of the object under recreation. This re-set is
+# achieved by invoking {{@method ::nx::Object class cleanup}}.
+# {{{
+# Object create Bar
+# \# ...
+# Object create Bar; # calls Object->recreate(::Bar, ...) + ::Bar->cleanup()
+# }}}
+# By refining {{{recreate}}} in an application-level subclass or mixin
+# class, you can intercept the recreation process. In the pre-part the
+# refined {{{recreate}}} method, the recreated object has its old
+# state, after calling {{@command ::nx::next}} it is cleaned up.
+#
+# If the name conflict occurs between an existing class and a newly
+# created object (or vice versa), {{{recreate}}} is not
+# performed. Rather, a sequence of {{@method ::nx::Object class
+# destroy}} and {{@method ::nx::Class class create}} is triggered:
+# {{{
+# Object create Bar
+# \# ...
+# Class create Bar; # calls Bar->destroy() + Class->create(::Bar, ...)
+# }}}
+#
+# @properties interally-called
+# @parameter name The name (identifier) of the object under recreation
+# @parameter args Arbitrary vector of arguments
+# @return The name of the recreated object
+
+# @class.method {Object residualargs}
+#
+# @properties interally-called
+# @parameter args
+
+# @command next
+#
+# @use ::nsf::command
+
+# @command current
+#
+# @use ::nsf::current
+
+# @class.method {Object configure}
+#
+# This method participates in the object creation process. It is
+# automatically invoked after having produced a new object by
+# {{@method ::nx::Class class create}}. Upon its invocation, the
+# variable argument vector {{{args}}} contains a list of parameters
+# and parameter values passed in from the call site of object
+# creation. They are matched against an object parameter
+# definition. This definition, and so the actual method parameter
+# definition of this method, is assembled from configuration values of
+# the classes along the precedence order (see also {{@method
+# ::nx::Object class objectparameter}}). The method {{{configure}}}
+# can be called at arbitrary times to "re-set" an object.
+#
+# @properties interally-called
+# @parameter args The variable argument vector stores the object parameters and their values
+
+# @class.method {Object destroy}
+#
+# The standard destructor for an object. The method {{@method
+# ::nx::Object class destroy}} triggers the physical destruction of
+# the object. The method {{{destroy}}} can be refined by subclasses or
+# mixin classes to add additional (class specific) destruction
+# behavior. Note that in most cases, the class specific {{{destroy}}}
+# methods should call {{@command ::nx::next}} to trigger physical
+# destruction.
+# {{{
+# nx::Class create Foo {
+# :method destroy {} {
+# puts "destroying [self]"
+# next
+# }
+# }
+# Foo create f1
+# f1 destroy
+# }}}
+# Technical details: The method {{@method ::nx::Object class destroy}}
+# delegates the actual destruction to {{@method ::nx::Class class
+# dealloc}} which clears the memory object storage. Essentially, the
+# behaviour could be scripted as:
+# {{{
+# Object method destroy {} {
+# [:info class] dealloc [self]
+# }
+# }}}
+# Note, however, that {{{destroy}}} is protected against
+# application-level redefinition. You must refine it in a subclass
+# or mixin class.
+#
+
+# @class.method {Object uplevel}
+#
+# This helper allows you to evaluate a script in the context of
+# another callstack level (i.e., callstack frame).
+#
+# @parameter level:optional The starting callstack level (defaults to the
+# value of {{{[current callinglevel]}}})
+# @parameter script:list The script to be evaluated in the targeted
+# callstack level
+
+# @class.method {Object upvar}
+#
+# This helper allows you to bind a local variable to a variable
+# residing at a different callstack level (frame).
+#
+# @parameter level:optional The starting callstack level (defaults to the
+# value of {{{[current callinglevel]}}})
+#
+# @parameter sourceVar A variable which should be linked to a ...
+# @parameter targetVar ... which is a local variable in a method scope
+# @see ...
+
+# @class.method {Object volatile}
+#
+# By calling on this method, the object is bound in its lifetime to
+# the one of call site (e.g., the given Tcl proc or method scope):
+# {{{
+# proc foo {} {
+# info vars; # shows ""
+# set x [Object create Bar -volatile]
+# info vars; # shows "x Bar"
+# }
+# }}}
+# Behind the scenes, {{{volatile}}} registers a C-level variable trace
+# ({{{Tcl_TraceVar()}}}) on the hiddenly created local variable (e.g.,
+# {{{Bar}}}), firing upon unset events and deleting the referenced
+# object ({{{Bar}}}). That is, once the callframe context of {{{foo}}}
+# is left, the local variable {{{Bar}}} is unset and so the bound
+# object is destroyed.
+
+# @class.method {Class new}
+#
+# A convenience method to create auto-named objects and classes. It is
+# a front-end to {{@method ::nx::Class class create}}. For instance:
+# {{{
+# set obj [Object new]
+# set cls [Class new]
+# }}}
+#
+# This will provide object identifiers of the form
+# e.g. {{{::nsf::__#0}}}. In contrast to {{@method ::nx::Object class autoname}},
+# the uniqueness of auto-generated identifiers is guaranteed for the
+# scope of the {{{interp}}}.
+#
+# @parameter -childof If provided, the new object is created as a child of
+# the specified object.
+# @parameter args The variable arguments passed down to {{@method
+# ::nx::Class class create}}.
+
+# @class.method {Class method}
+#
+# Defines a per-class method, similarly to Tcl specifying
+# {{{procs}}}. Optionally assertions may be specified by two
+# additional arguments. Therefore, to specify only post-assertions
+# an empty pre-assertion list must be given. All assertions are a
+# list of ordinary Tcl {{{expr}}} statements. When {{{method}}} is
+# called with an empty argument list and an empty body, the
+# specified method is deleted.
+# {{{
+# Class create AClass {
+# :method foo args {;}
+# }
+#
+# AClass create anInstance
+# anInstance foo; # invokes "foo"
+# }}}
+#
+# @parameter name The method name
+# @parameter arguments:list A list specifying non-positional and positional parameters
+# @parameter body The script which forms the method body
+# @parameter preAssertion Optional assertions that must hold before the proc executes
+# @parameter postAssertion Optional assertions that must hold after the proc executes
+
+# @class.method {Object method}
+#
+# Defines a per-object method, similarly to Tcl specifying
+# {{{procs}}}. Optionally assertions may be specified by two
+# additional arguments. Therefore, to specify only post-assertions
+# an empty pre-assertion list must be given. All assertions are a
+# list of ordinary Tcl {{{expr}}} statements. When {{{method}}} is
+# called with an empty argument list and an empty body, the
+# specified method is deleted.
+# {{{
+# Object create anObject {
+# :method foo args {;}
+# }
+# anObject foo; # invokes "foo"
+# }}}
+#
+# @parameter name The method name
+# @parameter arguments:list A list specifying non-positional and positional parameters
+# @parameter body The script which forms the method body
+# @parameter preAssertion Optional assertions that must hold before the proc executes
+# @parameter postAssertion Optional assertions that must hold after the proc executes
+
+# @class.method {Object forward}
+#
+# Register a per-object method (similar to a {{{proc}}}) for
+# forward-delegating calls to a callee (target Tcl command, other
+# object). When the forwarder method is called, the actual arguments
+# of the invocation are appended to the specified arguments. In
+# callee an arguments certain substitutions can take place:
+#
+# {{{%proc}}} substituted by name of the forwarder method
+#
+# {{{%self}}} substitute by name of the object
+#
+# {{{%1}}} substitute by first argument of the invocation
+#
+# {{{ {%@POS value} }}} substitute the specified value in the
+# argument list on position POS, where POS can be a positive or
+# negative integer or end. Positive integers specify the position
+# from the begin of the list, while negative integer specify the
+# position from the end.
+#
+# {{{ {%argclindex LIST} }}} take the nth argument of the specified
+# list as substitution value, where n is the number of arguments
+# from the invocation.
+#
+# {{{%%}}} a single percent.
+#
+# {{{%Tcl-command}}} command to be executed; substituted by result.
+#
+# Additionally each argument can be prefixed by the positional prefix
+# %@POS (note the delimiting space at the end) that can be used to
+# specify an explicit position. POS can be a positive or negative
+# integer or the word end. The positional arguments are evaluated from
+# left to right and should be used in ascending order.
+#
+# @parameter name The name of the delegating or forward method
+# @parameter -objscope:optional Causes the target to be evaluated in the scope of the object.
+# @parameter -methodprefix Prepends the specified prefix to the second argument of the invocation.
+# @parameter -default Is used for default method names (only in connection
+# with %1)
+#
+# @parameter -earlybinding Look up the function pointer of the called Tcl
+# command at definition time of the forwarder instead of invocation
+# time. This option should only be used for calling C-implemented Tcl
+# commands, no scripted procs
+#
+# @parameter -verbose Print the substituted command to stderr before
+# executing
+
+# @parameter callee
+# @parameter args
+
+# @class.method {Class forward}
+#
+# Register a per-class method (similar to a {{{proc}}}) for
+# forward-delegating calls to a callee (target Tcl command, other
+# object). When the forwarder method is called on an instance of the
+# class, the actual arguments of the invocation are appended to the
+# specified arguments. In callee an arguments certain substitutions
+# can take place:
+#
+# {{{%proc}}} substituted by name of the forwarder method
+#
+# {{{%self}}} substitute by name of the object
+#
+# {{{%1}}} substitute by first argument of the invocation
+#
+# {{{ {%@POS value} }}} substitute the specified value in the
+# argument list on position POS, where POS can be a positive or
+# negative integer or end. Positive integers specify the position
+# from the begin of the list, while negative integer specify the
+# position from the end.
+#
+# {{{ {%argclindex LIST} }}} take the nth argument of the specified
+# list as substitution value, where n is the number of arguments
+# from the invocation.
+#
+# {{{%%}}} a single percent.
+#
+# {{{%Tcl-command}}} command to be executed; substituted by result.
+#
+# Additionally each argument can be prefixed by the positional prefix
+# %@POS (note the delimiting space at the end) that can be used to
+# specify an explicit position. POS can be a positive or negative
+# integer or the word end. The positional arguments are evaluated from
+# left to right and should be used in ascending order.
+#
+# @parameter name The name of the delegating or forward method
+# @parameter -objscope:optional Causes the target to be evaluated in the
+# scope of the object.
+# @parameter -methodprefix Prepends the specified prefix to the second
+# argument of the invocation.
+# @parameter -default Is used for default method names (only in
+# connection with %1)
+# @parameter -earlybinding Look up the function pointer of the called
+# Tcl command at definition time of the forwarder instead of
+# invocation time. This option should only be used for calling
+# C-implemented Tcl commands, no scripted procs
+# @parameter -verbose Print the substituted command to stderr before
+# executing
+# @parameter callee
+# @parameter args
+
+# @class.method {Object info}
+#
+# Provides introspection on objects. A variety of introspection
+# options exists. {{{info}}} is implemented as en ensemble
+# object. Hence, the introspection options turn into proper
+# sub-methods.
+#
+# @sub-method callable
+# @sub-method has
+# @sub-method filter
+# @sub-method is Binds all introspection facilities offered by
+# {{{::nsf::is}}} to the object, i.e., the object is automatically
+# folded in as the first argument passed to {{{::nsf::is}}}
+# @sub-method mixin
+
+# @class.method {Object "info callable method"}
+#
+# Verifies whether there is a method under a given name available
+# for invocation upon the object. In case, the introspective call
+# returns the corresponding method handle. If there is no so named
+# method available, an empty string is returned.
+
+# @class.method {Object "info callable filter"}
+#
+# Search for a method which is currently registered as a filter (in
+# the invocation scope of the given object). If found, the
+# corresponding method handle is returned.
+
+# @class.method {Object "info children"}
+#
+# Computes the list of aggregated (or nested) objects. The resulting
+# list reports the fully qualified object names. If a name pattern
+# was specified, all matching child objects are returned. Otherwise,
+# all children are reported.
+
+
+# @class.method {Object "info class"}
+#
+# Gives the name of the class of the current object.
+
+# @class.method {Object "info filter guard"}
+#
+# Returns the guards for filter identified by a filter name
+
+# @class.method {Object "info filter methods"}
+#
+# Returns a list of methods registered as filters.
+
+# @class.method {Object "info forward"}
+#
+# Provides you with the list of forwarders defined for the given
+# object.
+
+# @class.method {Object "info has mixin"}
+#
+# Verifies in a boolean test whether the object has the given class
+# registered as a mixin class.
+
+# @class.method {Object "info has namespace"} Some words on info has type
+#
+# Tells you whether the object has a companion, per-object Tcl
+# namespace. Note that the results do not necessarily correspond to
+# those yielded by {{{[namespace exists /obj/]}}}.
+
+# @class.method {Object "info has type"}
+#
+# 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.
+
+# @class.method {Object "info methods"}
+#
+# Allows you to query the methods (of various kinds) defined on the
+# object.
+
+# @class.method {Object "info mixin guard"}
+#
+# Retrieves the guards applied to the mixin class idenitified by the
+# mixin class name
+
+# @class.method {Object "info mixin classes"}
+#
+# The list of per-object mixin classes currently registered for the
+# object is returned.
+
+# @class.method {Object "info parent"}
+#
+# Resolves the fully qualified name of the parent object (or "::" if
+# there is no parent object).
+
+# @class.method {Object "info precedence"}
+#
+# Presents to you the list of classes the object is inheriting
+# attributes and methods, ordered according to their precedence.
+
+# @class.method {Object "info slotobjects"}
+#
+# Assembles the list of slot objects which apply the given
+# object. They are resolved by following the class precedence list
+# upward and coercing the lists of slots provided by these classes.
+
+# @class.method {Object "info vars"}
+#
+# Yields a list of variable names created and defined on the object.
+
+# @class Slot
+#
+# A slot is a meta-object that manages property changes of
+# objects. A property is either an attribute or a role taken by an
+# object in an inter-object relation (e.g., in system slots). The
+# predefined system slots are {{{class}}}, {{{superclass}}},
+# {{{mixin}}}, and {{{filter}}}. These slots appear as methods of
+# {{@class ::nx::Object}} or {{@class ::nx::Class}}. The slots
+# provide a common getter and setter interface. Every multivalued
+# slot provides e.g. a method {{{add}}} to append a value to the
+# list of values, and a method {{{delete}}} which removes it.
+#
+# @superclass ::nx::doc::entities::class::nx::Object
+
+# @class ObjectParameterSlot
+#
+# @superclass ::nx::doc::entities::class::nx::Slot
+
+# @class.attribute {Slot name}
+#
+# Name of the slot which can be used to access the slot from an object
+
+# @class.attribute {Slot multivalued}
+#
+# Boolean value for specifying single or multiple values (lists)
+
+# @class.attribute {Slot required}
+#
+# Denotes whether a value must be provided
+
+# @class.attribute {Slot default}
+#
+# Allows you to define a default value (to be set upon object creation)
+
+# @class.attribute {Slot type}
+#
+# You may specify a type constraint on the value range to managed by the slot
+
+# @class.attribute {ObjectParameterSlot name}
+#
+# Name of the slot which can be used to access the slot from an
+# object. It defaults to unqualified name of an instance.
+
+# @class.attribute {ObjectParameterSlot methodname}
+#
+# The name of the accessor methods to be registed on behalf of the
+# slot object with its domains can vary from the slot name.
+
+# @class.attribute {ObjectParameterSlot domain}
+#
+# The domain (object or class) of a slot on which it can be used
+
+# @class.attribute {ObjectParameterSlot defaultmethods}
+#
+# A list of two elements for specifying which methods are called per
+# default, when no slot method is explicitly specified in a call.
+
+# @class.attribute {ObjectParameterSlot manager}
+#
+# The manager object of the slot (per default, the slot object takes
+# this role, i.e. {{{[self]}}})
+
+# @class.attribute {ObjectParameterSlot per-object}
+#
+# If set to {{{true}}}, the accessor methods are registered with the
+# domain object scope only. It defaults to {{{false}}}.
+
+# @class.method Object objectparameter
+
+# @class.attribute {Class superclass}
+#
+# Specifies superclasses for a given class. As a setter ***
+# generell: setter kann hier mit der methode namens "setter"
+# verwechselt werden; wir sollten hier die paramter syntax
+# anfuehren, die allerdings in zwei varianten kommt:
+#{{{
+# obj superclass ?value?
+# obj superclass add|assign|delete|get value
+#}}}
+# Das gilt allgemein, nicht nur für die relation-slots, sondern
+# für alle incremental slots.
+# **** {{{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}
+#
+# Sets or retrieves the class of an object. When {{{class}}} is
+# called without arguments, it returns the current class of the
+# object.
+#
+# @return If called as a getter (without arguments), {{{class}}}
+# returns the current class of the object
+
+# @class.attribute {Object mixin}
+#
+# As a setter, {{{mixin}}} specifies a list of mixins to
+# set. Every mixin must be an existing class. In getter mode, you
+# can retrieve the list of mixins active for the given object.
+#
+# @return :list If called as a getter (without arguments),
+# {{{mixin}}} returns the list of current mixin classes registered
+# with the object
+
+# @class.attribute {Object filter}
+#
+# In its setter mode, {{{filter}}} allows you to register methods
+# as per-object filters. Every filter must be an existing method
+# in the scope of the object. When acting as a getter, you can
+# retrieve the list of filter methods active for the given object.
+#
+# @return :list If called as a getter (without arguments),
+# {{{filter}}} returns the list of current filters
+# registered with the object
+
+# @class.attribute {Class mixin}
+#
+# As a setter, {{{mixin}}} specifies a list of mixins to set for
+# the class. Every mixin must be an existing class. In getter
+# mode, you can retrieve the list of mixins active for the given
+# class.
+#
+# @return :list If called as a getter (without arguments), {{{mixin}}}
+# returns the list of current mixin classes registered with the class
+
+# @class.attribute {Class filter}
+#
+# In its setter mode, {{{filter}}} allows you to register methods
+# as per-class filters. Every filter must be an existing method
+# in the scope of the class. When acting as a getter, you can
+# retrieve the list of filter methods active for the given class.
+#
+# @return :list If called as a getter (without arguments),
+# {{{filter}}} returns the list of current filters
+# registered with the class
+
+# @class Attribute
+#
+# Attribute slots are used to manage the access, mutation, and
+# querying of instance variables. One defines Attribute slots for
+# objects and classes usually via the helper method {{@method
+# ::nx::Object class attribute}} **** TODO STEFAN, kein Link? GEPLANT?
+# MIT 2 GESCHWEIFTEN KLAMMER UM SALARY GIBT ES EINEN LAUFZEITFEHLER???
+# ******** The following example defines a class with three attribute
+# slots. The attribute {salary} has a default of {0}, the attribute
+# {projects} has the empty list as default and is defined as
+# multivalued.
+# {{{
+# Class create Person {
+# :attribute name
+# :attribute {salary:integer 0}
+# :attribute {projects:multivalued ""} {
+# set :incremental true
+# }
+# }
+# }}}
+#
+# @parameter incremental A boolean value, only useful for multivalued
+# slots. When set, one can add/delete incrementally values to the
+# multivalued set (e.g., through an incremental {{{add}}})
+# @parameter valuecmd A Tcl command to be executed whenever the managed
+# object variable is read
+# @parameter valuechangedcmd A Tcl command to be executed whenever the
+# value of the managed object variable changes
+# @parameter arg
+# @superclass ::nx::doc::entities::class::nx::ObjectParameterSlot
Index: library/nx/nx.tcl
===================================================================
diff -u -rfee959816f9851be0afd54905e906854680fccb2 -r25f4f3c883ff0021b8564377f6658afb69c346c8
--- library/nx/nx.tcl (.../nx.tcl) (revision fee959816f9851be0afd54905e906854680fccb2)
+++ library/nx/nx.tcl (.../nx.tcl) (revision 25f4f3c883ff0021b8564377f6658afb69c346c8)
@@ -1,19 +1,3 @@
-# TODO: decide how to deal with @package and @project names (don't
-# need namespace delimiters!)
-
-# @package ::nx
-#
-# The Next Scripting Language is a compact and expressive object-oriented language
-# extension for Tcl. The object system model is highly influenced by
-# CLOS. This package provides the basic object system for the Next
-# language. It defines the basic language entities {{@class ::nx::Object}} and
-# {{@class ::nx::Class}}, as well as essential language primitives
-# (e.g., {{@command ::nx::next}} and {{@command ::nx::self}}).
-#
-# @require Tcl
-# @version 1.0.0a
-# @namespace ::nx
-
package provide nx 2.0
package require nsf
@@ -28,143 +12,6 @@
# First create the ::nx object system.
#
- # @class Object
- #
- # Next Scripting Language (NSL)programs are constructed out of
- # objects. This class describes common structural and behavioural
- # features for all NSL objects. It is the root object-class in the
- # NSL object system.
-
- # @class Class
- #
- # A class defines a family of object types which own a common set of
- # attributes (see {{@class ::nx::Attribute}}) and methods. Classes
- # are organised according to their similarities and differences in
- # classification hierarchies. This object represents the root
- # meta-class in the "Next" object system.
- #
- # @superclass ::nx::doc::entities::class::nx::Object
-
- # @class.method {Class alloc}
- #
- # Creates a bare object or class which is not
- # fully initialized. {{{alloc}}} is used by {{@method ::nx::Class class create}} to
- # request a memory object storage. In subsequent steps,
- # {{{create}}} invokes {{{configure}}} and {{{init}}} to further
- # set up the object. Only in rare situations, you may consider
- # bypassing the overall {{{create}}} mechanism by just allocating
- # uninitialized objects using {{{alloc}}}.
- #
- # @properties interally-called
- # @param name The object identifier assigned to the object storage to be allocated.
- # @return The name of the allocated, uninitialized object
-
- # @class.method {Class create}
- #
- # Provides for creating application-level classes and objects. If
- # the method receiver is a meta-class, a class will be
- # created. Otherwise, {{{create}}} yields an object. {{{create}}}
- # is responsible a multi-phase object creation scheme. This
- # creation scheme involves three major steps:
- # {{{
- # [Object create anObject] (1)
- # ---------------. .--------------.
- # -------------->|Class->create()|-->|Class->alloc()|
- # `---------------' `--------------'
- # | | (2) .-------------------.
- # | .----->|Object->configure()|
- # | `-------------------'
- # | (3) .------.
- # .........>|init()|
- # `------'
- # }}}
- # (1) A call to {{@method ::nx::Class class alloc}} to create a raw,
- # uninitalized object.
- #
- # (2) The newly allocated object receives a method call upon
- # {{@method ::nx::Object class configure}}. This will establish the
- # object's initial state, by applying object parameter values
- # provided at object creation time and default values defined at
- # object definition time.
- #
- # (3) Finally, {{{create}}} emits a call to the initialization
- # method {{{init}}} (i.e., the actual "constructor"), if
- # available. An {{{init}}} method can be defined by a class on
- # behalf of its objects, to lay out class-specific initialisation
- # behaviour. Alternatively, each single object may define an
- # {{{init}}} method on its own.
- #
- # By overloading the method in a meta-class, you can refine or
- # replace this default object creation scheme (e.g., for applying
- # application-specific naming schemes).
- #
- # For creating an object or a class, you must name {{{create}}}
- # explicitly, i.e.:
- # {{{
- # ::nx::Object create anObject
- # ::nx::Class create AClass
- # ::nx::Class AnotherClass; # This fails: "Method 'AnotherClass' unknown for ::nx::Class."
- # }}}
- #
- # @param name The designated identifier on the class or the object to be created.
- # @param args arguments to be passed down to the object creation
- # procedure used to initialize the object.
- # @return The name of the created, fully initialized object.
-
- # @class.method {Class dealloc}
- #
- # Marks objects for physical deletion in memory. Beware the fact
- # that calling {{{dealloc}}} does not necessarily cause the object
- # to be deleted immediately. Depending on the lifecycle of the the
- # object's environment (e.g., the {{{interp}}}, the containing
- # namespace) and on call references down the callstack, the actual
- # memory freeing operation may occur time-shifted (that is,
- # later). While {{{dealloc}}} itself cannot be redefined for
- # {{{::nx::Class}}}, you may consider refining it in a subclass or
- # mixin class for customizing the destruction process.
- #
- # @properties interally-called
- # @param object The name of the object to be scheduled for deletion.
-
- # @class.method {Class recreate}
- #
- # This method is called upon recreating an object. Recreation is the
- # scheme for resolving object naming conflicts in the dynamic and
- # scripted programming environment of "Next": An object or class is
- # created while an object or class with an identical object identifier
- # already exists. The method {{{recreate}}} performs standard object
- # initialization, per default, after re-setting the state and
- # relationships of the object under recreation. This re-set is
- # achieved by invoking {{@method ::nx::Object class cleanup}}.
- # {{{
- # Object create Bar
- # \# ...
- # Object create Bar; # calls Object->recreate(::Bar, ...) + ::Bar->cleanup()
- # }}}
- # By refining {{{recreate}}} in an application-level subclass or mixin
- # class, you can intercept the recreation process. In the pre-part the
- # refined {{{recreate}}} method, the recreated object has its old
- # state, after calling {{@command ::nx::next}} it is cleaned up.
- #
- # If the name conflict occurs between an existing class and a newly
- # created object (or vice versa), {{{recreate}}} is not
- # performed. Rather, a sequence of {{@method ::nx::Object class destroy}}
- # and {{@method ::nx::Class class create}} is triggered:
- # {{{
- # Object create Bar
- # \# ...
- # Class create Bar; # calls Bar->destroy() + Class->create(::Bar, ...)
- # }}}
- #
- # @properties interally-called
- # @param name The name (identifier) of the object under recreation
- # @param args Arbitrary vector of arguments
- # @return The name of the recreated object
-
- # @class.method {Object residualargs}
- #
- # @properties interally-called
- # @param args
::nsf::createobjectsystem ::nx::Object ::nx::Class {
-class.alloc alloc
-class.create create
@@ -186,14 +33,6 @@
#
namespace eval ::nsf {}
- # @command next
- #
- # @use ::nsf::command
-
- # @command current
- #
- # @use ::nsf::current
-
namespace import ::nsf::next ::nsf::current
#
@@ -205,115 +44,13 @@
::nsf::alias Object $cmdName $cmd
}
- # @class.method {Object configure}
- #
- # This method participates in the object creation process. It is
- # automatically invoked after having produced a new object by
- # {{@method ::nx::Class class create}}.
- # Upon its invocation, the variable argument vector {{{args}}}
- # contains a list of parameters and parameter values passed in
- # from the call site of object creation. They are matched against
- # an object parameter definition. This definition, and so the
- # actual method parameter definition of this method, is assembled
- # from configuration values of the classes along the precedence
- # order (see also {{@method ::nx::Object class objectparameter}}).
- # The method {{{configure}}} can be called at arbitrary times to
- # "re-set" an object.
- #
- # @properties interally-called
- # @param args The variable argument vector stores the object parameters and their values
-
- # @class.method {Object destroy}
- #
- # The standard destructor for an object. The method {{@method ::nx::Object class destroy}}
- # triggers the physical destruction of the object. The method {{{destroy}}} can be refined
- # by subclasses or mixin classes to add additional (class specific) destruction behavior.
- # Note that in most cases, the class specific {{{destroy}}} methods should call
- # {{@command ::nx::next}} to trigger physical destruction.
- # {{{
- # nx::Class create Foo {
- # :method destroy {} {
- # puts "destroying [self]"
- # next
- # }
- # }
- # Foo create f1
- # f1 destroy
- # }}}
- # Technical details: The method {{@method ::nx::Object class destroy}}
- # delegates the actual destruction to {{@method ::nx::Class class dealloc}}
- # which clears the memory object storage. Essentially, the behaviour could be
- # scripted as:
- # {{{
- # Object method destroy {} {
- # [:info class] dealloc [self]
- # }
- # }}}
- # Note, however, that {{{destroy}}} is protected against
- # application-level redefinition. You must refine it in a subclass
- # or mixin class.
- #
-
- # @class.method {Object uplevel}
- #
- # This helper allows you to evaluate a script in the context of
- # another callstack level (i.e., callstack frame).
- #
- # @param level:optional The starting callstack level (defaults to the value of {{{[current callinglevel]}}})
- # @param script:list The script to be evaluated in the targeted callstack level
-
- # @class.method {Object upvar}
- #
- # This helper allows you to bind a local variable to a variable
- # residing at a different callstack level (frame).
- #
- # @param level:optional The starting callstack level (defaults to the value of {{{[current callinglevel]}}})
- # @param sourceVar A variable which should be linked to a ...
- # @param targetVar ... which is a local variable in a method scope
- # @see ...
-
- # @class.method {Object volatile}
- #
- # By calling on this method, the object is bound in its lifetime to
- # the one of call site (e.g., the given Tcl proc or method scope):
- # {{{
- # proc foo {} {
- # info vars; # shows ""
- # set x [Object create Bar -volatile]
- # info vars; # shows "x Bar"
- # }
- # }}}
- # Behind the scenes, {{{volatile}}} registers a C-level variable trace
- # ({{{Tcl_TraceVar()}}}) on the hiddenly created local variable (e.g.,
- # {{{Bar}}}), firing upon unset events and deleting the referenced
- # object ({{{Bar}}}). That is, once the callframe context of {{{foo}}}
- # is left, the local variable {{{Bar}}} is unset and so the bound
- # object is destroyed.
-
# provide ::eval as method for ::nx::Object
::nsf::alias Object eval -nonleaf ::eval
#
# class methods
#
- # @class.method {Class new}
- #
- # A convenience method to create auto-named objects and classes. It is
- # a front-end to {{@method ::nx::Class class create}}. For instance:
- # {{{
- # set obj [Object new]
- # set cls [Class new]
- # }}}
- #
- # This will provide object identifiers of the form
- # e.g. {{{::nsf::__#0}}}. In contrast to {{@method ::nx::Object class autoname}},
- # the uniqueness of auto-generated identifiers is guaranteed for the
- # scope of the {{{interp}}}.
- #
- # @param -childof If provided, the new object is created as a child of the specified object.
- # @param args The variable arguments passed down to {{@method ::nx::Class class create}}.
-
# provide the standard command set for Class
foreach cmd [info command ::nsf::cmd::Class::*] {
set cmdName [namespace tail $cmd]
@@ -398,30 +135,6 @@
# define method "method" for Class and Object
- # @class.method {Class method}
- #
- # Defines a per-class method, similarly to Tcl specifying
- # {{{procs}}}. Optionally assertions may be specified by two
- # additional arguments. Therefore, to specify only post-assertions
- # an empty pre-assertion list must be given. All assertions are a
- # list of ordinary Tcl {{{expr}}} statements. When {{{method}}} is
- # called with an empty argument list and an empty body, the
- # specified method is deleted.
- # {{{
- # Class create AClass {
- # :method foo args {;}
- # }
- #
- # AClass create anInstance
- # anInstance foo; # invokes "foo"
- # }}}
- #
- # @param name The method name
- # @param arguments:list A list specifying non-positional and positional parameters
- # @param body The script which forms the method body
- # @param preAssertion Optional assertions that must hold before the proc executes
- # @param postAssertion Optional assertions that must hold after the proc executes
-
::nsf::method Class method {
name arguments body -precondition -postcondition
} {
@@ -435,27 +148,6 @@
return $r
}
- # @class.method {Object method}
- #
- # Defines a per-object method, similarly to Tcl specifying
- # {{{procs}}}. Optionally assertions may be specified by two
- # additional arguments. Therefore, to specify only post-assertions
- # an empty pre-assertion list must be given. All assertions are a
- # list of ordinary Tcl {{{expr}}} statements. When {{{method}}} is
- # called with an empty argument list and an empty body, the
- # specified method is deleted.
- # {{{
- # Object create anObject {
- # :method foo args {;}
- # }
- # anObject foo; # invokes "foo"
- # }}}
- #
- # @param name The method name
- # @param arguments:list A list specifying non-positional and positional parameters
- # @param body The script which forms the method body
- # @param preAssertion Optional assertions that must hold before the proc executes
- # @param postAssertion Optional assertions that must hold after the proc executes
::nsf::method Object method {
name arguments body -precondition -postcondition -returns
} {
@@ -555,102 +247,9 @@
# define forward methods
- # @class.method {Object forward}
- #
- # Register a per-object method (similar to a {{{proc}}}) for
- # forward-delegating calls to a callee (target Tcl command, other
- # object). When the forwarder method is called, the actual arguments
- # of the invocation are appended to the specified arguments. In
- # callee an arguments certain substitutions can take place:
- #
- # {{{%proc}}} substituted by name of the forwarder method
- #
- # {{{%self}}} substitute by name of the object
- #
- # {{{%1}}} substitute by first argument of the invocation
- #
- # {{{ {%@POS value} }}} substitute the specified value in the
- # argument list on position POS, where POS can be a positive or
- # negative integer or end. Positive integers specify the position
- # from the begin of the list, while negative integer specify the
- # position from the end.
- #
- # {{{ {%argclindex LIST} }}} take the nth argument of the specified
- # list as substitution value, where n is the number of arguments
- # from the invocation.
- #
- # {{{%%}}} a single percent.
- #
- # {{{%Tcl-command}}} command to be executed; substituted by result.
- #
- # Additionally each argument can be prefixed by the positional prefix
- # %@POS (note the delimiting space at the end) that can be used to
- # specify an explicit position. POS can be a positive or negative
- # integer or the word end. The positional arguments are evaluated from
- # left to right and should be used in ascending order.
- #
- # @param name The name of the delegating or forward method
- # @param -objscope:optional Causes the target to be evaluated in the scope of the object.
- # @param -methodprefix Prepends the specified prefix to the second argument of the invocation.
- # @param -default Is used for default method names (only in connection with %1)
- # @param -earlybinding Look up the function pointer of the called Tcl command at definition time of the forwarder instead of invocation time. This option should only be used for calling C-implemented Tcl commands, no scripted procs
- # @param -verbose Print the substituted command to stderr before executing
- # @param callee
- # @param args
::nsf::forward Object forward ::nsf::forward %self -per-object
#set ::nsf::signature(::nx::Object-method-forward) {(methodName) obj forward name ?-default default? ?-earlybinding? ?-methodprefix name? ?-objscope? ?-onerror proc? ?-verbose? target ?args?}
- # @class.method {Class forward}
- #
- # Register a per-class method (similar to a {{{proc}}}) for
- # forward-delegating calls to a callee (target Tcl command, other
- # object). When the forwarder method is called on an instance of the
- # class, the actual arguments of the invocation are appended to the
- # specified arguments. In callee an arguments certain substitutions
- # can take place:
- #
- # {{{%proc}}} substituted by name of the forwarder method
- #
- # {{{%self}}} substitute by name of the object
- #
- # {{{%1}}} substitute by first argument of the invocation
- #
- # {{{ {%@POS value} }}} substitute the specified value in the
- # argument list on position POS, where POS can be a positive or
- # negative integer or end. Positive integers specify the position
- # from the begin of the list, while negative integer specify the
- # position from the end.
- #
- # {{{ {%argclindex LIST} }}} take the nth argument of the specified
- # list as substitution value, where n is the number of arguments
- # from the invocation.
- #
- # {{{%%}}} a single percent.
- #
- # {{{%Tcl-command}}} command to be executed; substituted by result.
- #
- # Additionally each argument can be prefixed by the positional prefix
- # %@POS (note the delimiting space at the end) that can be used to
- # specify an explicit position. POS can be a positive or negative
- # integer or the word end. The positional arguments are evaluated from
- # left to right and should be used in ascending order.
- #
- # @param name The name of the delegating or forward method
- # @param -objscope:optional Causes the target to be evaluated in the
- # scope of the object.
- # @param -methodprefix Prepends the specified prefix to the second
- # argument of the invocation.
- # @param -default Is used for default method names (only in
- # connection with %1)
- # @param -earlybinding Look up the function pointer of the called
- # Tcl command at definition time of the forwarder instead of
- # invocation time. This option should only be used for calling
- # C-implemented Tcl commands, no scripted procs
- # @param -verbose Print the substituted command to stderr before
- # executing
- # @param callee
- # @param args
-
::nsf::forward Class forward ::nsf::forward %self
# The method __unknown is called in cases, where we try to resolve
@@ -848,111 +447,6 @@
# we have to use "eval", since objectParameters are not defined yet
- # @class.method {Object info}
- #
- # Provides introspection on objects. A variety of introspection
- # options exists. {{{info}}} is implemented as en ensemble
- # object. Hence, the introspection options turn into proper
- # sub-methods.
- #
- # @sub-method callable
- # @sub-method has
- # @sub-method filter
- # @sub-method is Binds all introspection facilities offered by
- # {{{::nsf::is}}} to the object, i.e., the object is automatically
- # folded in as the first argument passed to {{{::nsf::is}}}
- # @sub-method mixin
-
- # @class.method {Object "info callable method"}
- #
- # Verifies whether there is a method under a given name available
- # for invocation upon the object. In case, the introspective call
- # returns the corresponding method handle. If there is no so named
- # method available, an empty string is returned.
-
- # @class.method {Object "info callable filter"}
- #
- # Search for a method which is currently registered as a filter (in
- # the invocation scope of the given object). If found, the
- # corresponding method handle is returned.
-
- # @class.method {Object "info children"}
- #
- # Computes the list of aggregated (or nested) objects. The resulting
- # list reports the fully qualified object names. If a name pattern
- # was specified, all matching child objects are returned. Otherwise,
- # all children are reported.
-
-
- # @class.method {Object "info class"}
- #
- # Gives the name of the class of the current object.
-
- # @class.method {Object "info filter guard"}
- #
- # Returns the guards for filter identified by a filter name
-
- # @class.method {Object "info filter methods"}
- #
- # Returns a list of methods registered as filters.
-
- # @class.method {Object "info forward"}
- #
- # Provides you with the list of forwarders defined for the given
- # object.
-
- # @class.method {Object "info has mixin"}
- #
- # Verifies in a boolean test whether the object has the given class
- # registered as a mixin class.
-
- # @class.method {Object "info has namespace"} Some words on info has type
- #
- # Tells you whether the object has a companion, per-object Tcl
- # namespace. Note that the results do not necessarily correspond to
- # those yielded by {{{[namespace exists /obj/]}}}.
-
- # @class.method {Object "info has type"}
- #
- # 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.
-
- # @class.method {Object "info methods"}
- #
- # Allows you to query the methods (of various kinds) defined on the
- # object.
-
- # @class.method {Object "info mixin guard"}
- #
- # Retrieves the guards applied to the mixin class idenitified by the
- # mixin class name
-
- # @class.method {Object "info mixin classes"}
- #
- # The list of per-object mixin classes currently registered for the
- # object is returned.
-
- # @class.method {Object "info parent"}
- #
- # Resolves the fully qualified name of the parent object (or "::" if
- # there is no parent object).
-
- # @class.method {Object "info precedence"}
- #
- # Presents to you the list of classes the object is inheriting
- # attributes and methods, ordered according to their precedence.
-
- # @class.method {Object "info slotobjects"}
- #
- # Assembles the list of slot objects which apply the given
- # object. They are resolved by following the class precedence list
- # upward and coercing the lists of slots provided by these classes.
-
- # @class.method {Object "info vars"}
- #
- # Yields a list of variable names created and defined on the object.
-
Object eval {
:alias "info callable" ::nsf::cmd::ObjectInfo::callable
:alias "info children" ::nsf::cmd::ObjectInfo::children
@@ -1146,25 +640,8 @@
}
namespace eval ::nx {
- # @class Slot
- #
- # A slot is a meta-object that manages property changes of
- # objects. A property is either an attribute or a role taken by an
- # object in an inter-object relation (e.g., in system slots). The
- # predefined system slots are {{{class}}}, {{{superclass}}},
- # {{{mixin}}}, and {{{filter}}}. These slots appear as methods of
- # {{@class ::nx::Object}} or {{@class ::nx::Class}}. The slots
- # provide a common getter and setter interface. Every multivalued
- # slot provides e.g. a method {{{add}}} to append a value to the
- # list of values, and a method {{{delete}}} which removes it.
- #
- # @superclass ::nx::doc::entities::class::nx::Object
MetaSlot create ::nx::Slot
- # @class ObjectParameterSlot
- #
- # @superclass ::nx::doc::entities::class::nx::Slot
-
MetaSlot create ::nx::ObjectParameterSlot
::nsf::relation ObjectParameterSlot superclass Slot
@@ -1220,26 +697,6 @@
# Define slots for slots
############################################
- # @class.param {Slot name}
- #
- # Name of the slot which can be used to access the slot from an object
-
- # @class.param {Slot multivalued}
- #
- # Boolean value for specifying single or multiple values (lists)
-
- # @class.param {Slot required}
- #
- # Denotes whether a value must be provided
-
- # @class.param {Slot default}
- #
- # Allows you to define a default value (to be set upon object creation)
-
- # @class.param {Slot type}
- #
- # You may specify a type constraint on the value range to managed by the slot
-
createBootstrapAttributeSlots ::nx::Slot {
{name}
{multivalued false}
@@ -1248,35 +705,6 @@
type
}
- # @class.param {ObjectParameterSlot name}
- #
- # Name of the slot which can be used to access the slot from an
- # object. It defaults to unqualified name of an instance.
-
- # @class.param {ObjectParameterSlot methodname}
- #
- # The name of the accessor methods to be registed on behalf of the
- # slot object with its domains can vary from the slot name.
-
- # @class.param {ObjectParameterSlot domain}
- #
- # The domain (object or class) of a slot on which it can be used
-
- # @class.param {ObjectParameterSlot defaultmethods}
- #
- # A list of two elements for specifying which methods are called per
- # default, when no slot method is explicitly specified in a call.
-
- # @class.param {ObjectParameterSlot manager}
- #
- # The manager object of the slot (per default, the slot object takes
- # this role, i.e. {{{[self]}}})
-
- # @class.param {ObjectParameterSlot per-object}
- #
- # If set to {{{true}}}, the accessor methods are registered with the
- # domain object scope only. It defaults to {{{false}}}.
-
createBootstrapAttributeSlots ::nx::ObjectParameterSlot {
{name "[namespace tail [::nsf::current object]]"}
{methodname}
@@ -1465,7 +893,6 @@
return $parameterdefinitions
}
- # @method ::nx::Object#objectparameter
Object protected method objectparameter {{lastparameter __initcmd:initcmd,optional}} {
#puts stderr "... objectparameter [::nsf::current object]"
set parameterdefinitions [::nsf::parametersFromSlots [::nsf::current object]]
@@ -1565,81 +992,21 @@
############################################
proc ::nsf::register_system_slots {os} {
- # @class.param {Class superclass}
- #
- # Specifies superclasses for a given class. As a setter ***
- # generell: setter kann hier mit der methode namens "setter"
- # verwechselt werden; wir sollten hier die paramter syntax
- # anfuehren, die allerdings in zwei varianten kommt:
- #{{{
- # obj superclass ?value?
- # obj superclass add|assign|delete|get value
- #}}}
- # Das gilt allgemein, nicht nur für die relation-slots, sondern
- # für alle incremental slots.
- # **** {{{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
::nx::RelationSlot create ${os}::Class::slot::superclass
::nsf::alias ${os}::Class::slot::superclass assign ::nsf::relation
- # @class.param {Object class}
- #
- # Sets or retrieves the class of an object. When {{{class}}} is
- # called without arguments, it returns the current class of the
- # object.
- #
- # @return If called as a getter (without arguments), {{{class}}} returns the current class of the object
::nx::RelationSlot create ${os}::Object::slot::class -multivalued false
::nsf::alias ${os}::Object::slot::class assign ::nsf::relation
- # @class.param {Object mixin}
- #
- # As a setter, {{{mixin}}} specifies a list of mixins to
- # set. Every mixin must be an existing class. In getter mode, you
- # can retrieve the list of mixins active for the given object.
- #
- # @return :list If called as a getter (without arguments), {{{mixin}}} returns the list of current mixin classes registered with the object
::nx::RelationSlot create ${os}::Object::slot::mixin \
-methodname object-mixin
- # @class.param {Object filter}
- #
- # In its setter mode, {{{filter}}} allows you to register methods
- # as per-object filters. Every filter must be an existing method
- # in the scope of the object. When acting as a getter, you can
- # retrieve the list of filter methods active for the given object.
- #
- # @return :list If called as a getter (without arguments),
- # {{{filter}}} returns the list of current filters
- # registered with the object
::nx::RelationSlot create ${os}::Object::slot::filter -elementtype "" \
-methodname object-filter
- # @class.param {Class mixin}
- #
- # As a setter, {{{mixin}}} specifies a list of mixins to set for
- # the class. Every mixin must be an existing class. In getter
- # mode, you can retrieve the list of mixins active for the given
- # class.
- #
- # @return :list If called as a getter (without arguments), {{{mixin}}} returns the list of current mixin classes registered with the class
::nx::RelationSlot create ${os}::Class::slot::mixin -methodname class-mixin
- # @class.param {Class filter}
- #
- # In its setter mode, {{{filter}}} allows you to register methods
- # as per-class filters. Every filter must be an existing method
- # in the scope of the class. When acting as a getter, you can
- # retrieve the list of filter methods active for the given class.
- #
- # @return :list If called as a getter (without arguments),
- # {{{filter}}} returns the list of current filters
- # registered with the class
::nx::RelationSlot create ${os}::Class::slot::filter -elementtype "" \
-methodname class-filter
@@ -1691,37 +1058,6 @@
############################################
::nsf::invalidateobjectparameter MetaSlot
- # @class Attribute
- #
- # Attribute slots are used to manage the access, mutation, and
- # querying of instance variables. One defines Attribute slots
- # for objects and classes usually via the helper method
- # {{@method ::nx::Object class attribute}}
- # **** TODO STEFAN, kein Link? GEPLANT? MIT 2 GESCHWEIFTEN KLAMMER UM SALARY GIBT ES EINEN LAUFZEITFEHLER??? ********
- # The following example defines a class with
- # three attribute slots. The attribute {salary} has
- # a default of {0}, the attribute {projects} has the
- # empty list as default and is defined as multivalued.
- # {{{
- # Class create Person {
- # :attribute name
- # :attribute {salary:integer 0}
- # :attribute {projects:multivalued ""} {
- # set :incremental true
- # }
- # }
- # }}}
- #
- # @param incremental A boolean value, only useful for multivalued
- # slots. When set, one can add/delete incrementally values to the
- # multivalued set (e.g., through an incremental {{{add}}})
- # @param valuecmd A Tcl command to be executed whenever the managed
- # object variable is read
- # @param valuechangedcmd A Tcl command to be executed whenever the
- # value of the managed object variable changes
- # @param arg
- # @superclass ::nx::doc::entities::class::nx::ObjectParameterSlot
-
MetaSlot create ::nx::Attribute -superclass ObjectParameterSlot
createBootstrapAttributeSlots ::nx::Attribute {
Index: tests/doc.tcl
===================================================================
diff -u -rfee959816f9851be0afd54905e906854680fccb2 -r25f4f3c883ff0021b8564377f6658afb69c346c8
--- tests/doc.tcl (.../doc.tcl) (revision fee959816f9851be0afd54905e906854680fccb2)
+++ tests/doc.tcl (.../doc.tcl) (revision 25f4f3c883ff0021b8564377f6658afb69c346c8)
@@ -328,7 +328,7 @@
{}
{some text on the class entity}
{}
- {@class-param attr1 Here! we check whether we can get a valid description block}
+ {@class-attribute attr1 Here! we check whether we can get a valid description block}
{for text spanning multiple lines}
}
@@ -339,9 +339,9 @@
? [list ::nsf::is object $entity] 1
? [list $entity info has type ::nx::doc::@class] 1
? [list $entity as_text] "some text on the class entity";
- ? [list llength [$entity @param]] 1
- ? [list [$entity @param] info has type ::nx::doc::@param] 1
- ? [list [$entity @param] as_text] "Here! we check whether we can get a valid description block for text spanning multiple lines"
+ ? [list llength [$entity @attribute]] 1
+ ? [list [$entity @attribute] info has type ::nx::doc::@param] 1
+ ? [list [$entity @attribute] as_text] "Here! we check whether we can get a valid description block for text spanning multiple lines"
#
# basic test for in-situ documentation (initcmd block)
@@ -354,7 +354,7 @@
# @author gustaf.neumann@wu-wien.ac.at
# @author ssoberni@wu.ac.at
- # @.param attr1
+ # @.attribute attr1
#
# This attribute 1 is wonderful
#
@@ -368,8 +368,8 @@
#
# This describes the foo method
#
- # @param a Provides a first value
- # @param b Provides a second value
+ # @parameter a Provides a first value
+ # @parameter b Provides a second value
:method foo {a b} {;}
}
}
@@ -383,9 +383,9 @@
? [list $entity @author] "gustaf.neumann@wu-wien.ac.at ssoberni@wu.ac.at"
# TODO: Fix the [@param id] programming scheme to allow (a) for
# entities to be passed and the (b) documented structures
- set entity [@param id [@class id ::Foo] class attr1]
+ set entity [@attribute id [@class id ::Foo] class attr1]
? [list ::nsf::is object $entity] 1
- ? [list $entity info has type ::nx::doc::@param] 1
+ ? [list $entity info has type ::nx::doc::@attribute] 1
? [list $entity @see] "::nx::Attribute ::nx::MetaSlot";
set entity [@method id ::Foo class foo]
@@ -394,7 +394,7 @@
? [list $entity info has type ::nx::doc::@method] 1
? [list $entity as_text] "This describes the foo method";
- foreach p [$entity @param] expected {
+ foreach p [$entity @parameter] expected {
"Provides a first value"
"Provides a second value"
} {
@@ -415,7 +415,7 @@
# @author gustaf.neumann@wu-wien.ac.at
# @author ssoberni@wu.ac.at
- # @class.param {::Bar attr1}
+ # @class.attribute {::Bar attr1}
#
# This attribute 1 is wonderful
#
@@ -427,15 +427,15 @@
#
# This describes the foo method
#
- # @param a Provides a first value
- # @param b Provides a second value
+ # @parameter a Provides a first value
+ # @parameter b Provides a second value
# @class.object-method {::Bar foo}
#
# This describes the per-object foo method
#
- # @param a Provides a first value
- # @param b Provides a second value
+ # @parameter a Provides a first value
+ # @parameter b Provides a second value
namespace eval ::ns1 {
::nx::Object create ooo
@@ -450,21 +450,21 @@
#
# This describes the foo method in the initcmd
#
- # @param a Provides a first value
- # @param b Provides a second value
+ # @parameter a Provides a first value
+ # @parameter b Provides a second value
:method foo {a b} {
# This describes the foo method in the method body
#
- # @param a Provides a first value (refined)
+ # @parameter a Provides a first value (refined)
}
:object method foo {a b c} {
# This describes the per-object foo method in the method body
#
- # @param b Provides a second value (refined)
- # @param c Provides a third value (first time)
+ # @parameter b Provides a second value (refined)
+ # @parameter c Provides a third value (first time)
}
@@ -481,9 +481,9 @@
# TODO: Fix the [@param id] programming scheme to allow (a) for
# entities to be passed and the (b) documented structures
- set entity [@param id [@class id ::Bar] class attr1]
+ set entity [@attribute id [@class id ::Bar] class attr1]
? [list $i eval [list ::nsf::is object $entity]] 1
- ? [list $i eval [list $entity info has type ::nx::doc::@param]] 1
+ ? [list $i eval [list $entity info has type ::nx::doc::@attribute]] 1
? [list $i eval [list $entity @see]] "::nx::Attribute ::nx::MetaSlot";
set entity [@method id ::Bar class foo]
@@ -492,7 +492,7 @@
? [list $i eval [list $entity info has type ::nx::doc::@method]] 1
? [list $i eval [list $entity as_text]] "This describes the foo method in the method body";
- foreach p [$i eval [list $entity @param]] expected {
+ foreach p [$i eval [list $entity @parameter]] expected {
"Provides a first value (refined)"
"Provides a second value"
} {
@@ -506,7 +506,7 @@
? [list $i eval [list $entity info has type ::nx::doc::@method]] 1
? [list $i eval [list $entity as_text]] "This describes the per-object foo method in the method body";
- foreach p [$i eval [list $entity @param]] expected {
+ foreach p [$i eval [list $entity @parameter]] expected {
"Provides a first value"
"Provides a second value (refined)"
"Provides a third value (first time)"
@@ -550,33 +550,33 @@
# This fails because we do not allow uninitialised/non-existing
# entity objects (@object o) along the resolution path ...
set block {
- {@class.object.param {::C o attr1} We have an invalid specification}
+ {@class.object.attribute {::C o attr1} We have an invalid specification}
}
set cbp [CommentBlockParser process $block]
? [list $cbp status ? STYLEVIOLATION] 1
# ? [list $cbp message] "The tag 'object' is not supported for the entity type '@class'"
set block {
- {@class.method.param attr1 We have an imbalanced specification (the names are underspecified!)}
+ {@class.method.attribute attr1 We have an imbalanced specification (the names are underspecified!)}
}
set cbp [CommentBlockParser process $block]
? [list $cbp status ? STYLEVIOLATION] 1
- ? [list $cbp message] "Imbalanced tag line specification in '@class.method.param attr1 We have an imbalanced specification (the names are underspecified!)'."
+ ? [list $cbp message] "Imbalanced tag line specification in '@class.method.attribute attr1 We have an imbalanced specification (the names are underspecified!)'."
# For now, we do not verify and use a fixed scope of permissive tag
# names. So, punctuation errors or typos are most probably reported
# as imbalanced specs. In the mid-term run, this should rather
# become an INVALIDTAG condition.
set block {
- {@cla.ss.method.param {::C foo p1} We mistyped a tag fragment}
+ {@cla.ss.method.parameter {::C foo p1} We mistyped a tag fragment}
}
set cbp [CommentBlockParser process $block]
? [list $cbp status ? STYLEVIOLATION] 1
- ? [list $cbp message] "Imbalanced tag line specification in '@cla.ss.method.param {::C foo p1} We mistyped a tag fragment'."
+ ? [list $cbp message] "Imbalanced tag line specification in '@cla.ss.method.parameter {::C foo p1} We mistyped a tag fragment'."
set block {
- {@cla,ss.method.param {::C foo p1} We mistyped a tag fragment}
+ {@cla,ss.method.parameter {::C foo p1} We mistyped a tag fragment}
}
set cbp [CommentBlockParser process $block]
? [list $cbp status ? INVALIDTAG] 1
@@ -587,11 +587,11 @@
#
# The global description of ::C
#
- # @param attr1 Here we can only provide a description block for object parameters
+ # @attribute attr1 Here we can only provide a description block for object parameters
- # @class.param {::C attr1} Here, we could also write '@class.class-param \{::C attr1\}', @param is a mere forwarder! In the context section, only one-liners are allowed!
+ # @class.attribute {::C attr1} Here, we could also write '@class.class-attribute \{::C attr1\}', @attribute is a mere forwarder! In the context section, only one-liners are allowed!
- # @class.object.param {::C foo p1} A short description is ...
+ # @class.object.attribute {::C foo p1} A short description is ...
#
# .. is overruled by a long one ...
@@ -619,9 +619,9 @@
# This is the initcmd-level description of ::C which overwrites the
# global description (see above)
- # @.param attr1
+ # @.attribute attr1
#
- # This is equivalent to writing "@class-param attr1"
+ # This is equivalent to writing "@class-attribute attr1"
:attribute attr1 {
# This description does not apply to the object parameter
# "attr1" owned by the ::C class, rather it is a description
@@ -630,20 +630,20 @@
# initcmd-level descriptions?
}
- # @.object-param attr2 Carries a short desc only
+ # @.object-attribute attr2 Carries a short desc only
:object attribute attr2
# @.method foo
#
- # @param p1
+ # @parameter p1
set fooHandle [:method foo {p1} {
# Here goes some method-body-level description
#
- # @param p1 The most specific level!
+ # @parameter p1 The most specific level!
return [current method]-$p1-[current]
}]
- # @.object-method.param {bar p1}
+ # @.object-method.parameter {bar p1}
#
# This extended form allows to describe a method parameter with all
# its structural features!
@@ -653,17 +653,17 @@
# @.object foo 'foo' needs to be defined before referencing any of its parts!
- # @.object.param {foo p1}
+ # @.object.attribute {foo p1}
#
# The first element in the name list is resolved into a fully
# qualified (absolute) entity, based on the object owning the
# initcmd!
Object create [current]::foo {
# Adding a line for the first time (not processed in the initcmd phase!)
- # @..param p1
+ # @..attribute p1
#
- # This is equivalent to stating "@object-param p1"
+ # This is equivalent to stating "@object-attribute p1"
:attribute p1
}
@@ -673,21 +673,21 @@
# context of the initcmd-owning object, i.e. you would NOT refer to
# a nested class object named "Foo" anymore!
- # @.class.param {Foo p1}
+ # @.class.attribute {Foo p1}
#
- # This is equivalent to stating "@child-class.class-param {Foo p1}"
+ # This is equivalent to stating "@child-class.class-attribute {Foo p1}"
- # @.class.object-param {Foo p2} Y
+ # @.class.object-attribute {Foo p2} Y
Class create [current]::Foo {
- # @..param p1
+ # @..attribute p1
#
#
- # This is equivalent to stating "@class-param p1"; or
- # '@class.object.param {::C Foo p1}' from the top-level.
+ # This is equivalent to stating "@class-attribute p1"; or
+ # '@class.object.attribute {::C Foo p1}' from the top-level.
:attribute p1
- # @..object-param p2
+ # @..object-attribute p2
:object attribute p2
}
@@ -701,7 +701,7 @@
# could allow both (@sub-method is the attribute name, @method is a
# forwarder in the context of an owning @method object!)
#
- # @param p1 Some words on p1
+ # @parameter p1 Some words on p1
:object alias "sub foo" $fooHandle
# @.method sub
@@ -728,7 +728,7 @@
# could allow both (@sub-method is the attribute name, @method is a
# forwarder in the context of an owning @method object!)
#
- # @param p1 Some words on p1
+ # @parameter p1 Some words on p1
# @see anotherentity
# @author ss@thinkersfoot.net
:object alias "sub foo2" $fooHandle
@@ -746,48 +746,48 @@
? [list ::nsf::isobject $entity] 1
? [list $entity info has type ::nx::doc::@class] 1
? [list $entity as_text] "The global description of ::C";
- # --testing-- "@class.param {::C attr1}"
- set entity [@param id $entity class attr1]
+ # --testing-- "@class.attribute {::C attr1}"
+ set entity [@attribute id $entity class attr1]
? [list ::nsf::isobject $entity] 1
- ? [list $entity info has type ::nx::doc::@param] 1
- ? [list $entity as_text] "Here, we could also write '@class.class-param {::C attr1}', @param is a mere forwarder! In the context section, only one-liners are allowed!"
+ ? [list $entity info has type ::nx::doc::@attribute] 1
+ ? [list $entity as_text] "Here, we could also write '@class.class-attribute {::C attr1}', @attribute is a mere forwarder! In the context section, only one-liners are allowed!"
- # --testing-- "@class.object.param {::C foo p1} A short description is ..."
- # set entity [@param id $entity class attr1]
+ # --testing-- "@class.object.attribute {::C foo p1} A short description is ..."
+ # set entity [@attribute id $entity class attr1]
# set entity [@object id -partof_name ::C -scope child foo]
# ? [list ::nsf::isobject $entity] 1
# ? [list $entity info has type ::nx::doc::@object] 1
# ? [list $entity as_text] ""
- # set entity [@param id $entity object p1]
+ # set entity [@attribute id $entity object p1]
# ? [list ::nsf::isobject $entity] 1
- # ? [list $entity info has type ::nx::doc::@param] 1
+ # ? [list $entity info has type ::nx::doc::@attribute] 1
# ? [list $entity as_text] ".. is overruled by a long one ..."
set entity [@object id ::C::foo]
? [list ::nsf::isobject $entity] 0
- set entity [@param id $entity object p1]
+ set entity [@attribute id $entity object p1]
? [list ::nsf::isobject $entity] 0
- # ? [list $entity info has type ::nx::doc::@param] 1
+ # ? [list $entity info has type ::nx::doc::@attribute] 1
# ? [list $entity as_text] ".. is overruled by a long one ..."
- # --testing-- @object-param attr2 (its non-existance)
- set entity [@param id [@class id ::C] object attr2]
+ # --testing-- @object-attribute attr2 (its non-existance)
+ set entity [@attribute id [@class id ::C] object attr2]
? [list ::nsf::isobject $entity] 0
# --testing-- @child-class Foo (its non-existance)
set entity [@class id ::C::Foo]
? [list ::nsf::isobject $entity] 0
# --testing -- @method foo (its non-existance)
set entity [@method id ::C class foo]
? [list ::nsf::isobject $entity] 0
- # --testing-- @object-method.param {bar p1} (its non-existance)
- set entity [@param id [@method id ::C object bar] "" p1]
+ # --testing-- @object-method.parameter {bar p1} (its non-existance)
+ set entity [@parameter id [@method id ::C object bar] "" p1]
? [list ::nsf::isobject $entity] 0
- # --testing-- @child-object.param {foo p1} (its non-existance)
+ # --testing-- @child-object.attribute {foo p1} (its non-existance)
set cl [@class id ::C::Foo]
? [list ::nsf::isobject $entity] 0
- set entity [@param id $cl class p1]
+ set entity [@attribute id $cl class p1]
? [list ::nsf::isobject $entity] 0
- set entity [@param id $cl object p2]
+ set entity [@attribute id $cl object p2]
? [list ::nsf::isobject $entity] 0
#
@@ -805,27 +805,27 @@
? [list $entity info has type ::nx::doc::@class] 1
? [list $entity as_text] "This is the initcmd-level description of ::C which overwrites the global description (see above)"
- set entity [@param id $entity class attr1]
+ set entity [@attribute id $entity class attr1]
? [list ::nsf::isobject $entity] 1
- ? [list $entity info has type ::nx::doc::@param] 1
- ? [list $entity as_text] {This is equivalent to writing "@class-param attr1"}
+ ? [list $entity info has type ::nx::doc::@attribute] 1
+ ? [list $entity as_text] {This is equivalent to writing "@class-attribute attr1"}
set entity [@object id ::C::foo]
? [list ::nsf::isobject $entity] 1
? [list $entity info has type ::nx::doc::@object] 1
? [list $entity as_text] "'foo' needs to be defined before referencing any of its parts!"; # still empty!
- set entity [@param id $entity object p1]
+ set entity [@attribute id $entity object p1]
? [list ::nsf::isobject $entity] 1
- ? [list $entity info has type ::nx::doc::@param] 1
+ ? [list $entity info has type ::nx::doc::@attribute] 1
? [list $entity as_text] "The first element in the name list is resolved into a fully qualified (absolute) entity, based on the object owning the initcmd!"
# b) newly added ...
- # --testing-- @object-param attr2
- set entity [@param id [@class id ::C] object attr2]
+ # --testing-- @object-attribute attr2
+ set entity [@attribute id [@class id ::C] object attr2]
? [list ::nsf::isobject $entity] 1
- ? [list $entity info has type ::nx::doc::@param] 1
+ ? [list $entity info has type ::nx::doc::@attribute] 1
? [list $entity as_text] "Carries a short desc only";
# --testing-- @child-class Foo
@@ -835,26 +835,26 @@
? [list $entity info has type ::nx::doc::@class] 1
? [list $entity as_text] {By providing a fully-qualified identifier ("::Foo") you leave the context of the initcmd-owning object, i.e. you would NOT refer to a nested class object named "Foo" anymore!}
- set entity [@param id [@class id ::C] class p1]
+ set entity [@attribute id [@class id ::C] class p1]
? [list ::nsf::isobject $entity] 0; # should be 0 at this stage!
# --testing -- @method foo
set entity [@method id ::C class foo]
? [list ::nsf::isobject $entity] 1
? [list $entity as_text] ""
- # --testing-- @object-method.param {bar p1} (its non-existance) It
+ # --testing-- @object-method.parameter {bar p1} (its non-existance) It
# still cannot exist as a documented entity, as the object method
# has not been initialised before!
- set entity [@param id [@method id ::C object bar] "" p1]
+ set entity [@parameter id [@method id ::C object bar] "" p1]
? [list ::nsf::isobject $entity] 0
- # --testing-- @child-class.param {foo p1} (its non-existance)
- # --testing-- @child-class.object-param {foo p2} (its non-existance)
+ # --testing-- @child-class.attribute {foo p1} (its non-existance)
+ # --testing-- @child-class.object-attribute {foo p2} (its non-existance)
set cl [@class id ::C::Foo]
? [list ::nsf::isobject $cl] 1
- set entity [@param id $cl class p1]
+ set entity [@attribute id $cl class p1]
? [list ::nsf::isobject $entity] 1
- ? [list $entity as_text] {This is equivalent to stating "@child-class.class-param {Foo p1}"}
- set entity [@param id $cl object p2]
+ ? [list $entity as_text] {This is equivalent to stating "@child-class.class-attribute {Foo p1}"}
+ set entity [@attribute id $cl object p2]
? [list ::nsf::isobject $entity] 1
? [list $entity as_text] "Y"
@@ -877,7 +877,7 @@
? [list $entity @see] "anotherentity"
# TODO: @author not supported for @method (fine so?)
# ? [list $entity @author] "ss@thinkersfoot"
- set entity [@param id $entity "" p1]
+ set entity [@parameter id $entity "" p1]
? [list ::nsf::isobject $entity] 1
? [list $entity as_text] "Some words on p1"
@@ -892,16 +892,16 @@
set entity [@method id ::C class foo]
? [list ::nsf::isobject $entity] 1
? [list $entity as_text] "Here goes some method-body-level description"
- set entity [@param id [@method id ::C class foo] "" p1]
+ set entity [@parameter id [@method id ::C class foo] "" p1]
? [list ::nsf::isobject $entity] 1
? [list $entity as_text] "The most specific level!"
# attributes ...
# attr1
- set entity [@param id [@class id ::C] class attr1]
+ set entity [@attribute id [@class id ::C] class attr1]
? [list ::nsf::isobject $entity] 1
- ? [list $entity info has type ::nx::doc::@param] 1
+ ? [list $entity info has type ::nx::doc::@attribute] 1
? [list $entity as_text] {This description does not apply to the object parameter "attr1" owned by the ::C class, rather it is a description of the attribute slot object! How should we deal with this situation? Should this level overwrite the top-level and initcmd-level descriptions?}
#
@@ -915,23 +915,23 @@
? [list ::nsf::isobject $entity] 1
? [list $entity info has type ::nx::doc::@object] 1
? [list $entity as_text] "Adding a line for the first time (not processed in the initcmd phase!)"; # still empty!
- set entity [@param id $entity object p1]
+ set entity [@attribute id $entity object p1]
? [list ::nsf::isobject $entity] 1
- ? [list $entity info has type ::nx::doc::@param] 1
- ? [list $entity as_text] {This is equivalent to stating "@object-param p1"}
+ ? [list $entity info has type ::nx::doc::@attribute] 1
+ ? [list $entity as_text] {This is equivalent to stating "@object-attribute p1"}
doc analyze_initcmd -parsing_level 2 @class ::C::Foo [::C::Foo eval {set :__initcmd}]
doc process=@class [@class id ::C::Foo]
set cl [@class id ::C::Foo]
? [list ::nsf::isobject $cl] 1
- set entity [@param id $cl class p1]
+ set entity [@attribute id $cl class p1]
? [list ::nsf::isobject $entity] 1
- ? [list $entity as_text] {This is equivalent to stating "@class-param p1"; or '@class.object.param {::C Foo p1}' from the top-level.}
- set entity [@param id $cl object p2]
+ ? [list $entity as_text] {This is equivalent to stating "@class-attribute p1"; or '@class.object.attribute {::C Foo p1}' from the top-level.}
+ set entity [@attribute id $cl object p2]
? [list ::nsf::isobject $entity] 1
? [list $entity as_text] ""
-
+
puts stderr =================================================
#
# self documentation
@@ -1126,7 +1126,12 @@
# but if we would fold these into tcl-info, conflicts with
# tcl will arise.
+ # ISSUE: Object->info->parameter() still needed to retrieve
+ # objectparameters?
+ # TODO: decide how to deal with @package and @project names (don't
+ # need namespace delimiters!)
+
}
# if {$log} {