Index: generic/gentclAPI.decls
===================================================================
diff -u -ra47d62c39a33a69e4550eab30369560d56baf574 -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- generic/gentclAPI.decls (.../gentclAPI.decls) (revision a47d62c39a33a69e4550eab30369560d56baf574)
+++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -4,18 +4,6 @@
# same directory. It is also used by the nx::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 "::nsf"
@@ -45,71 +33,6 @@
{-argName "arg" -required 0 -type tclobj}
}
-# @command ::nsf::configure
-#
-# A top-level configuration facility which allows you modify
-# properties of the "Next" object system for the scope of an entire
-# {{{interp}}}.
-
-# @subcommand ::nsf::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 ::nsf::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 ::nsf::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":
-#
-# {{{
-# ::nsf::configure objectsystems; # returns "::nx::Object ::nx::Class"
-# }}}
-#
-# @return The active pair of root class and root meta-class
-
-# @subcommand ::nsf::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}
@@ -195,22 +118,6 @@
{-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}
@@ -241,31 +148,6 @@
{-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 setvar XOTclSetVarCmd {
{-argName "object" -required 1 -type object}
{-argName "variable" -required 1 -type tclobj}
@@ -277,182 +159,35 @@
{-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
-#
-# TODO: this is a method not used in the Next Scripting Langauge. This
-# mehtod is just called via recreate, so everything necessary can be
-# performed there as well. However, it is available for backward
-# compatibility available in XOTcl 2.0
-#
-# 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
-# ::nsf::configure}}, object variables are deleted, per-object
-# namespaces are cleared, and the object's relationsships (e.g., mixin
-# relations) are reset.
-#
-# @properties interally-called
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.
-#
-# @properties interally-called
-# @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 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.
-#
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#filterguard
-#
-# Adds conditions to guard invocations of a filter. The
-# filter will only execute, if the guards evaluate to true. Otherwise,
-# the guarded filter is ignored. If no guards are given,
-# 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}
@@ -462,100 +197,27 @@
# {-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
-#
-# @properties interally-called
-# @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}
}
@@ -589,122 +251,19 @@
# 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}}}.
-#
-# @properties interally-called
-# @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.
-#
-# @properties interally-called
-# @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. {{{::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}}.
classMethod new XOTclCNewMethod {
{-argName "-childof" -type object -nrargs 1}
{-argName "args" -required 0 -type args}
@@ -718,40 +277,6 @@
{-argName "guard" -required 1 -type tclobj}
}
-# @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, ...)
-# }}}
-#
-# @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
classMethod recreate XOTclCRecreateMethod {
{-argName "name" -required 1 -type tclobj}
{-argName "args" -type allargs}
Index: generic/predefined.tcl
===================================================================
diff -u -r6a0e62b53f8b405d11f009e3c0acb2098702d921 -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- generic/predefined.tcl (.../predefined.tcl) (revision 6a0e62b53f8b405d11f009e3c0acb2098702d921)
+++ generic/predefined.tcl (.../predefined.tcl) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -1,20 +1,268 @@
namespace eval ::nsf {
-
#
# get frequenly used primitiva into the ::nsf namespace
#
# 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.
+ #
+ # @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}}.
+
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}}}.
+
+ # @subcommand 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 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 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
+
+ # @subcommand 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]} {
@@ -38,6 +286,11 @@
#
# 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"
@@ -83,6 +336,11 @@
#
# 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/api.css
===================================================================
diff -u -r783648c4c7132adc4a447faa69d6e4e12b621c46 -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- library/lib/doc-assets/api.css (.../api.css) (revision 783648c4c7132adc4a447faa69d6e4e12b621c46)
+++ library/lib/doc-assets/api.css (.../api.css) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -105,6 +105,9 @@
#doc3 .section.details .description dt { font-weight: bold; }
#doc3 .section.details .description td { border:1px solid #ccc; margin:2px;padding:2px;}
+#doc3 .members { padding:10px; border:1px solid #98AAB1; }
+#doc3 .members h4 { font-size: 100%;}
+
#doc3 .inheritance { padding:10px; background-color:#ECF0F6; border:1px solid #98AAB1; }
#doc3 .inheritance h4 { font-size: 100%;}
Index: library/lib/doc-assets/command.html.tmpl
===================================================================
diff -u -r8aaec98df564488dc8540cd078d6a32dd55a08f7 -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- library/lib/doc-assets/command.html.tmpl (.../command.html.tmpl) (revision 8aaec98df564488dc8540cd078d6a32dd55a08f7)
+++ library/lib/doc-assets/command.html.tmpl (.../command.html.tmpl) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -13,10 +13,26 @@
Subcommands
+
+
+
+ [:for sub ${:@subcommand} {
+
+ [$sub name]
+
+ }]
+
+
+
+
[:for sub ${:@subcommand} {
-
[$sub name]
+
[:? {[$sub eval {info exists :@return}] && [[$sub @return] spec] ne ""} {<[[$sub @return] spec]>} ]
Index: library/lib/doc-assets/entity.html.tmpl
===================================================================
diff -u -r89b5047e54e47a88a7de75d8523a07ffa5743407 -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- library/lib/doc-assets/entity.html.tmpl (.../entity.html.tmpl) (revision 89b5047e54e47a88a7de75d8523a07ffa5743407)
+++ library/lib/doc-assets/entity.html.tmpl (.../entity.html.tmpl) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -55,14 +55,14 @@
This is the API documentation for the
[:name] project.
-
Choose a package or object name from the list for more information.
+
Choose a package, object or command name from the list for more information.
}]
- [:?var packages {
+ [:? {$packages ne ""} {
}]
- [:?var objects {
+ [:? {$objects ne ""} {
}]
- [:?var commands {
+ [:? {$commands ne ""} {
Commands
Index: library/lib/doc-tools.tcl
===================================================================
diff -u -r8534d945b2e3a053018e880336a59a6be68a9d4b -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision 8534d945b2e3a053018e880336a59a6be68a9d4b)
+++ library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -186,6 +186,13 @@
:attribute {root_namespace "::nx::doc::entities"}
namespace eval ::nx::doc::entities {}
+
+ :method get_fully_qualified_name {name} {
+ if {![string match "::*" $name]} {
+ error "You need to provide a fully-qualified (absolute) entity name for '$name'."
+ }
+ return $name
+ }
# @method id
#
@@ -199,7 +206,9 @@
# @see root_namespace
:method id {name} {
set subns [string trimleft [namespace tail [current]] @]
- return [:root_namespace]::${subns}::[string trimleft $name :]
+ #return [:root_namespace]::${subns}::[string trimleft $name :]
+ puts stderr "[current callingproc] -> [:root_namespace]::${subns}[:get_fully_qualified_name $name]"
+ return "[:root_namespace]::${subns}[:get_fully_qualified_name $name]"
}
:method new {-name:required args} {
@@ -209,10 +218,12 @@
#
# @param name The of the documented entity
# @return The identifier of the newly generated or resolved entity object
- :createOrConfigure [:id $name] -name $name {*}$args
+ set fq_name [:get_fully_qualified_name $name]
+ :createOrConfigure [:id $name] -name $fq_name {*}$args
}
:method createOrConfigure {id args} {
+ puts stderr "createOrConfigure id $id"
# This method handles verifies whether an entity object based on
# the given id exists. If so, it returns the resolved name. If
# not, it provides for generating an object with the precomputed
@@ -245,6 +256,7 @@
# ::Foo class foo
set subns [string trimleft [namespace tail [current]] @]
set partof_name [string trimleft $partof_object :]
+ # puts stderr "ID -> [join [list [:root_namespace] $subns $partof_name $scope $name] ::]"
return [join [list [:root_namespace] $subns $partof_name $scope $name] ::]
}
:method new {
@@ -257,8 +269,8 @@
-name
args
} {
-
- :createOrConfigure [:id [$partof name] [$part_attribute scope] $name] {*}[current args]
+ puts stderr "+++ PART [current args]"
+ :createOrConfigure [:id [:get_fully_qualified_name [$partof name]] [$part_attribute scope] $name] {*}[current args]
}
}
@@ -410,11 +422,78 @@
}
- EntityClass create @project -superclass Entity {
+ Class create ContainerEntity -superclass Entity {
+
+ Class create [current]::Resolvable {
+ :object attribute container:object,type=[:info parent]
+ :method get_fully_qualified_name {name} {
+ set container [[current class] container]
+ if {![string match "::*" $name]} {
+ # puts -nonewline stderr "--- EXPANDING name $name"
+ set name [$container namespace]::[string trimleft $name :]
+ # puts stderr " to name $name"
+ }
+ next $name
+ }
+ }
+
+ Class create [current]::Containable {
+ # TODO: check the interaction of required, per-object attribute and ::nsf::assertion
+ #:object attribute container:object,type=[:info parent],required
+ :object attribute container:object,type=[:info parent]
+ :method init args {
+ #
+ # Note: preserve the container currently set at this callstack
+ # level. [next] will cause the container to change if another
+ # container entity is initialised in the following!
+ #
+ set container [[current class] container]
+ next
+ puts stderr "--- entity [current] starts living, register with $container"
+ $container register [current]
+ }
+ }
+ # Note: The default "" corresponds to the top-level namespace "::"!
+ :attribute {namespace ""}
+
+ :attribute @class -slotclass ::nx::doc::PartAttribute {
+ set :part_class @class
+ }
+ :attribute @object -slotclass ::nx::doc::PartAttribute {
+ set :part_class @object
+ }
+ :attribute @command -slotclass ::nx::doc::PartAttribute {
+ set :part_class @command
+ }
+
+ :method init {} {
+ next
+ puts stderr "APPLYING Resolvable container [current]"
+ EntityClass mixin add [current class]::Resolvable
+ [current class]::Resolvable container [current]
+ puts stderr "APPLYING Containable container [current]"
+ Entity mixin add [current class]::Containable
+ [current class]::Containable container [current]
+ }
+
+ :method register {containable:object,type=::nx::doc::Entity} {
+ set tag [[$containable info class] tag]
+ puts stderr "REGISTERING: tag $tag containable $containable on [current]"
+ if {[:info callable methods -application "@$tag"] ne ""} {
+ :@$tag $containable
+ }
+ }
+ }
+
+ EntityClass create @project -superclass ContainerEntity {
:attribute url
:attribute license
:attribute creationdate
:attribute {version ""}
+
+ :attribute @package -slotclass ::nx::doc::PartAttribute {
+ set :part_class @package
+ }
}
#
@@ -435,7 +514,7 @@
# - ...
#
- EntityClass create @package -superclass Entity {
+ EntityClass create @package -superclass ContainerEntity {
:attribute @require -slotclass ::nx::doc::PartAttribute
:attribute @version -slotclass ::nx::doc::PartAttribute
}
@@ -472,43 +551,18 @@
EntityClass create @object \
-superclass Entity {
- :attribute @superclass -slotclass ::nx::doc::PartAttribute
:attribute @author -slotclass ::nx::doc::PartAttribute
- :attribute @method -slotclass ::nx::doc::PartAttribute {
- set :part_class @method
- :method require_part {domain prop value} {
- # TODO: verify whether these scoping checks are sufficient
- # and/or generalisable: For instance, is the scope
- # requested (from the part_attribute) applicable to the
- # partof object, which is the object behind [$domain name]?
- if {[info exists :scope] &&
- ![::nsf::objectproperty [$domain name] ${:scope}]} {
- error "The object '[$domain name]' does not qualify as '[$part_attribute scope]'"
- }
- next
- }
- }
+
+ :forward @method %self @object-method
:attribute @object-method -slotclass ::nx::doc::PartAttribute {
set :part_class @method
}
- :attribute @param -slotclass ::nx::doc::PartAttribute {
+
+ :forward @param %self @object-param
+ :attribute @object-param -slotclass ::nx::doc::PartAttribute {
set :part_class @param
}
- :method inherited {member} {
- if {[${:name} info is class]} {
- set inherited [dict create]
- foreach c [lreverse [${:name} info heritage]] {
- set entity [[::nsf::current class] id $c]
- if {![::nsf::is $entity object]} continue
- if {[$entity eval [list info exists :${member}]]} {
- dict set inherited $entity [$entity $member]
- }
- }
- return $inherited
- }
- }
-
:method undocumented {} {
# TODO: for object methods and class methods
if {![::nsf::objectproperty ${:name} object]} {return ""}
@@ -523,6 +577,45 @@
}
}
+ EntityClass create @class -superclass @object {
+ :attribute @superclass -slotclass ::nx::doc::PartAttribute
+
+ :forward @param %self @class-param
+ :attribute @class-param -slotclass ::nx::doc::PartAttribute {
+ set :part_class @param
+ }
+
+ :forward @method %self @class-method
+ :attribute @class-method -slotclass ::nx::doc::PartAttribute {
+ set :part_class @method
+ :method require_part {domain prop value} {
+ # TODO: verify whether these scoping checks are sufficient
+ # and/or generalisable: For instance, is the scope
+ # requested (from the part_attribute) applicable to the
+ # partof object, which is the object behind [$domain name]?
+ if {[info exists :scope] &&
+ ![::nsf::objectproperty [$domain name] ${:scope}]} {
+ error "The object '[$domain name]' does not qualify as '[$part_attribute scope]'"
+ }
+ next
+ }
+ }
+
+ :method inherited {member} {
+ if {[${:name} info is class]} {
+ set inherited [dict create]
+ foreach c [lreverse [${:name} info heritage]] {
+ set entity [[::nsf::current class] id $c]
+ if {![::nsf::is $entity object]} continue
+ if {[$entity eval [list info exists :${member}]]} {
+ dict set inherited $entity [$entity $member]
+ }
+ }
+ return $inherited
+ }
+ }
+ }
+
# @object ::nx::doc::Part
#
@@ -704,8 +797,8 @@
}
}
- namespace export CommentBlockParser @command @object @method @param \
- @param @package @ Exception StyleViolation InvalidTag \
+ namespace export CommentBlockParser @command @object @class @package @project @method \
+ @param @ Exception StyleViolation InvalidTag \
MissingPartofEntity ExceptionClass
}
@@ -783,7 +876,7 @@
}
#
- # TODO: This should make turn into a hook, the output
+ # TODO: This should turn into a hook, the output
# specificities should move in a refinement of TemplateData, e.g.,
# DefaultHtmlTemplateData or the like.
#
@@ -828,6 +921,21 @@
}
}
}
+ } elseif {[:info is type ::nx::doc::@command]} {
+ set features @subcommand
+ foreach feature $features {
+ if {[info exists :$feature]} {
+ set instances [sorted [set :$feature] name]
+ foreach inst $instances {
+ set access ""
+ set host ${:name}
+ set name [$inst name]
+ set url "[:filename].html#[$feature tag]_[$inst name]"
+ set type [$feature tag]
+ lappend entries [subst $entry]
+ }
+ }
+ }
}
return "\[[join $entries ,\n]\]"
}
@@ -1018,7 +1126,8 @@
# 1) in-situ processing: a class object
if {[::nsf::objectproperty $thing object]} {
if {[$thing eval {info exists :__initcmd}]} {
- :analyze_initcmd @object $thing [$thing eval {set :__initcmd}]
+
+ :analyze_initcmd [expr {[::nsf::objectproperty $thing class]?"@class":"@object"}] $thing [$thing eval {set :__initcmd}]
}
} elseif {![catch {package present $thing} msg]} {
# For tcl packages, we assume that the package is sourceable
@@ -1121,9 +1230,18 @@
foreach addition $additions {
# TODO: for now, we skip over pure Tcl commands and procs
if {![::nsf::is $addition object]} continue;
+ set kind [expr {[::nsf::is $addition class]?"@class":"@object"}]
#puts stderr "ADDITION :process [namespace origin $addition]"
- #:process [namespace origin $addition]
- ::nx::doc::CommentBlockParser process=@object $addition
+ if {[$addition eval {info exists :__initcmd}]} {
+ :analyze_initcmd $kind $addition [$addition eval {set :__initcmd}]
+ }
+
+ # TODO: Note, the CommentBlockParser should operate on the
+ # level of a single block, not entire initcmd and method body
+ # scripts. The process=@object ressembles some ::nx::doc
+ # methods, so relocated and call the parser from within.
+ set entity [@ $kind $addition]
+ ::nx::doc::CommentBlockParser process=$kind $entity
}
}
@@ -1284,30 +1402,35 @@
{-renderer ::nx::doc::HtmlRenderer}
{-outdir /tmp/}
{-tmpl entity.html.tmpl}
- {-project {url http://www.next-scripting.org/ name Next}}
+ {-project:object,type=::nx::doc::@project}
} {
- array set prj $project
- set project [@project new -name $prj(name) -url $prj(url) -version $prj(version)]
Entity mixin add $renderer
- # TODO: why the manual hack instead of "file extension"?
+ # GN: why the manual hack instead of "file extension"?
+ # SS: Because I use the name of the template file to denote the
+ # file extension of the output file which is not *.tmpl, but
+ # rather: *.html.tmpl -> *.html. [file extension] just returns
+ # the trailing extension.
set ext [lindex [split [file tail $tmpl] .] end-1]
set entities [concat [sorted [@package info instances] name] \
[sorted [@command info instances] name] \
[sorted [@object info instances] name]]
set init [subst -nocommands {
set project $project
}]
-
- if {![catch {file mkdir [file join $outdir [$project name]]} msg]} {
- puts stderr [list file copy -force -- [$renderer find_asset_path] [file join $outdir [$project name]]/assets]
- file copy -force -- [$renderer find_asset_path] [file join $outdir [$project name]]/assets
+ set project_path [file join $outdir [string trimleft [$project name] :]]
+ if {![catch {file mkdir $project_path} msg]} {
+ # puts stderr [list file copy -force -- [$renderer find_asset_path] $project_path/assets]
+ set assets [lsearch -all -inline -glob -not [glob -directory [$renderer find_asset_path] *] *.tmpl]
+ set target $project_path/assets
+ file mkdir $target
+ file copy -force -- {*}$assets $target
set index [$project render -initscript $init $tmpl]
- puts stderr "we have [llength $entities] documentation entities ($entities)"
- :write $index [file join $outdir [$project name] "index.$ext"]
+ # puts stderr "we have [llength $entities] documentation entities ($entities)"
+ :write $index [file join $project_path "index.$ext"]
foreach e $entities {
set content [$e render -initscript $init $tmpl]
- :write $content [file join $outdir [$project name] "[$e filename].$ext"]
- puts stderr "$e written to [file join $outdir [$project name] [$e filename].$ext]"
+ :write $content [file join $project_path "[$e filename].$ext"]
+ puts stderr "$e written to [file join $project_path [$e filename].$ext]"
}
}
@@ -1398,8 +1521,9 @@
set failure ""
#
- # Note: Within the while-loop, two object variables constantly change (as "wanted" side-effects):
- # processed_section: reflects the currently processed comment section; see event=next()
+ # Note: Within the while-loop, two object variables constantly
+ # change (as "wanted" side-effects): processed_section: reflects
+ # the currently processed comment section; see event=next()
# current_entity: reflects the currently documentation entity
# (once resolved); see context->event=parse@tag()
#
@@ -1413,7 +1537,7 @@
if {[catch {
set actions [${:current_entity} event=process $line]
} failure]} {
- #puts stderr ERRORINFO=$::errorInfo
+ puts stderr ERRORINFO=$::errorInfo
:fastforward
}
}
@@ -1430,36 +1554,34 @@
# TODO: how can I obtain some reuse here when later @class is
# distinguished from @object (dispatch along the inheritance
# hierarchy?)
- :object method process=@object {name} {
- set object_entity [@ @object $name]
- if {![::nsf::is $name object]} return;
-
+ :object method process=@class {entity} {
+ set name [$entity name]
+ foreach methodName [${name} info methods -methodtype scripted] {
+ # TODO: should the comment_blocks parser relocated?
+ set blocks [doc comment_blocks [${name} info method \
+ body $methodName]]
+ foreach {line_offset block} $blocks {
+ if {$line_offset > 1} break;
+ set id [$entity @class-method $methodName]
+ :process \
+ -partof_entity $entity \
+ -initial_section description \
+ -entity $id \
+ $block
+ }
+ :process=@object $entity object
+ }
+ }
+
+ :object method process=@object {entity {scope ""}} {
+ set name [$entity name]
#
# process the initcmd !
#
-
- if {[$name eval {info exists :__initcmd}]} {
- doc analyze_initcmd @object $name [$name eval {set :__initcmd}]
- }
- set scope ""
- if {[$name info is class]} {
- set scope object
- foreach methodName [${name} info methods -methodtype scripted] {
- # TODO: should the comment_blocks parser relocated?
- set blocks [doc comment_blocks [${name} info method \
- body $methodName]]
- foreach {line_offset block} $blocks {
- if {$line_offset > 1} break;
- set id [$object_entity @method $methodName]
- :process \
- -partof_entity $object_entity \
- -initial_section description \
- -entity $id \
- $block
- }
- }
- }
+ # if {[$name eval {info exists :__initcmd}]} {
+ # doc analyze_initcmd @object $name [$name eval {set :__initcmd}]
+ # }
foreach methodName [${name} {*}$scope info methods\
-methodtype scripted] {
@@ -1468,26 +1590,26 @@
body $methodName]]
foreach {line_offset block} $blocks {
if {$line_offset > 1} break;
- set id [$object_entity @object-method $methodName]
+ set id [$entity @object-method $methodName]
:process \
- -partof_entity $object_entity \
+ -partof_entity $name \
-initial_section description \
-entity $id \
$block
}
}
}
# :method process=@method args {method_entity} {
-
+
# }
-
+
}
-
+
Class create CommentBlockParsingState -superclass Class {
-
+
:attribute next_comment_section
:attribute comment_line_transitions:required
-
+
}
Class create CommentSection {
@@ -1645,7 +1767,7 @@
# TODO: Currently, I only foresee @object and @command as
# possible qualifiers; however, this should be fixed asap, as
# soon as the variety of entities has been decided upon!
- foreach entity_type {@object @command} {
+ foreach entity_type {@class @command @object} {
set partof_entity [$entity_type id $qualifier]
# TODO: Also, we expect the qualifier to resolve against an
# already existing entity object? Is this intended?
Index: library/nx/nx.tcl
===================================================================
diff -u -ra47d62c39a33a69e4550eab30369560d56baf574 -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- library/nx/nx.tcl (.../nx.tcl) (revision a47d62c39a33a69e4550eab30369560d56baf574)
+++ library/nx/nx.tcl (.../nx.tcl) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -1,3 +1,15 @@
+# @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 {{@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
+
package provide nx 2.0
package require nsf
@@ -11,6 +23,143 @@
#
# First create the ::nx object system.
#
+
+ # @object ::nx::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.
+
+ # @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}}}.
+ #
+ # @properties interally-called
+ # @param name The object identifier assigned to the object storage to be allocated.
+ # @return The name of the allocated, uninitialized object
+
+ # @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.
+
+ # @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.
+ #
+ # @properties interally-called
+ # @param object The name of the object to be scheduled for deletion.
+
+ # @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, ...)
+ # }}}
+ #
+ # @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
+
+ # @method ::nx::Object#residualargs
+ #
+ # @properties interally-called
+ # @param args
::nsf::createobjectsystem ::nx::Object ::nx::Class {
-class.alloc alloc
-class.create create
@@ -31,6 +180,15 @@
# get frequenly used primitiva from the next scripting framework
#
namespace eval ::nsf {}
+
+ # @command ::nx::next
+ #
+ # @use ::nsf::command
+
+ # @command ::nx::current
+ #
+ # @use ::nsf::current
+
namespace import ::nsf::next ::nsf::current
#
@@ -42,9 +200,115 @@
::nsf::alias Object $cmdName $cmd
}
+ # @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.
+ #
+ # @properties interally-called
+ # @param args The variable argument vector stores the object parameters and their values
+
+ # @method ::nx::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.
+ #
+
+ # @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
+
+ # @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 ...
+
+ # @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.
+
# provide ::eval as method for ::nx::Object
::nsf::alias Object eval -nonleaf ::eval
+ #
+ # class methods
+ #
+
+ # @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. {{{::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]
Index: library/xotcl/library/xotcl2.tcl
===================================================================
diff -u -ra47d62c39a33a69e4550eab30369560d56baf574 -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- library/xotcl/library/xotcl2.tcl (.../xotcl2.tcl) (revision a47d62c39a33a69e4550eab30369560d56baf574)
+++ library/xotcl/library/xotcl2.tcl (.../xotcl2.tcl) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -61,13 +61,146 @@
}
}
+ # @object ::xotcl::Object
+ #
+ # Xotcl programs are constructed out of objects. This class
+ # describes common structural and behavioural features for all XOTcl
+ # objects. It is the root object-class in the XOTcl 2 object system.
+
# provide the standard command set for ::xotcl::Object
foreach cmd [info command ::nsf::cmd::Object::*] {
set cmdName [namespace tail $cmd]
if {$cmdName in [list "setter"]} continue
::nsf::alias Object $cmdName $cmd
}
+ #
+ # object methods
+ #
+
+ # @method ::xotcl::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
+
+ # @method ::xotcl::Object#cleanup
+ #
+ # TODO: this is a method not used in the Next Scripting Langauge. This
+ # mehtod is just called via recreate, so everything necessary can be
+ # performed there as well. However, it is available for backward
+ # compatibility available in XOTcl 2.0
+ #
+ # Resets an object or class to its initial state, as after object
+ # allocation (see {{@method ::xotcl::Class class alloc}}). This method
+ # participates in recreating objects, i.e, it is called during the
+ # recreation process by {{@method ::xotcl::Class class recreate}}.
+ # Depending on the recreation scheme applied (see {{@command
+ # ::nsf::configure}}, object variables are deleted, per-object
+ # namespaces are cleared, and the object's relationsships (e.g., mixin
+ # relations) are reset.
+ #
+ # @properties interally-called
+
+ # @method ::xotcl::Object#destroy
+ #
+ # @use ::xotcl::Object#destroy
+
+ # @method ::xotcl::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
+
+ # @method ::xotcl::Object#instvar
+ #
+ # @param args
+
+ # @method ::xotcl::Object#noinit
+ #
+ # Calling upon this method during object construction allows you to
+ # bypass the constructor method:
+ # {{{
+ # Class create C
+ # C instproc init {} {puts stderr "A class-specific constructor shouts out ..."}
+ # C c1 -noinit
+ # }}}
+ # This bypassing feature comes handy when streaming an object into a
+ # scripted form (e.g., by using the bundled Serializer). Upon
+ # deserializing the object, using the {{{noinit}}} flag helps you to
+ # preserve the serialized object state (rather then having the
+ # object re-initialized).
+
+ # @method ::xotcl::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
+ # }}}
+
+ # @method ::xotcl::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.
+
# provide some Tcl-commands as methods for ::xotcl::Object
foreach cmd {array append eval incr lappend set subst unset trace} {
::nsf::alias Object $cmd -objscope ::$cmd
@@ -460,7 +593,16 @@
::nsf::alias Class filterguard ::nsf::cmd::Object::filterguard
::nsf::alias Class instfilterguard ::nsf::cmd::Class::filterguard
+ # @method ::xotcl::Class#mixinguard
+ #
+ # @param mixin
+ # @param guard
::nsf::alias Class mixinguard ::nsf::cmd::Object::mixinguard
+
+ # @method ::nx::Class#instmixinguard
+ #
+ # @param mixin
+ # @param guard
::nsf::alias Class instmixinguard ::nsf::cmd::Class::mixinguard
# assertion handling
@@ -548,6 +690,15 @@
if {[::nsf::is [self] object -hasmixin $cl]} {return 1}
::nsf::is [self] type $cl
}
+
+ # @method ::nx::Object#filtersearch
+ #
+ # Search a fully qualified method name which is currently registered
+ # as a filter.
+ #
+ # @param filter Handle to identify and address a filter once registered
+ # @param guard A list of guard expressions
+ # @return A list in proc qualifier format: 'objName|className proc|instproc methodName'.
Object instproc filtersearch {filter} {
set handle [::nsf::cmd::ObjectInfo::callable [self] filter $filter]
return [method_handle_to_xotcl $handle]
Index: tests/doc.tcl
===================================================================
diff -u -r99168631019313a366696cb78384abaf48d488e7 -r6458c13882afd52e8719ee0e0e054b42e9aee696
--- tests/doc.tcl (.../doc.tcl) (revision 99168631019313a366696cb78384abaf48d488e7)
+++ tests/doc.tcl (.../doc.tcl) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696)
@@ -126,7 +126,7 @@
# TODO: Add tests for doc-parsing state machine.
#
set block {
- {@command cc}
+ {@command ::cc}
}
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 0
@@ -145,24 +145,24 @@
set block {
{}
- {@command cc}
+ {@command ::cc}
}
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 1
set block {
- {command cc}
+ {command ::cc}
{}
}
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 1
set block {
- {@command cc}
+ {@command ::cc}
{some description}
}
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 1
set block {
- {@command cc}
+ {@command ::cc}
{}
{}
{}
@@ -172,7 +172,7 @@
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 0
set block {
- {@command cc}
+ {@command ::cc}
{}
{some description}
{some description2}
@@ -184,7 +184,7 @@
# Note: We do allow description blocks with intermediate space
# lines, for now.
set block {
- {@command cc}
+ {@command ::cc}
{}
{some description}
{some description2}
@@ -211,7 +211,7 @@
# Alternatively, we can use the @see like syntax for qualifying:
# @param ::Foo#attr1 (I have a preference for this option).
set block {
- {@command cc}
+ {@command ::cc}
{@see someOtherEntity}
}
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 1
@@ -220,7 +220,7 @@
# TODO: Disallow space lines between parts? Check back with Javadoc spec.
#
set block {
- {@command cc}
+ {@command ::cc}
{}
{@see SomeOtherEntity}
{add a line of description}
@@ -235,7 +235,7 @@
# TODO: Should we enforce a mandatory space line between description and part block?
#
set block {
- {@command cc}
+ {@command ::cc}
{}
{add a line of description}
{a second line of description}
@@ -246,7 +246,7 @@
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 1
set block {
- {@command cc}
+ {@command ::cc}
{}
{add a line of description}
{a second line of description}
@@ -261,7 +261,7 @@
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 1
set block {
- {@command cc}
+ {@command ::cc}
{}
{add a line of description}
{a second line of description}
@@ -273,7 +273,7 @@
? [list StyleViolation thrown_by? [list CommentBlockParser process $block]] 0
set block {
- {@object cc}
+ {@object ::cc}
{}
{add a line of description}
{a second line of description}
@@ -284,7 +284,7 @@
? [list InvalidTag thrown_by? [list CommentBlockParser process $block]] 1
set block {
- {@class cc}
+ {@class ::cc}
{}
{add a line of description}
{a second line of description}
@@ -298,7 +298,7 @@
# testing the doc object construction
#
set block {
- {@object o}
+ {@object ::o}
{}
{some more text}
{and another line for the description}
@@ -313,13 +313,14 @@
? [list $entity text] "some more text and another line for the description";
set block {
- {@command c}
+ {@command ::c}
{}
{some text on the command}
{}
{@see ::o}
}
set entity [CommentBlockParser process $block]
+ puts stderr ENTITY=$entity
? [list ::nsf::is $entity object] 1
? [list $entity info is type ::nx::doc::@command] 1
? [list $entity text] "some text on the command";
@@ -359,9 +360,9 @@
eval $script
doc process ::Foo
- set entity [@object id ::Foo]
+ set entity [@class id ::Foo]
? [list ::nsf::is $entity object] 1
- ? [list $entity info is type ::nx::doc::@object] 1
+ ? [list $entity info is type ::nx::doc::@class] 1
? [list $entity text] "The class Foo defines the behaviour for all Foo objects";
? [list $entity @author] "gustaf.neumann@wu-wien.ac.at ssoberni@wu.ac.at"
# TODO: Fix the [@param id] programming scheme to allow (a) for
@@ -373,7 +374,7 @@
? [list $entity @see] "::nx::Attribute ::nx::MetaSlot";
set entity [@method id ::Foo class foo]
- ? [list [@object id ::Foo] @method] $entity
+ ? [list [@class id ::Foo] @method] $entity
? [list ::nsf::is $entity object] 1
? [list $entity info is type ::nx::doc::@method] 1
? [list $entity text] "This describes the foo method";
@@ -393,28 +394,28 @@
set script {
namespace import -force ::nx::*
- # @object Bar
+ # @class ::Bar
#
# The class Bar defines the behaviour for all Bar objects
#
# @author gustaf.neumann@wu-wien.ac.at
# @author ssoberni@wu.ac.at
- # @param Bar#attr1
+ # @param ::Bar#attr1
#
# This attribute 1 is wonderful
#
# @see ::nx::Attribute
# @see ::nx::MetaSlot
- # @method Bar#foo
+ # @method ::Bar#foo
#
# This describes the foo method
#
# @param a Provides a first value
# @param b Provides a second value
- # @object-method Bar#foo
+ # @object-method ::Bar#foo
#
# This describes the per-object foo method
#
@@ -457,9 +458,9 @@
set i [doc process $script]
- set entity [@object id ::Bar]
+ set entity [@class id ::Bar]
? [list $i eval [list ::nsf::is $entity object]] 1
- ? [list $i eval [list $entity info is type ::nx::doc::@object]] 1
+ ? [list $i eval [list $entity info is type ::nx::doc::@class]] 1
? [list $i eval [list $entity text]] "The class Bar defines the behaviour for all Bar objects";
? [list $i eval [list $entity @author]] "gustaf.neumann@wu-wien.ac.at ssoberni@wu.ac.at"
@@ -472,7 +473,7 @@
? [list $i eval [list $entity @see]] "::nx::Attribute ::nx::MetaSlot";
set entity [@method id ::Bar class foo]
- ? [list $i eval [list [@object id ::Bar] @method]] $entity
+ ? [list $i eval [list [@class id ::Bar] @method]] $entity
? [list $i eval [list ::nsf::is $entity object]] 1
? [list $i eval [list $entity info is type ::nx::doc::@method]] 1
? [list $i eval [list $entity text]] "This describes the foo method in the method body";
@@ -484,7 +485,7 @@
? [list expr [list [$i eval [list $p text]] eq $expected]] 1;
}
set entity [@method id ::Bar object foo]
- ? [list $i eval [list [@object id ::Bar] @object-method]] $entity
+ ? [list $i eval [list [@class id ::Bar] @object-method]] $entity
? [list $i eval [list ::nsf::is $entity object]] 1
? [list $i eval [list $entity info is type ::nx::doc::@method]] 1
? [list $i eval [list $entity text]] "This describes the per-object foo method in the method body";
@@ -526,7 +527,7 @@
#
# core documentation
#
- set path [file join /tmp NextLanguageCore]
+ set path [file join [::nsf::tmpdir] NextScriptingFramework]
if {[file exists $path]} {
file delete -force $path
}
@@ -536,20 +537,51 @@
package req nx::doc
namespace import ::nx::*
namespace import ::nx::doc::*
- puts stderr TIME=[time {
- doc process -noeval true generic/gentclAPI.decls
- doc process -noeval true library/nx/nx.tcl
+
+ # 1) NSF documentation project
+
+ set project [::nx::doc::@project new \
+ -name ::NextScriptingFramework \
+ -url http://www.next-scripting.org/ \
+ -version 1.0.0a \
+ -namespace "::nsf"]
+
+ doc process -noeval true generic/predefined.tcl
+
::nx::doc::make doc \
-renderer ::nx::doc::TemplateData \
- -outdir /tmp \
- -project {name NextLanguageCore url http://www.next-scripting.org/ version 1.0.0a}
- } 1]
+ -outdir [::nsf::tmpdir] \
+ -project $project
}
+
interp delete $i
+
+ set _ {
+ # 2) XOTcl2 documentation project
+ doc process -noeval true library/xotcl/xotcl.tcl
+ ::nx::doc::make doc \
+ -renderer ::nx::doc::TemplateData \
+ -outdir [::nsf::tmpdir] \
+ -project {name XOTcl2 url http://www.xotcl.org/ version 2.0.0a}
+
+ # 3) NSL documentation project
+ doc process -noeval true library/nx/nx.tcl
+ ::nx::doc::make doc \
+ -renderer ::nx::doc::TemplateData \
+ -outdir [::nsf::tmpdir] \
+ -project {name NextScriptingLanguage url http://www.next-scripting.org/ version 1.0.0a}
+
+ # 4) Next Scripting Libraries
+ # doc process -noeval true ...
+ # ::nx::doc::make doc \
+ # -renderer ::nx::doc::TemplateData \
+ # -outdir [::nsf::tmpdir] \
+ # -project {name NextScriptingLibraries url http://www.next-scripting.org/ version 1.0.0a}
+ }
+
}
-
# # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # #