#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.