diff --git a/harbour/ChangeLog b/harbour/ChangeLog index fb4f0a8596..272c6b1793 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,76 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + +2006-10-04 15:20 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbexprc.c + * translate HB_P_INC / HB_P_DEC in (pre|post)(inc|dec)rementation + to HB_P_[PLUS|MINUS]EQ + + * harbour/source/vm/hvm.c + - removed not necessary now hb_itemUnRef() in hb_vmInc()/hb_vmDec() + +2006-10-04 09:02 UTC+0100 Antonio Linares (alinares@fivetechsoft.com) + * common.mak + main.c has to be used instead of mainstd.c or mainwin.c + as main.c select the right entry point function based on the used defines + +2006-10-04 02:30 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbclass.ch + * most of the rules rewritten + ! fixed some wrong rules and general cleanup + + added additional code validation + ! fixed compilation of more then one class in single file. + Now it's even possible to declare all classes at beginning of + single file and then implementing their methods in any order + ! fixed using static classes and classes + ! fixed compilation without _ prefix in method names + + added support for HB_CLS_NO_DECORATION macro which disable + adding _ prefix to method names - this macro is + set by default when HB_SHORTNAMES is set. + + added support for declared parameters validation - it can be + disabled with HB_CLS_NO_PARAMS_ERR and I had to disable it + by default due to problems with our preprocessor. + Ryszard seems that our PP has serious problems with decoding + directives when there is no space between symbol and some other + non symbol character. I had to add some workarounds and even + introduce buggy rules to make it working. Please look at it. + You can remove #define HB_CLS_NO_PARAMS_ERR from hbclass.ch + and try to rebuild Harbour core code to see the problem. + + * harbour/include/hboo.ch + * harbour/source/vm/classes.c + + added support for new primitive message: HB_OO_MSG_PERFORM + + * harbour/source/rtl/tclass.prg + - removed parameter from HBClass messages and + internals data. Persistent is supported as scope bit and + separate variable was redundant. + - removed stripping of () from message names. Here is not a place + to fix wrong preprocessor rules. + + * harbour/utils/hbtest/rt_class.prg + * use: METHOD PROCEDURE ... CALSS ... + instead of: PROCEDURE ... CALSS ... + The first version is preferable syntax. + + * harbour/source/debug/dbgtmenu.prg + * harbour/source/rtl/checkbox.prg + ! fixed some parameters in method declaration - global cleanup + will have to wait for preprocessor fixes + + Hi all, + Please make test with current hbclass.ch code. + I hope that I haven't broken too much things ;-) but I rewrite + from scratch most rules and it's possible that I missed sth or + made some stupid typos. Current version is much shorter and should + be easier to updated. For sure I've intentionally changed one thing. + CLASSDATA was ignoring SHARED attribute and always created shared + class variables. Seems that it was long existing typo but the fix + may interact with already existing code which needs SHARED class + variables but does not use SHARED clause in CLASSDATA declaration. + In such case please update it and add missing SHARED. + Also in the end of CLASS declaration we have: [ ; #translate Super( ): => ::: ] ; [ ; #translate Super( ): => ::: ] ; [ ; #translate Super(): => ::: ] ; diff --git a/harbour/include/hbclass.ch b/harbour/include/hbclass.ch index a106734a1b..186d5bd053 100644 --- a/harbour/include/hbclass.ch +++ b/harbour/include/hbclass.ch @@ -9,6 +9,9 @@ * Copyright 1999 Antonio Linares * www - http://www.harbour-project.org * + * Copyright 2006 Przemyslaw Czerpak + * most of rules rewritten + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -95,46 +98,19 @@ /* So Each class _inherit_ of HBObject by default and */ /* Each type logical or numerical is initiated to .F. and 0 by default */ -/* #define HB_CLS_NOTOBJECT */ /* Should be included in some compatibility include files as needed */ -/* #define HB_CLS_NOAUTOINIT */ /* Idem */ -/* #define HB_CLS_ALLOWCLASS */ /* Work in progress, don't define it now */ -/* #define HB_CLS_ENFORCERO FLAG to disable Write access to RO VAR outside */ -/* of Constructors /!\ Could be related to some incompatibility */ +/* #define HB_CLS_NOTOBJECT */ /* Should be included in some compatibility include files as needed */ +/* #define HB_CLS_NOAUTOINIT */ /* Idem */ +/* #define HB_CLS_NO_DECORATION */ /* disable adding _ prefix to method function names */ +/* #define HB_CLS_NO_PARAMS_ERR */ /* disable parameters validation in method declaration and implementation */ +/* #define HB_CLS_NO_OO_ERR */ /* disable all code validation */ -DECLARE HBClass ; - New( cName AS String, OPTIONAL SuperParams ) AS CLASS HBClass ; - Create() AS Object ; - Instance() AS Object ; - AddClsMthds( cName AS String, @MethodName(), nScope AS Numeric, n2 AS Numeric, n3 AS Numeric ) ; - AddMultiClsData( cType AS String, uVal, nScope AS Numeric, aDatas AS Array OF String ) ; - AddMultiData( cType AS String, uVal, nScope AS Numeric, aDatas AS Array OF String, x AS LOGICAL, lPer AS LOGICAL ) ; - AddMethod( cName AS String, @MethodName(), nScope AS Numeric, lPersistent AS LOGICAL ) ; - AddInLine( cName AS String, bBlock AS CodeBlock, nScope AS Numeric, lPersistent AS LOGICAL ) ; - AddVirtual( cName AS String ) - -#xtranslate __ERR([]) => #error [] -#xtranslate )() => ) - -#ifdef HB_CLS_NOTOBJECT - #xtranslate __HB_CLS_PAR([]) => { [] } -#else - #xtranslate __HB_CLS_PAR([]) => ; - iif( <.cls.>, { }, { @HBObject() } ) -#endif -#xtranslate __HB_CLS_PAR0([]) => { [] } - -#ifdef HB_CLS_NOAUTOINIT - #define __HB_CLS_NOINI .T. -#else - #define __HB_CLS_NOINI .F. -#endif #ifndef HB_CLS_FWO #ifndef HB_CLS_CSY #ifndef HB_CLS_VO #ifndef HB_CLS_TOP - /* IF NOTHING DECIDED BY THE PROGRAMER USE ALL */ +/* IF NOTHING DECIDED BY THE PROGRAMER USE ALL */ #define HB_CLS_FWO #define HB_CLS_CSY #define HB_CLS_VO @@ -145,201 +121,363 @@ DECLARE HBClass ; #endif #endif -#xtranslate HBCLSCHOICE( , , ) => iif( , HB_OO_CLSTP_EXPORTED , iif( , HB_OO_CLSTP_PROTECTED, iif( , HB_OO_CLSTP_HIDDEN, nScope) ) ) -/* CLASSY SYNTAX */ -#IFDEF HB_CLS_CSY -#xtranslate CREATE CLASS => CLASS -#xtranslate _HB_MEMBER {AS Int => _HB_MEMBER {AS Numeric -#xtranslate _HB_MEMBER {AS Integer => _HB_MEMBER {AS Numeric -#xtranslate _HB_MEMBER {AS Num => _HB_MEMBER {AS Numeric -#xtranslate _HB_MEMBER {AS Char => _HB_MEMBER {AS Character -#xtranslate _HB_MEMBER {AS Block => _HB_MEMBER {AS CodeBlock +#ifndef __HARBOUR__ + #define HB_CLS_NO_DECORATION + #define HB_CLS_NO_DECLARATIONS +#endif +/* disable method decoration when Harbour compiled with short (10 chars) symbols */ +#ifdef HB_SHORTNAMES + #ifndef HB_CLS_NO_DECORATION + #define HB_CLS_NO_DECORATION + #endif +#endif + +/* + * I have to enable this definition by default untill we will not fix + * preprocessor. [druzus] + */ +#define HB_CLS_NO_PARAMS_ERR + +/* should we use <_ prefix for real method names? */ +#ifdef HB_CLS_NO_DECORATION + #xtranslate __HB_CLS_MTHNAME => +#else + #xtranslate __HB_CLS_MTHNAME => _ +#endif + +/* should we use _HB_CLASS/_HB_MEMBER declarations? */ +#ifdef HB_CLS_NO_DECLARATIONS + #xcommand _HB_CLASS => + #xcommand _HB_MEMBER => + #xcommand DECLARE <*decl*> => + #xtranslate AS => + #xtranslate AS CLASS => +#endif + +/* should we inherit from HBObject class by default ? */ +#ifdef HB_CLS_NOTOBJECT + #xtranslate __HB_CLS_PAR([]) => { [] } +#else + #xtranslate __HB_CLS_PAR([]) => iif( <.cls.>, { }, { @HBObject() } ) +#endif + +/* Should we initialize typed instance variables? */ +#ifdef HB_CLS_NOAUTOINIT + #define __HB_CLS_NOINI .T. +#else + #define __HB_CLS_NOINI .F. +#endif + +/* Should we generate compile error when method declaration has differ parameters? */ +#ifdef HB_CLS_NO_PARAMS_ERR + #xtranslate __HB_CLS_PARAMS() => __HB_CLS_ASID() +#else + #xtranslate __HB_CLS_PARAMS() => +#endif + +/* Should we disable compile errors for undeclared methods? */ +#ifdef HB_CLS_NO_OO_ERR + #xtranslate __HB_CLS_ERR([]) => +#else + #xtranslate __HB_CLS_ERR([]) => #error [] +#endif + + +DECLARE HBClass ; + New( cName AS String, OPTIONAL SuperParams ) AS CLASS HBClass ; + Create() AS Object ; + Instance() AS Object ; + AddClsMthds( cName AS String, @MethodName(), nScope AS Numeric, n2 AS Numeric, n3 AS Numeric ) ; + AddMultiClsData( cType AS String, uVal, nScope AS Numeric, aDatas AS Array OF String ) ; + AddMultiData( cType AS String, uVal, nScope AS Numeric, aDatas AS Array OF String, x AS LOGICAL, lPer AS LOGICAL ) ; + AddMethod( cName AS String, @MethodName(), nScope AS Numeric ) ; + AddInLine( cName AS String, bBlock AS CodeBlock, nScope AS Numeric ) ; + AddVirtual( cName AS String ) + +/* + * Class(y) like non virtual send operator but instead of using early + * bindings it casts object to class in which current method were defined. + */ #translate @:([]) => ; ::realclass:([]) -#endif +/* Indirect super casting translation */ +#xtranslate :Super( ): => :: -#ifdef HB_CLS_ALLOWCLASS /* DONT DECLARE IT ! WORK IN PROGRESS !!! */ -#ifndef HB_SHORTNAMES +#xtranslate __HB_CLS_OPT(,) => +#xtranslate __HB_CLS_OPT() => -#xtranslate DECLMETH => _ +#xtranslate __HB_CLS_ASSTRING( ) => <(FuncName)> +#xtranslate __HB_CLS_ASSTRING( ([]) ) => <(FuncName)> +#xtranslate __HB_CLS_ASFUNC( ) => () +#xtranslate __HB_CLS_ASFUNC( ([]) ) => ([]) +#xtranslate __HB_CLS_ASID( ) => +#xtranslate __HB_CLS_ASID( ([]) ) => +#xtranslate __HB_CLS_ASARGS( ) => +#xtranslate __HB_CLS_ASARGS( ([]) ) => [] +#xtranslate __HB_CLS_ASARGSOPT( ) => +#xtranslate __HB_CLS_ASARGSOPT( ([]) ) => [, ] -#xcommand CLASS [METACLASS ] ; - [ [,] ] ; - [ ] [ FUNCTION ] => ; - #undef _HB_CLS_FUNCNAME ; #define _HB_CLS_FUNCNAME ;; - [ #undef _HB_CLS_FUNCNAME ; #define _HB_CLS_FUNCNAME ] ;; - _HB_CLASS ;; - function _HB_CLS_FUNCNAME() ;; - static s_oClass ;; - local MetaClass,nScope ;; - nScope := HB_OO_CLSTP_EXPORTED ;; - if s_oClass == NIL ;; - s_oClass := IIF(<.metaClass.>, <(metaClass)>, HBClass():new( <(ClassName)> , __HB_CLS_PAR( [ @() ] [ , @() ] ) ) ) ;; - if ! <.metaClass.> ;; - Metaclass := HBClass():new( <(ClassName)>+" class", __HB_CLS_PAR0( [ ():class ] [ ,():class ] ) ) ;; - endif ;; - #undef _CLASS_NAME_ ;; - #define _CLASS_NAME_ ;; - #undef _CLASS_MODE_ ;; - #define _CLASS_MODE_ _CLASS_DECLARATION_ ;; - #xtranslate CLSMETH => @_ ;; - #xtranslate DECLCLASS => ;; - [ ; #translate Super( ) : => ::: ] ; - [ ; #translate Super( ) : => ::: ] ; - [ ; #translate Super() : => ::: ] ; - [ ; #translate Super : => ::: ] ; - [ ; #translate ::Super : => ::: ] +/* #xtranslate __HB_CLS_SCOPE( , , ) => ; + iif( , HB_OO_CLSTP_EXPORTED , ; + iif( , HB_OO_CLSTP_PROTECTED, ; + iif( , HB_OO_CLSTP_HIDDEN, nScope ) ) ) */ +#xtranslate __HB_CLS_SCOPE( ) => );__HB_CLS_ERR( Can not use multiple scope qualifiers! );empty(nScope +#xtranslate __HB_CLS_SCOPE( .T., .F., .F. ) => HB_OO_CLSTP_EXPORTED +#xtranslate __HB_CLS_SCOPE( .F., .T., .F. ) => HB_OO_CLSTP_PROTECTED +#xtranslate __HB_CLS_SCOPE( .F., .F., .T. ) => HB_OO_CLSTP_HIDDEN +#xtranslate __HB_CLS_SCOPE( .F., .F., .F. ) => nScope /* Default */ -#else - -#xcommand CLASS [METACLASS ] ; - [ [,] ] ; - [ ] [ FUNCTION ] => ; - #undef _HB_CLS_FUNCNAME ; #define _HB_CLS_FUNCNAME ;; - [ #undef _HB_CLS_FUNCNAME ; #define _HB_CLS_FUNCNAME ] ;; - _HB_CLASS ;; - function _HB_CLS_FUNCNAME() ;; - static s_oClass ;; - local MetaClass,nScope ;; - nScope := HB_OO_CLSTP_EXPORTED ;; - if s_oClass == NIL ;; - s_oClass := IIF(<.metaClass.>, <(metaClass)>, HBClass():new( <(ClassName)> , __HB_CLS_PAR( [ @() ] [ , @() ] ) ) ) ;; - if ! <.metaClass.> ;; - Metaclass := HBClass():new( <(ClassName)>+" class", __HB_CLS_PAR0( [ ():class ] [ ,():class ] ) ) ;; - endif ;; - #undef _CLASS_NAME_ ;; - #define _CLASS_NAME_ ;; - #undef _CLASS_MODE_ ;; - #define _CLASS_MODE_ _CLASS_DECLARATION_ ;; - #translate CLSMETH () => @ ; - [ ; #translate Super( ) : => ::: ] ; - [ ; #translate Super( ) : => ::: ] ; - [ ; #translate Super() : => ::: ] ; - [ ; #translate Super : => ::: ] ; - [ ; #translate ::Super : => ::: ] - -#endif /* HB_SHORTNAMES */ - -#else - -#ifndef HB_SHORTNAMES - -#xtranslate DECLMETH => _ #xcommand CLASS [METACLASS ] ; [ [,] ] ; [ ] ; [ ] [ FUNCTION ] => ; - #undef _HB_CLS_FUNCNAME ; #define _HB_CLS_FUNCNAME ;; - [ #undef _HB_CLS_FUNCNAME ; #define _HB_CLS_FUNCNAME ] ;; _HB_CLASS ;; - function _HB_CLS_FUNCNAME() ;; + function __HB_CLS_OPT([,] ) ;; static s_oClass ;; local nScope ;; - nScope := HB_OO_CLSTP_EXPORTED ;; if s_oClass == NIL ;; - s_oClass := IIF(<.metaClass.>, <(metaClass)>, HBClass():new( <(ClassName)> , __HB_CLS_PAR( [ @() ] [ , @() ] ), @_HB_CLS_FUNCNAME() [, <.modulfriend.> ] ) ) ;; - #undef _CLASS_NAME_ ;; - #define _CLASS_NAME_ ;; - #undef _CLASS_MODE_ ;; - #define _CLASS_MODE_ _CLASS_DECLARATION_ ;; - #xtranslate CLSMETH => @_ ;; - #xtranslate DECLCLASS => ;; - [ ; #translate Super( ) : => ::: ] ; - [ ; #translate Super( ) : => ::: ] ; - [ ; #translate Super() : => ::: ] ; - [ ; #translate Super : => ::: ] ; - [ ; #translate ::Super : => ::: ] + nScope := HB_OO_CLSTP_EXPORTED ;; + s_oClass := IIF(<.metaClass.>, <(metaClass)>, HBClass():new( <(ClassName)> , __HB_CLS_PAR( [ @() ] [ , @() ] ), @__HB_CLS_OPT([__HB_CLS_ASID(),] )() [, <.modulfriend.> ] ) ) ;; + #undef _CLASS_NAME_ ; #define _CLASS_NAME_ ;; + #undef _CLASS_MODE_ ; #define _CLASS_MODE_ _CLASS_DECLARATION_ ; + [ ; #translate Super( ): => ::: ] ; + [ ; #translate Super( ): => ::: ] ; + [ ; #translate Super(): => ::: ] ; + [ ; #translate Super: => ::: ] ; + [ ; #translate ::Super : => ::: ] +#xcommand ENDCLASS => ; + s_oClass:Create() ;; + endif ;; + return s_oClass:Instance() AS CLASS _CLASS_NAME_ ;; + #undef _CLASS_MODE_ ; #define _CLASS_MODE_ _CLASS_IMPLEMENTATION_ + + +#xcommand DECLARED METHOD CLASS => ; + static __HB_CLS_MTHNAME ;; + local Self AS CLASS := QSelf() AS CLASS + +#ifdef __XHARBOUR__ + #xcommand __HB_CLS_DECLARE_METHOD => ; + #xcommand METHOD \ \[(\[\])] CLASS _CLASS_IMPLEMENTATION_ => ; + DECLARED METHOD \ \[(\)] CLASS ;; + #undef _DUMMY_DEF_ #else - -#xcommand CLASS [METACLASS ] ; - [ [,] ] ; - [ ] ; - [ ] [ FUNCTION ] => ; - #undef _HB_CLS_FUNCNAME ; #define _HB_CLS_FUNCNAME ;; - [ #undef _HB_CLS_FUNCNAME ; #define _HB_CLS_FUNCNAME ] ;; - _HB_CLASS ;; - function _HB_CLS_FUNCNAME() ;; - static s_oClass ;; - local nScope ;; - nScope := HB_OO_CLSTP_EXPORTED ;; - if s_oClass == NIL ;; - s_oClass := IIF(<.metaClass.>, <(metaClass)>, HBClass():new( <(ClassName)> , __HB_CLS_PAR( [ @() ] [ , @() ] ), @_HB_CLS_FUNCNAME() [, <.modulfriend.> ] ) ) ;; - #undef _CLASS_NAME_ ;; - #define _CLASS_NAME_ ;; - #undef _CLASS_MODE_ ;; - #define _CLASS_MODE_ _CLASS_DECLARATION_ ;; - #translate CLSMETH () => @ ; - [ ; #translate Super( ) : => ::: ] ; - [ ; #translate Super( ) : => ::: ] ; - [ ; #translate Super() : => ::: ] ; - [ ; #translate Super : => ::: ] ; - [ ; #translate ::Super : => ::: ] - -#endif /* HB_SHORTNAMES */ - -/* Disable the message :Class */ -/* CLASSY SYNTAX */ -#IFDEF HB_CLS_CSY -#xtranslate :CLASS => -#xtranslate :CLASS: => : + #xcommand __HB_CLS_DECLARE_METHOD => ; + #xcommand METHOD \ \[(\[])] CLASS _CLASS_IMPLEMENTATION_ => ; + DECLARED METHOD \ \[(\)] CLASS #endif -#endif +#xcommand METHOD CLASS _CLASS_IMPLEMENTATION_ => ; + __HB_CLS_ERR( Method not declared or declaration mismatch in class: ) ;; + DECLARED METHOD CLASS +#xcommand METHOD [ ] [ AS ] [ ] [] [