Index: doc/index.html =================================================================== diff -u -r782b1f820f03b0f09c3e333a5e03f9ad2808fcac -rbb58b68431fe35dd6ff16e69044705e1246d0dda --- doc/index.html (.../index.html) (revision 782b1f820f03b0f09c3e333a5e03f9ad2808fcac) +++ doc/index.html (.../index.html) (revision bb58b68431fe35dd6ff16e69044705e1246d0dda) @@ -23,7 +23,7 @@
Index: generic/gentclAPI.decls =================================================================== diff -u -r3f0573cc75724179f416942b974373e5a62ec05e -rbb58b68431fe35dd6ff16e69044705e1246d0dda --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision 3f0573cc75724179f416942b974373e5a62ec05e) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision bb58b68431fe35dd6ff16e69044705e1246d0dda) @@ -1,8 +1,21 @@ # -*- Tcl -*- # # This script is sourced by the C-code generator gentclAPI.tcl in the -# same directory +# same directory. It is also used by the next::doc toolkit to generate +# the authorative language reference documents. +# @package next +# +# "Next" 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 {{@object ::nx::Object}} and +# {{@object ::nx::Class}}, as well as essential language primitives +# (e.g., {{@command ::nx::next}} and {{@command ::nx::self}}). +# +# @require Tcl +# @version 1.0.0a + # namespaces for types of methods array set ns { xotclCmd "::nx::core" @@ -29,6 +42,72 @@ {-argName "assertionsubcmd" -required 1 -type "check|object-invar|class-invar"} {-argName "arg" -required 0 -type tclobj} } + +# @command ::nx::core::configure +# +# A top-level configuration facility which allows you modify +# properties of the "Next" object system for the scope of an entire +# {{{interp}}}. + +# @subcommand ::nx::core::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 + +# @subcommand ::nx::core::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 + + +# @subcommand ::nx::core::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": +# +# {{{ +# ::nx::core::configure objectsystems; # returns "::nx::Object ::nx::Class" +# }}} +# +# @return The active pair of root class and root meta-class + +# @subcommand ::nx::core::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 xotclCmd configure XOTclConfigureCmd { {-argName "configureoption" -required 1 -type "filter|softrecreate|objectsystems|keepinitcmd"} {-argName "value" -required 0 -type tclobj} @@ -58,6 +137,7 @@ } xotclCmd finalize XOTclFinalizeObjCmd { } + xotclCmd forward XOTclForwardCmd { {-argName "object" -required 1 -type object} {-argName "-per-object"} @@ -109,6 +189,23 @@ {-argName "method" -required 1 -type tclobj} {-argName "args" -type args} } + +# @command ::nx::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 + +# TODO: shouldn't next be defined here? + xotclCmd namespace_copycmds XOTclNSCopyCmds { {-argName "fromNs" -required 1 -type tclobj} {-argName "toNs" -required 1 -type tclobj} @@ -138,6 +235,31 @@ xotclCmd current XOTclCurrentCmd { {-argName "currentoption" -required 0 -type "proc|method|object|class|activelevel|args|activemixin|calledproc|calledmethod|calledclass|callingproc|callingmethod|callingclass|callinglevel|callingobject|filterreg|isnextcall|next"} } + +# @command ::nx::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. +# +# @subcommand 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. +# @subcommand proc Returns the name of the currently executing method. +# @subcommand callingclass Returns the name of the class which is calling into the executing method. +# @subcommand callingobject Returns the name of the object which is calling into the executing method. +# @subcommand calledclass Returns the name of the class that holds the originally (and now shadowed) target method (applicable in mixin classes and filters). +# @subcommand calledproc Returns the name of the target method (applicable in a filter only). +# @subcommand isnextcall Returns 1 if the executing method was invoked via {{@command ::nx::next}}, 0 otherwise. +# @subcommand next Returns the name of the method next on the precedence path as a string. +# @subcommand filterreg In a method serving as active filter, returns the name of the object (class) on which the method is registered as a filter. +# @subcommand 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}}. +# @subcommand 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}}. xotclCmd self XOTclSelfCmd { {-argName "selfoption" -required 0 -type "proc|method|object|class|activelevel|args|activemixin|calledproc|calledmethod|calledclass|callingproc|callingmethod|callingclass|callinglevel|callingobject|filterreg|isnextcall|next"} } @@ -151,73 +273,395 @@ {-argName "-per-object"} {-argName "parameter" -type tclobj} } + # # object methods # + +# @object ::nx::Object +# +# "Next" programs are constructed out of objects. This class +# describes common structural and behavioural features for all "Next" +# objects. It is the root object-class in the "Next" object system. + +# @method ::nx::Object#autoname +# +# Provides a facility for auto-generating object identifiers. It is +# constructed from a seeding string which is appended a numeric +# index. This numeric index is incremented upon each call to +# {{{autoname}}}. +# {{{ +# set obj [Object new] +# $obj autoname a; # yields "a1" +# $obj autoname -instance B; # yields "b1" +# $obj autoname a; # yields "a2" +# $obj autoname b; # yields "b1" +# $obj autoname -reset a; # "" +# $obj autoname -reset -instance B; # "" +# $obj autoname -instance a; # yields "a1", and NOT "a3"! +# $obj autoname -instance B; # yields "b1" +# $obj autoname b; # yields "b2" +# }}} +# The seeding string may also contain {{{[format]}}} expressions (see ...): +# {{{ +# $obj autoname a%06d; # gives you "a000001", ... +# }}} +# +# @param -instance Have the generated name start with a lower letter (though the seed string has a major first letter) +# @param -reset Reset the object-internal counter for a given seed string +# @param name The seeding string which is used as a base for name generation +# @return The generated name string objectMethod autoname XOTclOAutonameMethod { {-argName "-instance"} {-argName "-reset"} {-argName "name" -required 1 -type tclobj} } + +# @method ::nx::Object#cleanup +# +# Resets an object or class to its initial state, as after object +# allocation (see {{@method ::nx::Class class alloc}}). This method +# participates in recreating objects, i.e, it is called during the +# recreation process by {{@method ::nx::Class class recreate}}. +# Depending on the recreation scheme applied (see {{@command +# ::nx::core::configure}}, object variables are deleted, per-object +# namespaces are cleared, and the object's relationsships (e.g., mixin +# relations) are reset. objectMethod cleanup XOTclOCleanupMethod { } + +# @method ::nx::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. +# +# @param args The variable argument vector stores the object parameters and their values objectMethod configure XOTclOConfigureMethod { {-argName "args" -type allargs} } + +# @method ::nx::Object#destroy +# +# The method lays out the default object destruction process. By +# calling {{{destroy}}} on an object, you request its destruction: +# {{{ +# Object create anObject +# anObject destroy +# }}} +# Upon calling {{{destroy}}} on a given object, {{{destroy}}} +# delegates the actual destruction to {{@method ::nx::Class class dealloc}} +# which clears the memory object storage. +# {{{ +# [anObject destroy] .-----------------. .----------------. +# .......>|Object->destroy()|.....>|Class->dealloc()| +# `-----------------' `----------------' +# }}} +# 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. By doing so, {{{destroy}}} may be used to hook +# into the destruction process (e.g., to realise +# application-specific cleanup tasks). objectMethod destroy XOTclODestroyMethod { } + +# @method ::nx::Object#exists +# +# A helper method for checking whether the variable {{{var}}} is +# defined on the object and assigned a value. You may use a variable +# name with or without prefix, both will resolve to the object scope: +# {{{ +# $obj eval { +# set :foo 1 +# set bar 2 +# } +# +# $obj exists foo; # returns 1 +# $obj exists :foo; # returns 1 +# $obj exists bar; # returns 0 +# $obj exists :bar; # returns 0 +# }}} +# +# @param var The name of the variable to verify +# @return :boolean 1 if the variable exists, 0 otherwise objectMethod exists XOTclOExistsMethod { {-argName "var" -required 1} } + +# @method ::nx::Object#filter +# +# Adds gateway conditions to guard a filter registration point. The +# filter will only execute, if the guards evaluate to true. Otherwise, +# the filters are ignored the filter. If no guards are given, we +# always execute the filter. +# +# @param filter Handle to identify and address a filter once registered +# @param guard A list of guard expressions objectMethod filterguard XOTclOFilterGuardMethod { {-argName "filter" -required 1} {-argName "guard" -required 1 -type tclobj} } + +# @method ::nx::Object#filtersearch +# +# +# +# @param filter Handle to identify and address a filter once registered +# @param guard A list of guard expressions +# @return A string which describes a fully qualified method handle objectMethod filtersearch XOTclOFilterSearchMethod { {-argName "filter" -required 1} } + +# @method ::nx::Object#instvar +# +# @param args objectMethod instvar XOTclOInstVarMethod { {-argName "args" -type allargs} } + +# @method ::nx::Object#mixinguard +# +# @param mixin +# @param guard objectMethod mixinguard XOTclOMixinGuardMethod { {-argName "mixin" -required 1} {-argName "guard" -required 1 -type tclobj} } objectMethod __next XOTclONextMethod { {-argName "args" -type allargs} } + +# @method ::nx::Object#mixinguard +# +# @param mixin +# @param guard objectMethod noinit XOTclONoinitMethod { } + +# @method ::nx::Object#requireNamespace +# +# This method allows you to request the creation of a namespace for +# the given object, a per-object namespace. The namespace is then used +# to store instance variables, methods and nested objects. Per-object +# namespaces are needed for using and binding object variables to +# non-object scopes in Tcl and Tk. For instance, you may use an +# per-object namespace to have object variables accessible Tk widgets +# and Tk callbacks. To verify whether a per-object namespace is +# available for an object, see ... +# +# Beware that there is a difference between per-object namespaces and +# Tcl namespaces which shadow an existing object (i.e., carry the same +# name): +# {{{ +# Object create Foo +# Foo requireNamespace +# namespace exists Foo; # returns 1 +# Foo info hasnamespace; # returns 1 +# +# Object create Bar +# namespace eval ::Bar {} +# namespace exists Bar; # returns 1 +# Bar info hasnamespace; # returns 0 +# }}} objectMethod requireNamespace XOTclORequireNamespaceMethod { } + +# @method ::nx::Object#residualargs +# +# @param args objectMethod residualargs XOTclOResidualargsMethod { {-argName "args" -type allargs} } + +# @method ::nx::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 objectMethod uplevel XOTclOUplevelMethod { {-argName "args" -type allargs} } + +# @method ::nx::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 ... objectMethod upvar XOTclOUpvarMethod { {-argName "args" -type allargs} } + +# @method ::nx::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. objectMethod volatile XOTclOVolatileMethod { } + +# @method ::nx::Object#vwait +# +# A method variant of the Tcl {{{vwait}}} command. You can use it to +# have the {{{interp}}} enter an event loop until the specified +# variable {{{varname}}} is set on the object. +# +# @param varname The name of the signalling object variable. objectMethod vwait XOTclOVwaitMethod { {-argName "varname" -required 1} } # # class methods # + +# @object ::nx::Class +# +# A class defines a family of object types which own a common set of +# attributes (see {{@object ::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::object::nx::Object + +# @method ::nx::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}}}. +# +# @param name The object identifier assigned to the object storage to be allocated. +# @return The name of the allocated, uninitialized object classMethod alloc XOTclCAllocMethod { {-argName "name" -required 1 -type tclobj} } + +# @method ::nx::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. classMethod create XOTclCCreateMethod { {-argName "name" -required 1} {-argName "args" -type allargs} } + +# @method ::nx::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. +# +# @param object The name of the object to be scheduled for deletion. classMethod dealloc XOTclCDeallocMethod { {-argName "object" -required 1 -type tclobj} } + +# @method ::nx::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. {{{::nx::core::__#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}}. classMethod new XOTclCNewMethod { {-argName "-childof" -type object -nrargs 1} {-argName "args" -required 0 -type args} @@ -232,6 +676,40 @@ } classMethod __invalidateobjectparameter XOTclCInvalidateObjectParameterMethod { } + +# @method ::nx::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, ...) +# }}} +# +# @param name The name (identifier) of the object under recreation +# @param args Arbitrary vector of arguments +# @return The name of the recreated object classMethod recreate XOTclCRecreateMethod { {-argName "name" -required 1 -type tclobj} {-argName "args" -type allargs} Index: generic/predefined.h =================================================================== diff -u -rfb73930aa9ecf6ce966e512e6f899acb5784ea8c -rbb58b68431fe35dd6ff16e69044705e1246d0dda --- generic/predefined.h (.../predefined.h) (revision fb73930aa9ecf6ce966e512e6f899acb5784ea8c) +++ generic/predefined.h (.../predefined.h) (revision bb58b68431fe35dd6ff16e69044705e1246d0dda) @@ -1,5 +1,4 @@ static char cmd[] = -"\n" "namespace eval ::nx {\n" "set bootstrap 1\n" "::nx::core::createobjectsystem ::nx::Object ::nx::Class {\n" @@ -36,12 +35,14 @@ "::nx::core::methodproperty Class alloc redefine-protected true\n" "::nx::core::methodproperty Class dealloc redefine-protected true\n" "::nx::core::methodproperty Class create redefine-protected true\n" +"# anInstance foo; # invokes \"foo\"\n" "::nx::core::method Class method {\n" "name arguments body -precondition -postcondition} {\n" "set conditions [list]\n" "if {[info exists precondition]} {lappend conditions -precondition $precondition}\n" "if {[info exists postcondition]} {lappend conditions -postcondition $postcondition}\n" "::nx::core::method [::nx::core::current object] $name $arguments $body {*}$conditions}\n" +"#\n" "::nx::core::method Object method {\n" "name arguments body -precondition -postcondition} {\n" "set conditions [list]\n" @@ -81,7 +82,11 @@ ":protected method init args {}\n" ":protected method defaultmethod {} {::nx::core::current object}\n" ":protected method objectparameter {} {;}}\n" +"# argument list on position POS, where POS can be a positive or\n" +"# left to right and should be used in ascending order.\n" "::nx::core::forward Object forward ::nx::core::forward %self -per-object\n" +"# {{{ {%@POS value} }}} substitute the specified value in the\n" +"# integer or the word end. The positional arguments are evaluated from\n" "::nx::core::forward Class forward ::nx::core::forward %self\n" "Class protected object method __unknown {name} {}\n" "Object public method alias {-nonleaf:switch -objscope:switch methodName cmd} {\n" Index: generic/predefined.xotcl =================================================================== diff -u -rfb73930aa9ecf6ce966e512e6f899acb5784ea8c -rbb58b68431fe35dd6ff16e69044705e1246d0dda --- generic/predefined.xotcl (.../predefined.xotcl) (revision fb73930aa9ecf6ce966e512e6f899acb5784ea8c) +++ generic/predefined.xotcl (.../predefined.xotcl) (revision bb58b68431fe35dd6ff16e69044705e1246d0dda) @@ -1,4 +1,3 @@ - namespace eval ::nx { # # By setting the variable bootstrap, we can check later, whether we @@ -16,8 +15,8 @@ -class.create create -class.dealloc dealloc -class.recreate recreate - -class.requireobject __unknown - -object.configure configure + -class.requireobject __unknown + -object.configure configure -object.defaultmethod defaultmethod -object.destroy destroy -object.init init @@ -34,6 +33,8 @@ namespace export next self \ my is relation interp } + + namespace import ::nx::core::next ::nx::core::self # @@ -58,6 +59,7 @@ foreach cmd [list __next cleanup noinit residualargs uplevel upvar] { ::nx::core::methodproperty Object $cmd protected 1 } + foreach cmd [list recreate] { ::nx::core::methodproperty Class $cmd protected 1 } @@ -70,6 +72,31 @@ ::nx::core::methodproperty Class create redefine-protected true # define method "method" for Class and Object + + # @method ::nx::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 + ::nx::core::method Class method { name arguments body -precondition -postcondition } { @@ -79,6 +106,27 @@ ::nx::core::method [::nx::core::current object] $name $arguments $body {*}$conditions } + # @method ::nx::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 ::nx::core::method Object method { name arguments body -precondition -postcondition } { @@ -156,7 +204,92 @@ } # define forward methods + + # @method ::nx::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 ::nx::core::forward Object forward ::nx::core::forward %self -per-object + + # @method ::nx::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 ::nx::core::forward Class forward ::nx::core::forward %self # The method __unknown is called in cases, where we try to resolve @@ -356,12 +489,27 @@ return [::nx::core::cmd::${info}::method $target name $name] } + # @object ::nx::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 + # {{@object ::nx::Object}} or {{@object ::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::object::nx::Object ::nx::MetaSlot create ::nx::Slot - ::nx::MetaSlot create ::nx::ObjectParameterSlot - ::nx::core::relation ::nx::ObjectParameterSlot superclass ::nx::Slot + # @object ::nx::ObjectParameterSlot # - # create class and object for method parameter slots + # @superclass ::nx::doc::entities::object::nx::Slot + ::nx::MetaSlot create ::nx::ObjectParameterSlot + ::nx::core::relation ::nx::ObjectParameterSlot superclass ::nx::Slot + ::nx::MetaSlot create ::nx::MethodParameterSlot ::nx::core::relation ::nx::MethodParameterSlot superclass ::nx::Slot @@ -414,6 +562,27 @@ ############################################ # Define slots for slots ############################################ + + # @param ::nx::Slot#name + # + # Name of the slot which can be used to access the slot from an object + + # @param ::nx::Slot#multivalued + # + # Boolean value for specifying single or multiple values (lists) + + # @param ::nx::Slot#required + # + # Denotes whether a value must be provided + + # @param ::nx::Slot#default + # + # Allows you to define a default value (to be set upon object creation) + + # @param ::nx::Slot#type + # + # You may specify a type constraint on the value range to managed by the slot + createBootstrapAttributeSlots ::nx::Slot { {name} {multivalued false} @@ -422,6 +591,34 @@ type } + # @param ::nx::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. + + # @param ::nx::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. + + # @param ::nx::ObjectParameterSlot#domain + # + # The domain (object or class) of a slot on which it can be used + + # @param ::nx::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. + + # @param ::nx::ObjectParameterSlot#manager + # + # The manager object of the slot (per default, the slot object takes + # this role, i.e. {{{[self]}}}) + + # @param ::nx::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 [::nx::core::current object]]"} {methodname} @@ -593,6 +790,7 @@ return $parameterdefinitions } + # @method ::nx::Object#objectparameter ::nx::Object protected method objectparameter {{lastparameter __initcmd:initcmd,optional}} { #puts stderr "... objectparameter [::nx::core::current object]" set parameterdefinitions [::nx::core::parametersFromSlots [::nx::core::current object]] @@ -682,16 +880,69 @@ proc ::nx::core::register_system_slots {os} { ${os}::Object alloc ${os}::Class::slot ${os}::Object alloc ${os}::Object::slot - + + # @param ::nx::Class#superclass + # + # Specifies superclasses for a given class. As a setter, + # {{{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 ::nx::core::alias ${os}::Class::slot::superclass assign ::nx::core::relation + + # @param ::nx::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 ::nx::core::alias ${os}::Object::slot::class assign ::nx::core::relation - + + # @param ::nx::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 + + # @param ::nx::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 "" + # @param ::nx::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 + + # @param ::nx::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 @@ -707,6 +958,29 @@ # Attribute slots ############################################ ::nx::MetaSlot __invalidateobjectparameter + + # @object ::nx::Attribute + # + # Attribute slots are used to manage the access, mutation, and + # querying of instance variables. There is a helper method {{@method + # ::nx::Object class attribute}} to define the attributes of classes + # (and objects). Consider the example of a class definition with + # three attribute slots: + # {{{ + # Class create Person { + # :attribute name + # :attribute {salary 0} + # :attribute {projects ""} { + # set :multivalued true + # } + # } + # }}} + # + # @param incremental Allows for using the fine-grained modification (i.e., setting) of the managed variable {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::object::nx::ObjectParameterSlot ::nx::MetaSlot create ::nx::Attribute -superclass ::nx::ObjectParameterSlot createBootstrapAttributeSlots ::nx::Attribute { Index: library/lib/doc-assets/ac-js =================================================================== diff -u -r2c490ff6c40c296798a08edce62d5cea6cb968ea -rbb58b68431fe35dd6ff16e69044705e1246d0dda --- library/lib/doc-assets/ac-js (.../ac-js) (revision 2c490ff6c40c296798a08edce62d5cea6cb968ea) +++ library/lib/doc-assets/ac-js (.../ac-js) (revision bb58b68431fe35dd6ff16e69044705e1246d0dda) @@ -49,7 +49,7 @@ return checked; }; - var els = ['show_private'], + var els = ['show_protected'], reapplyHash = false; for (var i = 0; i < els.length; i++) { Index: library/lib/doc-assets/command.html.tmpl =================================================================== diff -u -r5dcd186af36657d206cc32709e40b8d681ce1d0e -rbb58b68431fe35dd6ff16e69044705e1246d0dda --- library/lib/doc-assets/command.html.tmpl (.../command.html.tmpl) (revision 5dcd186af36657d206cc32709e40b8d681ce1d0e) +++ library/lib/doc-assets/command.html.tmpl (.../command.html.tmpl) (revision bb58b68431fe35dd6ff16e69044705e1246d0dda) @@ -19,31 +19,35 @@
[:? {[$sub exists @return] && [[$sub @return] spec] ne ""} {<[[$sub @return] spec]>} ]
+ ${:name}
+ [$sub name]
+ [$sub parameters]
+
[$param name]
- <[:? {[$param exists spec]} {[$param spec]}]>
+ [:? {[$param exists spec] && [$param spec] ne ""} {<[$param spec]>}]
[$param text]