You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.



XPIDL syntax (strawman)

Last modified: Mon Dec 14 15:14:10 EST 1998

XPIDL should be able to faithfully represent XPCOM interfaces, with minimal change to the interface introduced during the switch from hand-coded interfaces to generated ones.

Some thoughts on XPIDL and XPCOM:

  • NS_IMETHOD is the near-universal return type for XPCOM interface methods, so that methods can use a consistent protocol for reporting errors. In IDL, we'll say that the method returns void and raises (nsError). Where the NS_IMETHOD_(type) macro is used for a method, we will instead return type and still raise nsError. (The nsError IDL specification will include a type field compatible with the NS_* defines, etc.) Update: I'm now thinking of doing away with the raises nsError setup, and just moving away from NS_IMETHOD_(type) in C++ headers. This will require a one-time update of the various interfaces to have an additional out parameter to replace the old return type, but that's not too bad of a scene. Resolution: the return type, if non-void will become a final out param, except when it has to appear after the varargs entry (q.v.).
  • Many interfaces specify methods of the form SetFoo without a corresponding GetFoo method. Using the IDL attribute int foo syntax will cause a GetFoo to be generated as well. I don't think that's a big deal, but if it is we could try adding a writeonly attribute or something.
  • OMG IDL doesn't have a notion of in nsIFoo *aFooPtr, so we need to either agree that any in nsIFoo is passed as nsIFoo *aFooPtr in C++, and therefore switch the use of nsRect &aRect to be nsRect *aRectPtr or something. Ideas are more than welcome. Resolution: all interfaces are passed as pointers (double-indirect for out/inout), and we'll do the same for structs, I think. (Some resolution.)
  • We need varargs and probably a ``function'' type for some of the DOM stuff, and that sort of thing might be generally useful. Given JS impersonation of XPCOM interfaces, we could do the CORBA thing and just require that an object has methods (properties?) with the right names, which might take care of the ``function type''. For varargs, I think I'll turn something like:
    void method(in string arg1, ...);
    into:
    NS_IMETHOD method(nsString *arg1, const char *varfmt, ...); Resolution: The IDL will use ..., and that will become nsVarArgs *_varargs, where nsVarArgs is likely a struct. Function type will be provided by JS impersonation of XPCOM interfaces, which will just generally rock.
Sample IDL for nsIToolbar:

    interface nsIToolbar : nsISupports {

      readonly attribute boolean visible;
      attribute int hGap;
      attribute int vGap;
      attribute int margin;
      attribute boolean horizontalLayout;
      attribute boolean lastItemIsRightJustified;
      attribute boolean lastItemIsStretchy;
      attribute nsIToolbarManager toolbarManager;
      attribute nsToolbarBorderType borderType;
      attribute boolean wrapping;

      void AddItem(in nsIToolbarItem anItem,
                   in int aLeftGap,
                   in boolean stretchable);

      void InsertItemAt(in nsIToolbarItem anItem,
	                in int aLeftGap,
                        in boolean aStretchable,
                        in int anIndex);
      
      void GetItemAt(out nsIToolbarItem anItem,
                     in int anIndex);

      void GetPreferredSize(out int aWidth,
                            out int aHeight);

      void GetPreferredConstrainedSize(in int aSuggestedWidth,
                                       in int aSuggestedHeight,
                                       out int aWidth,
                                       out int aHeight);

      void DoLayout();

      nsEventStatus HandleEvent(in nsGUIEvent aEvent);

      nsEventStatus OnPaint(in nsIRenderingContext aRenderingContext,
                            in nsRect aDirtyRect);

      void CreateTab(out nsIWidget aTab);

    }
      
More sample IDL:
#include "nsISupports.idl"

%{ C++
/* this goes into the C++ header verbatim. */
#include "someCplusplus.h"
rawType rawVar;
%}

[
        uuid(4A781D61-3D28-11d2-8DB8-00609703C14E)
]
interface nsITest : nsISupports {
  /* a comment */
  attribute boolean visible;
  readonly attribute string name;

  /* method with a return type */
  boolean method(in string bogo, out string mips);

  /* a varargs method */
  void printf(in string format, ...);

  /* a varargs with return */
  long sprintf(out string filled, in string format, ...);

};
The output (still needs some pretty-printing and stuff):
/*
 * DO NOT EDIT.  THIS FILE IS GENERATED FROM nsITest.idl
 */

#ifndef __nsITest_h__
#define __nsITest_h__

#include "nsISupports.h" /* interface nsISupports */

/* this goes into the C++ header verbatim. */
#include "someCplusplus.h"
rawType rawVar;

/* starting interface nsITest */

/* {4A781D61-3D28-11d2-8DB8-00609703C14E} */
#define NS_ITEST_IID_STR "4A781D61-3D28-11d2-8DB8-00609703C14E"
#define NS_ITEST_IID \
  {0x4A781D61, 0x3D28, 0x11d2, \
    { 0x8D, 0xB8, 0x00, 0x60, 0x97, 0x03, 0xC1, 0x4E }}

class nsITest : public nsISupports {
 private:
  void operator delete(void *); // NOT TO BE IMPLEMENTED

 public: 
  static const nsIID& IID() {
    static nsIID iid = NS_ITEST_IID;
    return iid;
  }

  /* attribute boolean visible; */
  NS_IMETHOD IsVisible(PRBool *aIsVisible);
  NS_IMETHOD SetVisible(PRBool aVisible) = 0;

  /* readonly attribute string name; */
  NS_IMETHOD GetName(char * *aName) = 0;

  /* boolean method(in string bogo, out string mips); */
  NS_IMETHOD method(const char *bogo, char **mips, PRBool *_retval) = 0;

  /* void printf(in string format, ...); */
  NS_IMETHOD printf(const char *format, ...) = 0;

  /*  sprintf(out string filled, in string format, ...); */
  NS_IMETHOD sprintf(char **filled, const char *format,
                     PRInt32 *_retval, ...) = 0;
};

#endif /* __nsITest_h__ */

    

Mike Shaver