Index: generic/nsf.c =================================================================== diff -u -r2e7f0b2256363d70c78778c9ed401f9450622a6a -rfd3666742ed34091dbb93a872fe1d34d6b66ad9d --- generic/nsf.c (.../nsf.c) (revision 2e7f0b2256363d70c78778c9ed401f9450622a6a) +++ generic/nsf.c (.../nsf.c) (revision fd3666742ed34091dbb93a872fe1d34d6b66ad9d) @@ -3109,9 +3109,9 @@ } else { /* * In most situations, we have a varTablePtr through the clauses - * above. However, if someone redefines e.g. the method - * "configure" or "objectparameter", we might find an object with - * an still empty varTable, since these are lazy initiated. + * above. However, if someone redefines e.g. the method "configure" or + * "objectparameter", we might find an object with an still empty + * varTable, since these are lazy initiated. */ varTablePtr = object->varTablePtr = VarHashTableCreate(); } @@ -3370,9 +3370,9 @@ } else { /* * In most situations, we have a varTablePtr through the clauses - * above. However, if someone redefines e.g. the method - * "configure" or "objectparameter", we might find an object with - * an still empty varTable, since these are lazy initiated. + * above. However, if someone redefines e.g. the method "configure" or + * "objectparameter", we might find an object with an still empty + * varTable, since these are lazy initiated. */ varTablePtr = object->varTablePtr = VarHashTableCreate(); } @@ -7960,6 +7960,9 @@ INCR_REF_COUNT2("paramDefsObj", listObj); for (paramPtr = paramsPtr; paramPtr->name; paramPtr++) { + if (paramPtr->flags & NSF_ARG_NOCONFIG) { + continue; + } if (paramPtr -> paramObj) { innerListObj = paramPtr->paramObj; } else { @@ -8078,7 +8081,9 @@ INCR_REF_COUNT2("paramDefsObj", listObj); for (paramPtr = paramsPtr; paramPtr->name; paramPtr++) { - Tcl_ListObjAppendElement(interp, listObj, paramPtr->nameObj); + if ((paramPtr->flags & NSF_ARG_NOCONFIG) == 0) { + Tcl_ListObjAppendElement(interp, listObj, paramPtr->nameObj); + } } return listObj; } @@ -10356,6 +10361,9 @@ paramPtr->nrArgs = 0; } else if (strncmp(option, "noconfig", 8) == 0) { + if (disallowedOptions != NSF_DISALLOWED_ARG_OBJECT_PARAMETER) { + return NsfPrintError(interp, "Parameter option 'noconfig' only allowed for object parameters"); + } paramPtr->flags |= NSF_ARG_NOCONFIG; } else if (strncmp(option, "args", 4) == 0) { @@ -12536,7 +12544,6 @@ switch (level) { case CALLING_LEVEL: NsfCallStackFindLastInvocation(interp, 1, &framePtr); break; case ACTIVE_LEVEL: NsfCallStackFindActiveFrame(interp, 1, &framePtr); break; - default: framePtr = NULL; } if (framePtr) { @@ -12546,7 +12553,6 @@ buffer[0] = '#'; Nsf_ltoa(buffer+1, (long)Tcl_CallFrame_level(framePtr), &l); - /*fprintf(stderr, "*** framePtr=%p buffer %s\n", framePtr, buffer);*/ resultObj = Tcl_NewStringObj(buffer, l+1); } else { /* If not called from an nsf frame, return 1 as default */ @@ -21057,13 +21063,13 @@ } /* -objectInfoMethod slots NsfObjInfoSlotsMethod { +objectInfoMethod slotobjects NsfObjInfoSlotobjectsMethod { {-argName "-type" -required 0 -nrargs 1 -type class} {-argName "pattern" -required 0} } */ static int -NsfObjInfoSlotsMethod(Tcl_Interp *interp, NsfObject *object, +NsfObjInfoSlotobjectsMethod(Tcl_Interp *interp, NsfObject *object, NsfClass *type, CONST char *pattern) { Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); @@ -21458,7 +21464,7 @@ } if (paramsPtr == parsedParam.paramDefs->paramsPtr) { /* - * The named parameter was NOT found + * The named parameter was NOT found, so return "". */ Tcl_SetObjResult(interp, NsfGlobalObjs[NSF_EMPTY]); return TCL_OK; @@ -21486,15 +21492,15 @@ } /* -classInfoMethod slots NsfClassInfoSlotsMethod { +classInfoMethod slots NsfClassInfoSlotobjectsMethod { {-argName "-closure"} {-argName "-source" -nrargs 1 -type "all|application|baseclasses"} {-argName "-type" -required 0 -nrargs 1 -type class} {-argName "pattern" -required 0} } */ static int -NsfClassInfoSlotsMethod(Tcl_Interp *interp, NsfClass *class, +NsfClassInfoSlotobjectsMethod(Tcl_Interp *interp, NsfClass *class, int withClosure, int withSource, NsfClass *type, CONST char *pattern) { NsfClasses *clPtr, *intrinsic, *precedenceList = NULL; Index: library/lib/doc-tools.tcl =================================================================== diff -u -r96251cd0e203685f1f4cadbf88ccc3ede6146978 -rfd3666742ed34091dbb93a872fe1d34d6b66ad9d --- library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision 96251cd0e203685f1f4cadbf88ccc3ede6146978) +++ library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision fd3666742ed34091dbb93a872fe1d34d6b66ad9d) @@ -131,7 +131,7 @@ Class create MixinLayer { - :attribute {prefix ""} + :property {prefix ""} :public method init {} { set :active_mixins [dict create] next @@ -164,7 +164,7 @@ } Class create [current]::Mixin -superclass Class { - :attribute {scope class} + :property {scope class} } } @@ -180,8 +180,8 @@ # @param root_namespace You may choose your own root-level # namespace hosting the namespace hierarchy of entity objects - :attribute {tag {[string trimleft [string tolower [namespace tail [current]]] @]}} - :attribute {root_namespace "::nx::doc::entities"} + :property {tag {[string trimleft [string tolower [namespace tail [current]]] @]}} + :property {root_namespace "::nx::doc::entities"} namespace eval ::nx::doc::entities {} @@ -414,17 +414,17 @@ # part_class is given, the values will be transformed accordingly # before being pushed into the internal storage. - ::nx::MetaSlot create PartAttribute -superclass ::nx::Attribute { + ::nx::MetaSlot create PartAttribute -superclass ::nx::VariableSlot { # @param part_class # - # The attribute slot refers to a concrete subclass of Part which - # describes the parts being managed by the attribute slot. - :attribute part_class:optional,class - :attribute scope + # The property refers to a concrete subclass of Part which + # describes the parts being managed by the property. + :property part_class:optional,class + :property scope - :attribute {pretty_name {[string totitle [string trimleft [namespace tail [current]] @]]}} - :attribute {pretty_plural {[string totitle [string trimleft [namespace tail [current]] @]]}} + :property {pretty_name {[string totitle [string trimleft [namespace tail [current]] @]]}} + :property {pretty_plural {[string totitle [string trimleft [namespace tail [current]] @]]}} # :forward owning_entity_class {% [[:info parent] info parent] } :method init args { @@ -444,7 +444,7 @@ :public method id {domain prop value} { #puts stderr "PARTATTRIBUTE-ID: [current args]" if {![info exists :part_class]} { - error "Requested id generation from a simple part attribute!" + error "Requested id generation from a simple part property!" } return [${:part_class} id [$domain name] ${:scope} $value] } @@ -491,7 +491,7 @@ } } - ::nx::MetaSlot create SwitchAttribute -superclass ::nx::Attribute { + ::nx::MetaSlot create SwitchAttribute -superclass ::nx::VariableSlot { :public method init args { set :defaultmethods [list get get] next @@ -513,19 +513,19 @@ # @param name # # gives you the name (i.e., the Nx object identifier) of the documented entity - :attribute name:any,required + :property name:any,required # every Entity must be created with a "@doc" value and can have # an optional initcmd #:method objectparameter args { #next [list [list @doc:optional __initcmd:initcmd,optional]] #} - :class attribute current_project:object,type=::nx::doc::@project,0..1 + :class property current_project:object,type=::nx::doc::@project,0..1 :public forward current_project [current] %method - :attribute partof:object,type=::nx::doc::StructuredEntity - :attribute part_attribute:object,type=::nx::doc::PartAttribute + :property partof:object,type=::nx::doc::StructuredEntity + :property part_attribute:object,type=::nx::doc::PartAttribute # # TODO: the pdata/pinfo/validate combo only makes sense for @@ -537,7 +537,7 @@ return ${:name} } - :attribute pdata + :property pdata :public method validate {} { if {[info exists :pdata] && \ [:pinfo get -default complete status] ne "missing"} { @@ -599,31 +599,32 @@ return [concat {*}$path] } - :attribute @doc:0..* { + :property @doc:0..* { set :incremental 1 set :positional true set :position 1 } - :attribute -class ::nx::doc::PartAttribute @see - :attribute -class ::nx::doc::SwitchAttribute @deprecated:boolean { + :property -class ::nx::doc::PartAttribute @see + + :property -class ::nx::doc::SwitchAttribute @deprecated:boolean { set :default 0 } - :attribute -class ::nx::doc::SwitchAttribute @stashed:boolean { + :property -class ::nx::doc::SwitchAttribute @stashed:boolean { set :default 0 } - :attribute -class ::nx::doc::SwitchAttribute @c-implemented:boolean { + :property -class ::nx::doc::SwitchAttribute @c-implemented:boolean { set :default 0 } - # :attribute @properties -class ::nx::doc::PartAttribute + # :property @properties -class ::nx::doc::PartAttribute :public method @property {props} { foreach prop $props { :@$prop } } - :attribute @use { + :property @use { :public method assign {domain prop value} { # @command nx # @@ -701,9 +702,9 @@ } Tag create @glossary -superclass Entity { - :attribute @pretty_name - :attribute @pretty_plural - :attribute @acronym + :property @pretty_name + :property @pretty_plural + :property @acronym } @@ -770,7 +771,7 @@ Class create ContainerEntity -superclass StructuredEntity { Class create [current]::Resolvable { - :class attribute container:object,type=[:info parent] + :class property container:object,type=[:info parent] :method get_fully_qualified_name {name} { set container [[current class] container] if {![string match "::*" $name]} { @@ -783,9 +784,9 @@ } Class create [current]::Containable { - # TODO: check the interaction of required, per-object attribute and ::nsf::assertion - #:object attribute container:object,type=[:info parent],required - :attribute container:object,type=[:info parent] + # TODO: check the interaction of required, per-object property and ::nsf::assertion + #:object property container:object,type=[:info parent],required + :property container:object,type=[:info parent] :method create args { # # Note: preserve the container currently set at this callstack @@ -823,34 +824,35 @@ } # Note: The default "" corresponds to the top-level namespace "::"! - :attribute {@namespace ""} + :property {@namespace ""} - :attribute -class ::nx::doc::PartAttribute @class { + :property -class ::nx::doc::PartAttribute @class { :pretty_name "Class" :pretty_plural "Classes" set :part_class ::nx::doc::@class } - :attribute -class ::nx::doc::PartAttribute @object { + + :property -class ::nx::doc::PartAttribute @object { :pretty_name "Object" :pretty_plural "Objects" set :part_class ::nx::doc::@object } - :attribute -class ::nx::doc::PartAttribute @command { + :property -class ::nx::doc::PartAttribute @command { :pretty_name "Command" :pretty_plural "Commands" set :part_class ::nx::doc::@command } - # :attribute @class:object,type=::nx::doc::@class,multivalued { + # :property @class:object,type=::nx::doc::@class,multivalued { # set :incremental 1 # } - # :attribute @object:object,type=::nx::doc::@object,multivalued { + # :property @object:object,type=::nx::doc::@object,multivalued { # set :incremental 1 # } - # :attribute @command:object,type=::nx::doc::@command,multivalued { + # :property @command:object,type=::nx::doc::@command,multivalued { # set :incremental 1 # } @@ -887,18 +889,18 @@ Tag create @project -superclass ContainerEntity { - :attribute sandbox:object,type=::nx::doc::Sandbox - :attribute sources + :property sandbox:object,type=::nx::doc::Sandbox + :property sources - :attribute url - :attribute license - :attribute creationdate - :attribute {version ""} + :property url + :property license + :property creationdate + :property {version ""} - :attribute {is_validated 0} - :attribute depends:0..*,object,type=[current] + :property {is_validated 0} + :property depends:0..*,object,type=[current] - :attribute -class ::nx::doc::PartAttribute @glossary { + :property -class ::nx::doc::PartAttribute @glossary { set :part_class ::nx::doc::@glossary :public method get {domain prop} { set l [next] @@ -911,7 +913,7 @@ } } - :attribute -class ::nx::doc::PartAttribute @package { + :property -class ::nx::doc::PartAttribute @package { :pretty_name "Package" :pretty_plural "Packages" set :part_class ::nx::doc::@package @@ -960,15 +962,15 @@ # Tag create @package -superclass ContainerEntity { - :attribute -class ::nx::doc::PartAttribute @require - :attribute -class ::nx::doc::PartAttribute @version + :property -class ::nx::doc::PartAttribute @require + :property -class ::nx::doc::PartAttribute @version } QualifierTag create @command -superclass StructuredEntity { - :attribute -class ::nx::doc::PartAttribute @parameter { + :property -class ::nx::doc::PartAttribute @parameter { set :part_class ::nx::doc::@param } - :attribute -class ::nx::doc::PartAttribute @return { + :property -class ::nx::doc::PartAttribute @return { :method require_part {domain prop value} { set value [expr {![string match ":*" $value] ? "__out__: $value": "__out__$value"}] next [list $domain $prop $value] @@ -977,11 +979,12 @@ } :public forward @sub-command %self @command - :attribute -class ::nx::doc::PartAttribute @command { + + :property -class ::nx::doc::PartAttribute @command { :pretty_name "Subcommand" :pretty_plural "Subcommands" :public method id {domain prop value} { - # TODO: [${:part_class}] resolves to the attribute slot + # TODO: [${:part_class}] resolves to the property slot # object, not the global @command object. is this intended, in # line with the intended semantics? return [${:part_class} [current method] \ @@ -1033,15 +1036,17 @@ QualifierTag create @object \ -superclass StructuredEntity \ -mixin ContainerEntity::Containable { - :attribute -class ::nx::doc::PartAttribute @author + :property -class ::nx::doc::PartAttribute @author + :public forward @object %self @child-object - :attribute -class ::nx::doc::PartAttribute @child-object { + + :property -class ::nx::doc::PartAttribute @child-object { set :part_class ::nx::doc::@object :public method id {domain prop value} { # puts stderr "CHILD-OBJECT: [current args]" # if {![info exists :part_class]} { - # error "Requested id generation from a simple part attribute!" + # error "Requested id generation from a simple part property!" # } return [${:part_class} id [join [list [$domain name] $value] ::]] # return [${:part_class} id -partof_name [$domain name] -scope ${:scope} $value] @@ -1050,28 +1055,31 @@ } :public forward @class %self @child-class - :attribute -class ::nx::doc::PartAttribute @child-class { + + :property -class ::nx::doc::PartAttribute @child-class { set :part_class ::nx::doc::@class :public method id {domain prop value} { #puts stderr "CHILD-CLASS: [current args]" # if {![info exists :part_class]} { - # error "Requested id generation from a simple part attribute!" + # error "Requested id generation from a simple part property!" # } return [${:part_class} id [join [list [$domain name] $value] ::]] #return [${:part_class} id -partof_name [$domain name] -scope ${:scope} $value] } } :public forward @method %self @object-method - :attribute -class ::nx::doc::PartAttribute @object-method { + + :property -class ::nx::doc::PartAttribute @object-method { :pretty_name "Object method" :pretty_plural "Object methods" set :part_class ::nx::doc::@method } - :public forward @attribute %self @object-attribute + :public forward @property %self @object-property #:forward @param %self @object-param - :attribute -class ::nx::doc::PartAttribute @object-attribute { + + :property -class ::nx::doc::PartAttribute @object-attribute { set :part_class ::nx::doc::@param } @@ -1091,27 +1099,31 @@ QualifierTag create @class \ -superclass @object { - :attribute -class ::nx::doc::PartAttribute @superclass + + :property -class ::nx::doc::PartAttribute @superclass :public forward @attribute %self @class-attribute - :attribute -class ::nx::doc::PartAttribute @class-attribute { + + :property -class ::nx::doc::PartAttribute @class-attribute { :pretty_name "Per-class attribute" :pretty_plural "Per-class attributes" set :part_class ::nx::doc::@param } :public forward @class-object-method %self @object-method - :public forward @class-object-attribute %self @object-attribute + :public forward @class-object-property %self @object-property :public forward @hook %self @class-hook - :attribute -class ::nx::doc::PartAttribute @class-hook { + + :property -class ::nx::doc::PartAttribute @class-hook { :pretty_name "Hook method" :pretty_plural "Hook methods" set :part_class ::nx::doc::@method } :public forward @method %self @class-method - :attribute -class ::nx::doc::PartAttribute @class-method { + + :property -class ::nx::doc::PartAttribute @class-method { :pretty_name "Provided method" :pretty_plural "Provided methods" set :part_class ::nx::doc::@method @@ -1154,8 +1166,8 @@ } Class create PartEntity -superclass Entity { - :attribute partof:object,type=::nx::doc::StructuredEntity,required - :attribute part_attribute:object,type=::nx::doc::PartAttribute,required + :property partof:object,type=::nx::doc::StructuredEntity,required + :property part_attribute:object,type=::nx::doc::PartAttribute,required } @@ -1168,13 +1180,14 @@ # PartTag create @method \ -superclass StructuredEntity { - :attribute -class ::nx::doc::SwitchAttribute @syshook:boolean { + + :property -class ::nx::doc::SwitchAttribute @syshook:boolean { set :default 0 } - :attribute -class ::nx::doc::PartAttribute @parameter { + :property -class ::nx::doc::PartAttribute @parameter { set :part_class ::nx::doc::@param } - :attribute -class ::nx::doc::PartAttribute @return { + :property -class ::nx::doc::PartAttribute @return { # # TODO: @return spec fragments should be nameless, # conceptually. They represent "out" parameters with each @@ -1209,7 +1222,8 @@ :public forward @class-method %self @method :public forward @class-object-method %self @method :public forward @sub-method %self @method - :attribute -class ::nx::doc::PartAttribute @method { + + :property -class ::nx::doc::PartAttribute @method { set :part_class ::nx::doc::@method :public method id {domain prop name} { # TODO: ${:part_class} resolves to the local slot @@ -1334,10 +1348,11 @@ # PartTag create @param \ -superclass PartEntity { - #:attribute spec - :attribute -class ::nx::doc::PartAttribute @spec - :attribute default + #:property spec + :property -class ::nx::doc::PartAttribute @spec + :property default + :public class method id {partof_name scope name} { next [list [:get_unqualified_name ${partof_name}] $scope $name] } @@ -1434,7 +1449,7 @@ # Provide two interp-wide aliases for @param. This is mere syntactic # sugar! # - interp alias {} ::nx::doc::@attribute {} ::nx::doc::@param + interp alias {} ::nx::doc::@property {} ::nx::doc::@param interp alias {} ::nx::doc::@parameter {} ::nx::doc::@param # @@ -1451,7 +1466,7 @@ interp alias {} ::nx::doc::@acrfirst {} ::nx::doc::@glossary namespace export CommentBlockParser @command @object @class @package \ - @project @method @attribute @parameter @ MixinLayer + @project @method @property @parameter @ MixinLayer } @@ -1460,7 +1475,7 @@ Class create TemplateData { - :class attribute renderer + :class property renderer :public forward renderer [current] %method :public forward rendered [current] %method @@ -1705,8 +1720,8 @@ # Class create Renderer -superclass MixinLayer { - :attribute {extension "[namespace tail [current]]"} - :attribute extends:object,type=[current] + :property {extension "[namespace tail [current]]"} + :property extends:object,type=[current] # # mixin-layer management @@ -1735,8 +1750,8 @@ # template management # - :attribute current_theme - :protected attribute {templates {[dict create]}} + :property current_theme + :protected property {templates {[dict create]}} :public method addTemplate {name theme body} { dict set :templates $theme $name $body @@ -1935,16 +1950,16 @@ MixinLayer::Mixin create [current]::Entity -superclass TemplateData { # - # TODO: Would it be useful to allow attribute slots to describe + # TODO: Would it be useful to allow property slots to describe # a per-class-object state, while the accessor/mutator methods # are defined on the per-class level. It feels like the class # instance variables in Smalltalk ... # # TODO: Why is call protection barfing when the protected target # is called from within a public forward. This should qualify as # a valid call site (from "within" the same object!), shouldn't it? - # :protected class attribute current_project:object,type=::nx::doc::@project - # :class attribute current_project:object,type=::nx::doc::@project + # :protected class property current_project:object,type=::nx::doc::@project + # :class property current_project:object,type=::nx::doc::@project # :public forward current_project [current] %method # :public forward print_name %current name @@ -2082,7 +2097,7 @@ set entities [lrange $entities 1 end] } #return "$pof[join $pathnames .]" - # GN TODO: Maybe a nicer "title" attribute via method title? + # GN TODO: Maybe a nicer "title" property via method title? #return "[join $pathnames { }]" set iscript [join [list [list set title $pof[join $pathnames .]] \ @@ -2423,8 +2438,8 @@ return $value } - :protected attribute {current_packages "*"} - :attribute {permissive_pkgs:1..* "*"} { + :protected property {current_packages "*"} + :property {permissive_pkgs:1..* "*"} { set :incremental 1 } @@ -2762,7 +2777,7 @@ if {[info commands "::nx::Class"] ne ""} { if {[::nsf::object::dispatch $obj ::nsf::methods::object::info::hastype ::nx::Slot]} { dict set bundle objtype slot - dict set bundle incremental [expr {[::nsf::object::dispatch $obj ::nsf::methods::object::info::hastype ::nx::RelationSlot] || ([::nsf::object::dispatch $obj ::nsf::methods::object::info::hastype ::nx::Attribute] && [::nsf::var::exists $obj incremental] && [::nsf::var::set $obj incremental])}] + dict set bundle incremental [expr {[::nsf::object::dispatch $obj ::nsf::methods::object::info::hastype ::nx::RelationSlot] || ([::nsf::object::dispatch $obj ::nsf::methods::object::info::hastype ::nx::VariableSlot] && [::nsf::var::exists $obj incremental] && [::nsf::var::set $obj incremental])}] } if {[::nsf::object::dispatch $obj ::nsf::methods::object::info::hastype ::nx::EnsembleObject]} { dict set bundle objtype ensemble @@ -3074,9 +3089,9 @@ "" [current] at_source next } - :protected attribute {interp ""}; # the default empty string points to the current interp + :protected property {interp ""}; # the default empty string points to the current interp - :attribute registered_commands + :property registered_commands :public method get_companions {} { set companions [dict create] @@ -3207,7 +3222,7 @@ # MetaClassToken n/a Class create MetadataToken { - :class attribute analyzer + :class property analyzer :public forward analyzer [current] %method :method as {partof:object,type=::nx::doc::StructuredEntity} \ -returns object,type=::nx::doc::Entity { @@ -3860,7 +3875,7 @@ set name [$entity name] set box [$project sandbox] # attributes - foreach slot [$box do [list $name info slots]] { + foreach slot [$box do [list $name info slot objects]] { if {[$box do [list $slot eval {info exists :__initcmd}]]} { # # TODO: Here, we eagerly create doc entities, is this an issue? @@ -3975,10 +3990,10 @@ # Class create CommentBlockParser { - :attribute {parsing_level:integer 0} + :property {parsing_level:integer 0} - :attribute {message ""} - :attribute {status:in "COMPLETED"} { + :property {message ""} + :property {status:in "COMPLETED"} { set :incremental 1 @@ -4006,7 +4021,7 @@ } } - :attribute processed_section { + :property processed_section { set :incremental 1 :public method assign {domain prop value} { set current_entity [$domain current_entity] @@ -4018,7 +4033,7 @@ $current_entity {*}$scope add [next [list $domain $prop $value]] } } - :attribute current_entity:object + :property current_entity:object :public class method process { {-partof_entity ""} @@ -4072,7 +4087,7 @@ :processed_section [$initial_section] # TODO: currently, default values are not initialised for - # attribute slots defined in mixin classes; so do it manually + # property slots defined in mixin classes; so do it manually # for the time being. ${:current_entity} current_comment_line_type "" @@ -4135,15 +4150,15 @@ Class create CommentBlockParsingState -superclass Class { - :attribute next_comment_section - :attribute comment_line_transitions:required + :property next_comment_section + :property comment_line_transitions:required } Class create CommentSection { - :attribute block_parser:object,type=::nx::doc::CommentBlockParser - :attribute {current_comment_line_type ""} + :property block_parser:object,type=::nx::doc::CommentBlockParser + :property {current_comment_line_type ""} set :line_types { tag {regexp -- {^\s*@[^[:space:]@]+} $line} @@ -4346,7 +4361,8 @@ set entity [@$leaf(axis) new -name $leaf(name) {*}$args] } else { if {[$entity info lookup methods -source application @$leaf(axis)] eq ""} { - ${:block_parser} cancel INVALIDTAG "The tag '$leaf(axis)' is not supported for the entity type '[namespace tail [$entity info class]]'" + ${:block_parser} cancel INVALIDTAG \ + "The tag '$leaf(axis)' is not supported for the entity type '[namespace tail [$entity info class]]'" } set entity [$entity @$leaf(axis) [list $leaf(name) {*}$args]] } Index: tests/parameters.test =================================================================== diff -u -r2e7f0b2256363d70c78778c9ed401f9450622a6a -rfd3666742ed34091dbb93a872fe1d34d6b66ad9d --- tests/parameters.test (.../parameters.test) (revision 2e7f0b2256363d70c78778c9ed401f9450622a6a) +++ tests/parameters.test (.../parameters.test) (revision fd3666742ed34091dbb93a872fe1d34d6b66ad9d) @@ -37,7 +37,11 @@ Test case parametercheck { Object create o1 - Class create C -attributes {a {b:boolean} {c 1}} + Class create C { + :property a + :property {b:boolean} + :property {c 1} + } C create c1 Class create M c1 mixin M @@ -245,7 +249,7 @@ # {elementtype ::nx::Class} # } -- sample instances: class superclass, mixin filter # -# ::nx::Attribute -superclass ::xotcl::Slot { +# ::nx::VariableSlot -superclass ::xotcl::Slot { # {value_check once} # defaultcmd # valuecmd @@ -263,7 +267,11 @@ Test parameter count 10 Test case objectparameter { - Class create C -attributes {a {b:boolean} {c 1}} + Class create C { + :property a + :property {b:boolean} + :property {c 1} + } C create c1 ? {C eval :objectparameter} \ @@ -278,7 +286,11 @@ ####################################################### Test case reclass { - Class create C -attributes {a {b:boolean} {c 1}} + Class create C { + :property a + :property {b:boolean} + :property {c 1} + } C create c1 ? {c1 info lookup slots -source application} "::C::slot::a ::C::slot::b ::C::slot::c" @@ -287,7 +299,7 @@ ? {c1 info lookup slots -source application} "" - Class create D -superclass C -attributes {d:required} + Class create D -superclass C {:property d:required} D create d1 -d 100 ? {d1 info lookup slots -source application} \ @@ -302,12 +314,24 @@ ####################################################### Test case objparam-mixins { - Class create C -attributes {a {b:boolean} {c 1}} - Class create D -superclass C -attributes {d:required} + Class create C { + :property a + :property {b:boolean} + :property {c 1} + } + Class create D -superclass C { + :property d:required + } D create d1 -d 100 - Class create M -attributes {m1 m2 b} - Class create M2 -attributes {b2} + Class create M { + :property m1 + :property m2 + :property b + } + Class create M2 { + :property b2 + } D mixin M ? {D eval :objectparameter} \ @@ -342,8 +366,12 @@ Test case passed-arguments { - Class create C -attributes {a {b:boolean} {c 1}} - Class create D -superclass C -attributes {d:required} + Class create C { + :property a + :property b:boolean + :property {c 1} + } + Class create D -superclass C {:property d:required} ? {catch {D create d1 -d 123}} 0 "create d1 with required argument given" ? {catch {D create d1}} 1 "create d1 without required argument given" @@ -454,8 +482,8 @@ {invalid value in "o d1 x": expected object but got "x" for parameter "m"} \ "multiple values" - Class create Foo -attributes { - {ints:integer,1..*} + Class create Foo { + :property ints:integer,1..* } ? {Foo create foo -ints {1 2}} "::foo" ? {Foo create foo -ints {1 a 2}} {invalid value in "1 a 2": expected integer but got "a" for parameter "-ints"} @@ -477,8 +505,8 @@ Test case subst-default { Class create D { - :attribute {c 1} - :attribute {d 2} + :property {c 1} + :property {d 2} :create d1 @@ -494,14 +522,14 @@ ? {d1 bar -c 1} {::d1-[current]-1-2} "substdefault in method parameter" - Class create Bar -superclass D -attributes { - {s "[current]"} - {literal "\\[current\\]"} - {c "[:info class]"} - {d "literal $d"} + Class create Bar -superclass D { + :property {s "[current]"} + :property {literal "\\[current\\]"} + :property {c "[:info class]"} + :property {d "literal $d"} } - ? {Bar attribute ss:switch} "::nsf::classes::Bar::ss" + ? {Bar property ss:switch} "::nsf::classes::Bar::ss" Bar create bar1 #puts stderr [bar1 objectparameter] @@ -607,7 +635,7 @@ ####################################################### Test case user-types { - Class create D -attributes d + Class create D {:property d} D create d1 # create a userdefined type @@ -706,7 +734,7 @@ Test case mp-object-types { Class create C - Class create D -superclass C -attributes d + Class create D -superclass C {:property d} Class create M Class create M2 @@ -780,7 +808,11 @@ ####################################################### Test case substdefault { - Class create S -attributes {{x 1} {y b} {z {1 2 3}}} + Class create S { + :property {x 1} + :property {y b} + :property {z {1 2 3}} + } S create s1 { :public method foo {{y:substdefault ${:x}}} { return $y @@ -838,16 +870,16 @@ Class create Bar { # simple, implicit substdefault - :attribute {s0 "[current]"} + :property {s0 "[current]"} # explicit substdefault - :attribute {s1:substdefault "[current]"} + :property {s1:substdefault "[current]"} # unneeded double substdefault - :attribute {s2:substdefault,substdefault "[current]"} + :property {s2:substdefault,substdefault "[current]"} # substdefault with incremental - :attribute {s3:substdefault "[current]"} { + :property {s3:substdefault "[current]"} { # Bypassing the Optimizer helps after applying the patch (solving step 1) set :incremental 1 } @@ -867,8 +899,8 @@ ::nsf::method::require nx::Object configure Class create C { - :attribute {a ""} - :attribute {b 1} + :property {a ""} + :property {b 1} :method init {} { :configure -b 1 @@ -890,7 +922,7 @@ Test case op-object-types { Class create C - Class create D -superclass C -attributes d + Class create D -superclass C {:property d} Class create MC -superclass Class MC create MC1 @@ -899,17 +931,17 @@ C create c1 -mixin M Object create o - Class create ParamTest -attributes { - o:object - c:class - c1:class,type=::MC - d:object,type=::C - d1:object,type=C - m:metaclass - b:baseclass - u:upper - us:upper,1..* - {x:object,1..* {o}} + Class create ParamTest { + :property o:object + :property c:class + :property c1:class,type=::MC + :property d:object,type=::C + :property d1:object,type=C + :property m:metaclass + :property b:baseclass + :property u:upper + :property us:upper,1..* + :property {x:object,1..* {o}} } # TODO: we have no good interface for querying the slot notation for parameters @@ -974,11 +1006,11 @@ "value is not an object" # - # define multivalued attribute "os" via instance variables of the + # define multivalued property "os" via instance variables of the # slot object # ParamTest eval { - :attribute os { + :property os { :type object :multiplicity 1..n } @@ -1093,7 +1125,7 @@ Test case slot-specfic-converter { Class create Person { - :attribute sex { + :property sex { :type "sex" :convert true :method type=sex {name value} { @@ -1162,7 +1194,11 @@ Test parameter count 1000 Test case slot-optimizer { - Class create C -attributes {a b:integer c:integer,0..n} + Class create C { + :property a + :property b:integer + :property c:integer,0..n + } C create c1 ? {c1 a 1} 1 @@ -1182,7 +1218,11 @@ Test parameter count 10 Test case slot-nosetter { - Class create C -attributes {a b:integer,accessor=false {c:accessor=false ""}} + Class create C { + :property a + :property b:integer,noaccessor + :property {c:noaccessor ""} + } ? {C create c1 -a 1 -b 2} ::c1 ? {c1 info vars} "a b c" @@ -1227,9 +1267,9 @@ Test case slot-traces { ::nx::Object create o { - :attribute a {set :defaultcmd { set _ 4 } } - :attribute b {set :valuecmd { set _ 44 } } - :attribute c {set :valuechangedcmd { ::nsf::var::set $obj $var 999 }} + :property a {set :defaultcmd { set _ 4 } } + :property b {set :valuecmd { set _ 44 } } + :property c {set :valuechangedcmd { ::nsf::var::set $obj $var 999 }} } ? {o a} 4 @@ -1243,9 +1283,9 @@ ? {o c 5} 999 ::nx::Class create C { - :attribute a {set :defaultcmd { set _ 4 } } - :attribute b {set :valuecmd { set _ 44 } } - :attribute c {set :valuechangedcmd { ::nsf::var::set $obj $var 999 }} + :property a {set :defaultcmd { set _ 4 } } + :property b {set :valuecmd { set _ 44 } } + :property c {set :valuechangedcmd { ::nsf::var::set $obj $var 999 }} :create c1 } ? {c1 a} 4 @@ -1402,7 +1442,7 @@ # Test case dont-reset-to-defaults { Class create C { - :attribute {a 1} + :property {a 1} :create c1 } ? {c1 a} 1 @@ -1460,8 +1500,8 @@ Test case req-param { ::nx::Class create C { - :attribute y:required - :attribute x:required + :property y:required + :property x:required :method init args {set ::_ $args} } @@ -1482,8 +1522,8 @@ # Test case nsf-subdefault { nx::Class create C { - :attribute {n1 "[namespace tail [::nsf::self]]"} - :attribute {n2:any "[namespace tail [::nsf::self]]"} + :property {n1 "[namespace tail [::nsf::self]]"} + :property {n2:any "[namespace tail [::nsf::self]]"} :create c1 } ? {c1 n1} c1 @@ -1584,10 +1624,10 @@ Test case parameter-alias { Class create C { - :attribute {x:alias} - :attribute {A:alias,method=bar} - :attribute {{F:forward,method=%self foo %1 a b c %method}} - :attribute {D def} + :property {x:alias} + :property {A:alias,method=bar} + :property {{F:forward,method=%self foo %1 a b c %method}} + :property {D def} :public method x args {set :x $args} :public method foo args {set :foo $args} :public method bar args {set :bar $args} @@ -1606,9 +1646,9 @@ Test case parameter-alias-default { Class create C { - :attribute {x1:alias "hugo"} - :attribute {{F:forward,method=%self foo a %1 b c %method} "habicht"} - :attribute {x2:alias "[self]"} + :property {x1:alias "hugo"} + :property {{F:forward,method=%self foo a %1 b c %method} "habicht"} + :property {x2:alias "[self]"} :public method x1 args {set :x1 $args} :public method x2 args {set :x2 $args} :public method foo args {set :foo $args} @@ -1619,7 +1659,7 @@ ? {c1 eval {set :foo}} "a habicht b c F" ? {c1 eval {set :x2}} "::c1" ? {lsort [c1 info lookup methods -source application]} "foo x1 x2" - ? {lsort [C info slots]} "::C::slot::F ::C::slot::x1 ::C::slot::x2" + ? {lsort [C info slot objects]} "::C::slot::F ::C::slot::x1 ::C::slot::x2" ? {::C::slot::x1 getParameterSpec} {-x1:alias hugo} ? {::C::slot::x2 getParameterSpec} {-x2:alias,substdefault {[self]}} } @@ -1629,21 +1669,21 @@ # Test case parameter-object-mixin-dependency { Class create C { - :attribute a1 + :property a1 :create c1 { - :attribute a2 + :property a2 } } Class create M { - :attribute b1:required + :property b1:required } c1 mixin M ? {c1 info precedence} "::M ::C ::nx::Object" - ? {C info slots -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" + ? {C info slot objects -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" ? {C eval :objectparameter} "-a1 -volatile:alias,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" @@ -1657,7 +1697,7 @@ ? {c1 info precedence} "::M ::C ::nx::Object" - ? {C info slots -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" + ? {C info slot objects -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" ? {C eval :objectparameter} "-a1 -volatile:alias,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" @@ -1754,30 +1794,30 @@ nx::Test case reconfigure-perobj-default { Object create o ? {o eval {info exists :a}} 0 - o attribute {a oldvalue} + o property {a oldvalue} ? {o eval {info exists :a}} 1 ? {o a} oldvalue # - # By unsetting the var, upon recreating the attribute slot (or - # calling reconfigure upon the attribute) we can trigger + # By unsetting the var, upon recreating the property slot (or + # calling reconfigure upon the property) we can trigger # a re-assignment of the default value. # o eval {unset :a} ? {o eval {info exists :a}} 0 # # re-assignment of the default is handled by init # - o attribute {a newvalue} + o property {a newvalue} ? {o eval {info exists :a}} 1 ? {o a} newvalue o eval {unset :a} ? {o eval {info exists :a}} 0 - [o info slots a] default anothervalue + [o info slot objects a] default anothervalue ? {o eval {info exists :a}} 0 # # re-assignment must be requested by a reconfigure call # - [o info slots a] reconfigure + [o info slot objects a] reconfigure ? {o eval {info exists :a}} 1 ? {o a} anothervalue } @@ -1800,7 +1840,7 @@ # Strengths of object-level parameters: # - same interface as class-level attributes # - can use same meta-data mechanisms as for class-level attributes -# (e.g database types, attribute name in the database, persistence +# (e.g database types, property name in the database, persistence # information, ...) # - can use same setters/checkers as for class-level attributes # - can use as well incremental as for class-level attributes @@ -1820,7 +1860,7 @@ # cannot be called. # -# test object level attribute and variable +# test object level property and variable # nx::Test case object-level-variable { @@ -1829,33 +1869,33 @@ # just to get a reference value for the timing ? [list [self] eval {set :dummy 1}] "1" - # set 2 variables, one via variable, one via attribute + # set 2 variables, one via variable, one via property ? [list [self] variable -nocomplain captain1 "James Kirk"] "" - ? [list [self] attribute -nocomplain [list captain2 "Jean Luc"]] "::enterprise::captain2" + ? [list [self] property -nocomplain [list captain2 "Jean Luc"]] "::enterprise::captain2" # in both cases, we expect instance variables ? [list [self] eval {set :captain1}] "James Kirk" ? [list [self] eval {set :captain2}] "Jean Luc" - # just for the attribute, we have accessors + # just for the property, we have accessors ? [list [self] info lookup method captain1] "" ? [list [self] info lookup method captain2] "::enterprise::captain2" # set variable with a value checker ? [list [self] variable -nocomplain x1:int 1] "" - ? [list [self] attribute -nocomplain [list x2:int 2]] "::enterprise::x2" + ? [list [self] property -nocomplain [list x2:int 2]] "::enterprise::x2" # set variable with a value checker and an invalid value ? [list [self] variable y1:int a] {expected integer but got "a"} - ? [list [self] attribute [list y2:int b]] {expected integer but got "b"} + ? [list [self] property [list y2:int b]] {expected integer but got "b"} # set variable again, without -nocomplain ? [list [self] variable x1:int 1] {Object ::enterprise has already an instance variable named 'x1'} - ? [list [self] attribute [list x2:int 2]] {Object ::enterprise has already an instance variable named 'x2'} + ? [list [self] property [list x2:int 2]] {Object ::enterprise has already an instance variable named 'x2'} # set variable with a value checker, multiple ? [list [self] variable -nocomplain xm1:int,1..n {1 2 3}] "" - ? [list [self] attribute -nocomplain [list xm2:int,1..n {1 2 3}]] "::enterprise::xm2" + ? [list [self] property -nocomplain [list xm2:int,1..n {1 2 3}]] "::enterprise::xm2" # in both cases, we expect instance variables ? [list [self] eval {set :xm1}] "1 2 3" @@ -1864,7 +1904,7 @@ # set variable with a value checker, multiple with invalid value ? [list [self] variable -nocomplain xm1:int,1..n {1 2a 3}] \ {invalid value in "1 2a 3": expected integer but got "2a"} - ? [list [self] attribute -nocomplain [list xm2:int,1..n {1 2a 3}]] \ + ? [list [self] property -nocomplain [list xm2:int,1..n {1 2a 3}]] \ {invalid value in "1 2a 3": expected integer but got "2a"} # useless definition @@ -1875,7 +1915,7 @@ # define an application specific converter # # TODO: currently, we need two converters (or a converter on nx::Slot), since - # variable uses nsf::is and attribute uses the slot obj. method variable should + # variable uses nsf::is and property uses the slot obj. method variable should # be changed to use the slotobj as well. ::nx::ObjectParameterSlot method type=range {name value arg} { lassign [split $arg -] min max @@ -1894,20 +1934,20 @@ # # Test usage of application specific converter in "variable" and - # "attribute"; invalid value + # "property"; invalid value ? [list [self] variable -nocomplain r1:range,arg=1-10 11] \ {Value '11' of parameter value not between 1 and 10} - ? [list [self] attribute -nocomplain [list r2:range,arg=1-10 11]] \ + ? [list [self] property -nocomplain [list r2:range,arg=1-10 11]] \ {Value '11' of parameter value not between 1 and 10} # valid value ? [list [self] variable -nocomplain r1:range,arg=1-10 5] "" - ? [list [self] attribute -nocomplain [list r2:range,arg=1-10 5]] \ + ? [list [self] property -nocomplain [list r2:range,arg=1-10 5]] \ {::enterprise::r2} # testing incremental ? [list [self] variable -incremental -nocomplain i:int,0..* {}] "::enterprise::i" - ? [list [self] attribute -incremental -nocomplain j:int,0..* {}] "::enterprise::j" + ? [list [self] property -incremental -nocomplain j:int,0..* {}] "::enterprise::j" :i add 1 :j add 1 ? [list [self] i] "1" @@ -1921,9 +1961,9 @@ } nx::Class create C { - # set 2 class variables, one via variable, one via attribute + # set 2 class variables, one via variable, one via property ? [list [self] class variable -nocomplain v "v0"] "" - ? [list [self] class attribute -nocomplain [list a "a0"]] "::C::a" + ? [list [self] class property -nocomplain [list a "a0"]] "::C::a" # in both cases, we expect instance variables ? [list [self] eval {set :v}] "v0" @@ -1937,14 +1977,14 @@ } # -# test class level attribute and variable +# test class level property and variable # nx::Test case class-level-variable { nx::Class create C { - # define 2 class-level variables, one via variable, one via attribute + # define 2 class-level variables, one via variable, one via property :variable v v0 - :attribute {a a0} + :property {a a0} # create an instance :create c1 @@ -1958,13 +1998,14 @@ # # We expect a specifiable object parameter for "a" but not for "v". # The parameter for v can be obtained via spec, but is not listed in - # "info parameter syntax" or "info parameter spec". + # "info parameter syntax" or "info parameter definition". # ? {C info parameter list a} "-a" - ? {C info parameter spec a} "{-a a0}" + ? {C info parameter definition a} "{-a a0}" ? {C info parameter syntax a} "?-a value?" - ? {C info parameter spec v} "{-v:noconfig v0}" + ? {C info parameter definition v} "" + ? {C info slot definition v} "{v:noaccessor,noconfig v0}" ? {C info parameter list v} "" ? {C info parameter syntax v} "" @@ -1998,14 +2039,14 @@ } # -# test deletion of class level attribute and variable +# test deletion of class level property and variable # -nx::Test case delete-class-level-variable-and-attribute { +nx::Test case delete-class-level-variable-and-property { nx::Class create C { - # define 2 class-level variables, one via variable, one via attribute + # define 2 class-level variables, one via variable, one via property :variable v v0 - :attribute {a a0} + :property {a a0} # create an instance :create c1 @@ -2022,10 +2063,10 @@ ? {c1 info lookup method a} "::nsf::classes::C::a" ? {c1 info lookup method v} "" - # if we delete a class-level attribute or variable, + # if we delete a class-level property or variable, # the object parameter and setters for "a" will be gone C delete variable v - C delete attribute a + C delete property a ? {C info parameter list a} "" ? {c1 info lookup method a} "" @@ -2038,14 +2079,14 @@ } # -# test deletion of class level attribute and variable +# test deletion of class level property and variable # -nx::Test case delete-object-level-variable-and-attribute { +nx::Test case delete-object-level-variable-and-property { nx::Object create o { - # define 2 object-level variables, one via variable, one via attribute + # define 2 object-level variables, one via variable, one via property :variable v v0 - :attribute {a a0} + :property {a a0} } # the instance of C will have the two variables set ... @@ -2056,23 +2097,26 @@ ? {o info lookup method v} "" # Object-level attributes and variables set und unset instance - # variables. If we delete an object-level attribute or variable, + # variables. If we delete an object-level property or variable, # the setters for "a" will be unset. o delete variable v - o delete attribute a + o delete property a ? {o info lookup method a} "" # Both instance variables are unset ? {lsort [o info vars]} {} } +# +# Testing object parameters of type "switch" +# nx::Test case object-parameter-switch { - # Create a class with an attribute of type switch and an instance of + # Create a class with an property of type switch and an instance of # the class ? {::nx::Class create C { - :attribute foo:switch + :property foo:switch :create c1 }} "::C" @@ -2104,7 +2148,7 @@ # In the inverted case, the switch has a default of "true". If the # switch is specified, the valus is "false" - C attribute {foo2:switch 1} + C property {foo2:switch 1} C create c4 ? {lsort [c4 info vars]} {foo foo2} ? {c4 eval {set :foo2}} {1} @@ -2121,5 +2165,35 @@ }} ::o1 ? {o1 eval {set :foo}} 0 ? {o1 eval {set :bar}} 1 +} +# +# Test slots with configparameter true/false, accessor true/false +# against "info slot definition" and "info parameter" +# +Test case info-slots-types { + Class create C { + # variable has no config parameter and no accessor + :variable v 100 + } + + # "v" does not show up in "info parameter" + ? {C info parameter list} "-volatile -noinit -mixin -class -filter __initcmd" + ? {C info parameter names} "volatile noinit mixin class filter __initcmd" + + # "v" does show up in "info slot" + ? {C info slot objects} "::C::slot::v" + ? {C info slot definition} "{v:noaccessor,noconfig 100}" + + Class create D { + :property {p:noaccessor 200} + } + + # "p" does show up in "info parameter" + ? {D info parameter list} "-p -volatile -noinit -mixin -class -filter __initcmd" + ? {D info parameter names} "p volatile noinit mixin class filter __initcmd" + + # "p" does show up in "info slot" + ? {D info slot objects} "::D::slot::p" + ? {D info slot definition} "{p:noaccessor 200}" } \ No newline at end of file