/* * Header file for Class commands * * Copyright 1999 Antonio Linares * Copyright 2000-07 JF. Lefebvre & RA. Cuylen (Class(y), TopClass and Visual Object compatibility, multiple inheritance) * Copyright 2000-08-2001 JF. Lefebvre (Scoping, Delegating, DATA Shared, Support of 10 Chars limits) * 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) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file LICENSE.txt. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/). * * As a special exception, the Harbour Project gives permission for * additional uses of the text contained in its release of Harbour. * * The exception is that, if you link the Harbour libraries with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the Harbour library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by the Harbour * Project under the name Harbour. If you copy code from other * Harbour Project or Free Software Foundation releases into a copy of * Harbour, as the General Public License permits, the exception does * not apply to the code that you add in this way. To avoid misleading * anyone as to the status of such modified files, you must delete * this exception notice from them. * * If you write modifications of your own for Harbour, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. * */ #ifndef HB_CLASS_CH_ #define HB_CLASS_CH_ #include "hboo.ch" /* You can actually define one or all the syntax, they do not collide each other */ /* There is some difference with their original form and I hope I will have enough */ /* time to document it */ /* This is work in progress ... */ /* FWOBJECT AND CLASSY compatibility are the base of this work */ /* VO is just here as I like it's way of */ /* instantiating object but there is only a very few VO keywords here :-( */ /* TOPCLASS is better implemented because I like the way some Classy command */ /* are simplified */ /* There is also a big common block extending in fact each of the four base syntax */ /* it seem actually impossible to completely separate it without creating */ /* four different include files (what I would not see in fact ) */ /* There is also two compatibility define you can use */ /* HB_CLS_NOTOBJECT which IF DEFINED, disable the auto inherit of HBObject */ /* (which in fact also disable the classy compatibility :new(...) => :Init(...) */ /* HB_CLS_NOAUTOINIT which disable the (VO like) AutoInit for Logical, Numeric, */ /* Date and Timestamp when not specifically initiated */ /* These two are disabled by default */ /* So Each class _inherit_ of HBObject by default and */ /* Each logical, numeric, date and timestamp typed variable is initiated to */ /* .F., 0, CToD( "" ) and t"00:00" by default */ /* #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 */ /* #define HB_CLS_NO_DECLARATIONS */ /* disable value type declarations */ #ifndef HB_CLS_FWO #ifndef HB_CLS_CSY #ifndef HB_CLS_VO #ifndef HB_CLS_TOP /* IF NOTHING DECIDED BY THE PROGRAMMER USE ALL */ #define HB_CLS_FWO #define HB_CLS_CSY #define HB_CLS_VO #define HB_CLS_TOP #define HB_CLS_XPP #endif #endif #endif #endif /* Disable method decoration when Harbour compiled strict compatibility mode. In strict mode, PP doesn't support identifier concatenation, which would be needed for method decoration. */ #ifdef HB_CLP_STRICT #ifndef HB_CLS_NO_DECORATION #define HB_CLS_NO_DECORATION #endif #ifndef HB_CLS_PARAM_LIST #define HB_CLS_PARAM_LIST #endif #endif /* disable strict parameters validation in method declaration and implementation when warning level (-w?) is not 3 or higher */ #if __pragma( WARNINGLEVEL ) < 3 #ifndef HB_CLS_NO_PARAMS_ERR #define HB_CLS_NO_PARAMS_ERR #endif #endif /* should we use _ prefix for real method names? */ #ifdef HB_CLS_NO_DECORATION #xtranslate __HB_CLS_MTHNAME => #else #xtranslate __HB_CLS_MTHNAME => _ #endif /* parameters list passed throw - it's Harbour extension */ #ifndef HB_CLS_PARAM_LIST #define HB_CLS_PARAM_LIST ... #endif /* should we use _HB_CLASS/_HB_MEMBER declarations? */ #ifdef HB_CLS_NO_DECLARATIONS #xcommand _HB_CLASS => #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 different 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([]) => #xtranslate __HB_CLS_WARN([]) => #else #xtranslate __HB_CLS_ERR([]) => ;#error [ ] ; #line #xtranslate __HB_CLS_WARN([]) => ;#warning [ ] ; #line #endif /* disabled by default to not generate ignored by compiler noise in .ppo files */ #if 0 DECLARE HBClass ; New( cName AS String, OPTIONAL SuperParams ) AS CLASS HBClass ; Create() AS Object ; Instance() AS Object ; AddClsMethod( 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 ) #endif /* * 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:([ ]) /* Indirect super casting translation */ #xtranslate :Super( ): => :: #xtranslate __HB_CLS_OPT(,) => #xtranslate __HB_CLS_OPT() => #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( ([]) ) => [, ] /* #xtranslate __HB_CLS_VARERR() => __HB_CLS_ERR( Invalid instance variable name \<> ) #xtranslate __HB_CLS_ISVAR( ) => __HB_CLS_VARERR() #xtranslate __HB_CLS_ISVAR( ) => #xcommand __HB_CLS_CHECKVAR( [,] ) => __HB_CLS_ISVAR( ) [;__HB_CLS_ISVAR( )] */ /* #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! ) #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 */ #xcommand CLASS [METACLASS ] ; [ [,] ] ; [ ] ; [ ] [ FUNCTION ] => ; _HB_CLASS ;; function __HB_CLS_OPT( [,] ) ( HB_CLS_PARAM_LIST ) ;; STATIC s_oClass ;; LOCAL nScope, oClass, oInstance ;; IF s_oClass == NIL .AND. __clsLockDef( @s_oClass ) ;; BEGIN SEQUENCE ;; nScope := HB_OO_CLSTP_EXPORTED ; HB_SYMBOL_UNUSED( nScope ) ;; 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_ #xcommand ENDCLASS [] => ; oClass:Create() ; [<-lck-> __clsLock( oClass:hClass ) ] ;; ALWAYS ;; __clsUnlockDef( @s_oClass, oClass ) ;; END SEQUENCE ;; oInstance := oClass:Instance() ;; IF __objHasMsg( oInstance, "InitClass" ) ;; oInstance:InitClass( HB_CLS_PARAM_LIST ) ;; END ;; RETURN oInstance ;; END ;; 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 #xcommand __HB_CLS_DECLARE_METHOD => ; #xcommand METHOD \ CLASS _CLASS_IMPLEMENTATION_ => ; DECLARED METHOD \ CLASS #xcommand __HB_CLS_DECLARE_METHOD => ; #xcommand METHOD \ CLASS _CLASS_IMPLEMENTATION_ => ; DECLARED METHOD \ CLASS ;; #xcommand METHOD \ (\[ \] ) CLASS _CLASS_IMPLEMENTATION_ => ; DECLARED METHOD \ (\[ \] ) CLASS #xcommand METHOD CLASS _CLASS_IMPLEMENTATION_ => ; __HB_CLS_WARN( Method \<> not declared or declaration mismatch in class \<> ) ;; DECLARED METHOD CLASS #xcommand METHOD [ ] [ AS ] [ ] [] [