Macro: HANDLE$MESSAGE$2
#IFDEF UI.EXISTS
#ELSE
USE UI
#ENDIF
// if the publish meta-attribute is set, we want to generate the RegisterInterface command before we do anything in this new method.
// we will also check as many things as possible to make sure this is a valid place for this. We expect this:
// 1. to appear in classes and not objects
// 2. cannot be global, FOR, or desktop
// 3. cannnot be override
// If the meta attribute Published is true, we handle special case for webapps.
// note I am not checking for the Mangle_names ifdef - I just assume it's true (hasn't been unset for many versions).
#IFMATTR Published true // This is true if the Published attribute is active and its value is true
// method must be an object method and not For, global or overloaded
#IFSAME !3 GLOBAL FOR OVERLOADED // any of these are not allowed. Note that DESKTOP is already converted to For cDesktop at this point
#ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT "The Publish meta tag cannot be used with GLOBAL, DESKTOP, FOR, or OVERLOADED methods."
#ELSE
#IF (!b = 1) // the only valid place for this is within a method within an object.
MESSAGE$ADDRESS !1_!2 // create id symbol for this message. We do this to avoid fowward reference error in registerInterface
#SPUSH
#PUBLISH // This creates the Send RegisterInterface line and puts the result in !$, based on the original source line which is expected to be something like Function Foo Integer iArg...
!$ // This would then actually call Send RegisterInterface
#REM !$
#SPOP
#ELSE
#ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT "The Publish meta tag can only be used within methods defined directly inside of objects."
#ENDIF
#ENDIF
#ENDIF
// procedure construct_object only allowed in class
#IF (!b & 1) // if in object
#IFDEF MANGLE_NAMES
#IFSAME !1 MSG
#IFSAME !2 CONSTRUCT_OBJECT
#ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT Construct_object .not. allowed in objects
#ENDIF
#ENDIF
#ELSE
#IFSAME !1 MSG_CONSTRUCT_OBJECT
#ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT Construct_object .not. allowed in objects
#ENDIF
#ENDIF
#ENDIF
// not allowed to nest methods
// Check flag to determine whether we are already in a method.
#IF (!b & 4)
#ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT Procedures and Functions may .not. be nested.
#ELSE
// non global methods are not allowed class child-objects
#IFNDEF MANGLE_NAMES
#IFSAME !2 GLOBAL
#ELSE
#IF ((!b & 3)=3) // if in class object
#ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT Methods .not. allowed in class child-objects
#ENDIF
#ENDIF
#ELSE
#IFSAME !3 GLOBAL
#ELSE
#IF ((!b & 3)=3) // if in class object
#ERROR DFERR_COMP_ILLEGAL_CODE_PLACEMENT Methods .not. allowed in class child-objects
#ENDIF
#ENDIF
#ENDIF
#ENDIF
// Give error if the stack symbol NUM_ARGUMENTS is defined.
#CHECK NUM_ARGUMENTS _T
//
#SET ZN$ !n // static nesting level
#SET ZM$ 0 // # objects in method
#PUSH !Zg
#PUSH !Za
#SET ZA$ !a
#PUSH !Zu
#DATA
#STKSYM // forget all old stack symbols
#SET B$ (!b | 4) // set flag to in_procedure
// This was changed to allow us to prohibit arguments with num_arguments inside the scope of a function.
#REPLACE NUM_ARGUMENTS |SI0 // define the arg count
#IFDEF MANGLE_NAMES
#SREP __@INSIDE_FUNCTION@__ |CI1 // lets other commands check that they are inside a function scope.
#ENDIF
#IFNDEF MANGLE_NAMES
#ELSE
// This is the mangling code.
#IFSAME !3 GLOBAL
#DPUSH |CI0 // No message
#DPUSH |CI0 // for no class
// Check if overloaded symbol is already defined.
#IFSAME OVERLOADED !4 !5 !6 !7 !8 !9
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION Global functions/procedures cannot be overloaded
#ELSE
#IFDEF !1_!2_OVERLOADED
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION This Method Was Previously Defined As Overloaded
#ELSE
#IFDEF !1_!2
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION Global method !1 !2 Already Defined
#ELSE
#SET ZG$ (0-!a-2) // make it negative to distuinguish it
#REPLACE !1_!2 |CI!Zg
#ENDIF
#ENDIF
#ENDIF
CHECK$METHOD$ARGUMENT$LIST !4 !5 !6 !7 !8 !9
#IF (!0>1) // do we have arguments?
#SET ZG$ 1 // starting argument number
DEFINE_ARGUMENTS !4 !5 !6 !7 !8 !9
#ENDIF
HANDLE$MESSAGE$HELP !1 !1_!2 !3 !4 !5 !6 !7 !8 !9
#ELSE // not global functions
// make sure message is not already defined as a global
#IFDEF !1_!2
#IF (!1_!2<0) // if defined as a global already, we have an error
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION !1 !2 already defined as a Global method
#ENDIF
#ENDIF
// Mangling case & Using FOR
#IFSAME !3 FOR // are we explicit about the class?
#IFSAME OVERLOADED !5 !6 !7 !8 !9
#IFDEF !1_!2
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION This Method Was Previously Defined As non-overloaded
#ELSE
// we don't support Byref with overloading
#IFSAME BYREF !5 !6 !7 !8 !9
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION "BYREF not allowed in overloaded methods"
#ENDIF
// Mangle name of method.
#MARG !1_!2 !5 !6 !7 !8 !9
// Also lock name without parameters and sugar.
#IFNDEF !1_!2_OVERLOADED
#REPLACE !1_!2_OVERLOADED |CI1
#ENDIF
MESSAGE$ADDRESS !? // create id symbol for this message
#DPUSH !?
#ENDIF
#ELSE // FOR class, but not an overloaded function.
#IFDEF !1_!2_OVERLOADED
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION This Method Was Previously Defined As Overloaded
#ELSE
MESSAGE$ADDRESS !1_!2 // create id symbol for this message
#DPUSH !1_!2
#ENDIF
#ENDIF
#IFDEF !4
#IFSAME !4 DESKTOP
#IFDEF IS$WINDOWS
#DPUSH U_cObject // Message for the desktop class
#ELSE
#DPUSH U_DESKTOP // Message for the desktop class
#ENDIF
#ELSE
#DPUSH !4 // Message for the named class
#ENDIF
#ELSE
#CHECK U_!4 _RSDNU // Check the class to see if it exists.
#DPUSH U_!4 // Message for the named class
#ENDIF
CHECK$METHOD$ARGUMENT$LIST !5 !6 !7 !8 !9
#IF (!0>3)
#SET ZG$ 1 // starting argument number
DEFINE_ARGUMENTS !5 !6 !7 !8 !9
#ENDIF
#IFSAME OVERLOADED !4 !5 !6 !7 !8 !9 // Non global
HANDLE$MESSAGE$HELP !1 !? !5 !6 !7 !8 !9
#ELSE
HANDLE$MESSAGE$HELP !1 !1_!2 !5 !6 !7 !8 !9
#ENDIF
#ELSE // Method is declared in a class or in an object
#IF (!b & 2) // obj_flag == in_class?
#ELSE
#IF (!b & 1) // in_object, instance method
!A [] CLONE$CLASS // if in object, clone the class
#ENDIF
#ENDIF
#IFSAME OVERLOADED !3 !4 !5 !6 !7 !8 !9
#IFDEF !1_!2
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION This Method Was Previously Defined As non-overloaded
#ELSE
// we don't support Byref with overloading
#IFSAME BYREF !3 !4 !5 !6 !7 !8 !9
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION "BYREF not allowed in overloaded methods"
#ENDIF
#MARG !1_!2 !3 !4 !5 !6 !7 !8 !9
MESSAGE$ADDRESS !?
#IFNDEF !1_!2_OVERLOADED
#REPLACE !1_!2_OVERLOADED |CI1
#ENDIF
#DPUSH !? // the message
#ENDIF
#ELSE
// a non-overlaoded message
#IFDEF !1_!2_OVERLOADED
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION This Method Was Previously Defined As Overloaded
#ELSE
MESSAGE$ADDRESS !1_!2 // create id symbol for this message
#DPUSH !1_!2
#ENDIF
#ENDIF
// push the proper destination for the message
#IF (!b & 2) // obj_flag == in_class?
#DPUSH U_!$ // handle msg for "current class"
#ELSE
#IF (!b & 1) // in_object, instance method
#DPUSH |CI0 // handle for objects class
#ELSE // Message is out on desktop and not identfied w/ FOR Xxxxx
#IFDEF IS$WINDOWS // 8.3: if windows we are going to place this on the cDesktop object
// which will allow all objects to delegate to it, which is probably
// what people expect. Prior to 8.3, it create a "for desktop" so all classes/objects
// immediately understood this. This represents a change in behavior.
#REM Ambiguous methods on .DESKTOP. are .not. recommended (Obsolete technique)
// this is not a real error but we can use this to look at ambiguous desktop methods to make make sure
// that they are being used in the proper 8.3 style. This warning is controlled by the method
// Compiler_desktop_method_warnings ON|OFF (OFF is default)
#IF (!Zl & 4)
#ERROR DFERR_COMP_ILLEGAL_METHOD_DEFINTION Ambiguous method on .Desktop. Should be "Desktop" or "Global" or moved.
#ENDIF
#DPUSH U_cObject // Message for the desktop (UI_OBJECT) class. Not advised for VDF after 8.2
#ELSE
#DPUSH U_DESKTOP // Message for the desktop (UI_OBJECT) class. Not advised for VDF after 8.2
#ENDIF
#ENDIF // stand alone message that gets defined as U_DESKTOP
#ENDIF // end of else of object method
CHECK$METHOD$ARGUMENT$LIST !3 !4 !5 !6 !7 !8 !9
#IF (!0>1) // do we have arguments?
#SET ZG$ 1 // starting argument number
DEFINE_ARGUMENTS !3 !4 !5 !6 !7 !8 !9
#ENDIF
#IFSAME OVERLOADED !3 !4 !5 !6 !7 !8 !9
HANDLE$MESSAGE$HELP !1 !? !3 !4 !5 !6 !7 !8 !9
#ELSE
HANDLE$MESSAGE$HELP !1 !1_!2 !3 !4 !5 !6 !7 !8 !9
#ENDIF
#ENDIF // class method
#ENDIF
#ENDIF // mangling case
// !A [] HANDLE$FOR |CI0 |VL // handle the message
!A [] $0454 |CI0 |VL
#FREF OBJ$!Za$ENDPROC !a // fref the end procedure line
#IFDEF MANGLE_NAMES
// MG added code here to check the parameter count.
#IFDEF !1_!2_OVERLOADED
// Check parameter count
#DATA
#DPUSH NUM_ARGUMENTS
#DPUSH |CI!Zg
#DPUSH !?
#IFSAME !1 GET
#DPUSH |CI1
#ELSE
#IFSAME !1 MSG
#DPUSH |CI2
#ELSE
#IFSAME !1 SET
#DPUSH |CI3
#ENDIF
#ENDIF
#ENDIF
!A [] $0467 |CI0 |VL
#FORBID NUM_ARGUMENTS 300 "NUM_ARGUMENTS was used in an overloaded method"
#ENDIF
#ENDIF
#SET ZG$ 0 // starting argument number for locals
// JJT - changed in 9.1. This used to occur when the first local was created. Since this is executed at runtime
// this created a situation where the first local might be in a block that is not executed. When moved to here
// the local init command is always executed. We still strongly discourage the declartion of variables anywhere
// accept the top of a method block. This simply fixes and unintended side-effect of our implementation.
//!A [] LOCAL$ARGUMENT |CI0 // Create the command to save the local count,
!A [] $0456 |CI0
#FREF OBJ$!Za$LNUM !a // and tell flex to update it later.