Here's the first revision of an IDL interface rules document that I've
put together.

Developers, please read over this document to learn how to write proper
scriptable interfaces.

Reviewers, direct people to this document whenever you review code with
bad IDL....

Everyone, I'm looking for more rules/advice/suggestions.. One thing I'm
going to add is a section on types (mapping to C++, etc)

http://www.mozilla.org/projects/xpcom/interface-rules.html

Title: IDL interface rules
The Mozilla
Organization
At A Glance
Feedback
Get Involved
Newsgroups
License Terms
Newsbot
Developer Docs
Roadmap
Projects
Ports
Module Owners
Hacking
Get the Source
Build It
Testing
Download
Report A Bug
Bugzilla
Bug Writing
Tools
View Source
Tree Status
New Checkins
Submit A Bug
FAQ
Search

IDL interface rules

This document describes some do's and don'ts when writing an interface in IDL for mozilla.

Rule: Use interCaps for naming. All methods and attributes should begin with a lowercase letter. Every subsequent word in the method or attribute name should be capitalized. Avoid capitalizing first letters and using underscores to seperate words.
Why: IDL usually follows JavaScript convention, which is intercaps. In addition, the first letter of all names are promoted to upper case in C++. The C++ signature is the same whether or not the first letter is capitalized.

  • Bad:
    /* don't capitalize first letters! */
    void OpenFile(in nsIFile file);
    attribute AString Filename;
    /* Avoid underscores! */
    attribute long unknown_entries;
  • Good:
    void openFile(in nsIFile file);
    attribute AString filename;
    attribute long unknownEntries;

Rule: Use attributes wherever you are referring to a single, non-dynamic value.
Why: Scripted access to the interface is easier to read. Combining two get/set methods into a single attribute also syntactically shows their relevance. Methods also imply some sort of action or side effect.

  • Bad:
    /* These refer to the same value, why make them functions? */
    long getColorValue();
    void setColorValue(in long value);

    /* we just want a getter, but we can still use an attribute!
     * besides, a method implies an action. */
    long brightness();
  • Good:
    attribute long colorValue;
    readonly attribute long brightness;

Rule: Avoid excessivly long names, but keep them readable. Don't abbreviate words. Avoid names that involve prepositions like "of" or "on"
Why: Its easier to use methods/attributes with shorter names, but it is easy to confuse shortened names, especially for non-english speakers.

  • Bad:
    /* seems a bit verbose */
    readonly attribute long numberOfEntries;

    /* why shorten this? is this Attribute? Attrition? */
    long getAttrCount(in ACString name);
  • Good:
    readonly attribute long entryCount;
    long getAttributeCount(in ACString name);

Rule: Use ACString to represent ASCII strings or binary string-like data.
Why: The "A" string classes are more efficient than the "string" type. They include the length of the string passed in, and avoid excess allocations. They also allow for subfragments of existing strings without copying, and multi-fragment strings.

  • Bad:
    /* use the new string classes! */
    void processName(in string name);

    /* high bit will get stripped by XPConnect. is that ok? */
    void fillBuffer(in string data);

    /* new string classes will avoid excess allocation,
     * especially when the caller uses nsCAutoString */
    void getHeaderValues(out string prefix, out string postfix);
  • Good:
    void processName(in ACString name);
    void fillBuffer(in ACString data);
    void getHeaderValues(out ACString prefix, out ACString postfix);

Rule: Use AString or UTF8 string to represent unicode strings. Avoid the "wstring" type where possible.
Why: The "A" string classes are more efficient than the old "wstring" type. XPConnect will properly convert to/from UTF8.

  • Bad:
    /* Even if errorMsg is UTF8, it will get corrupted by XPConnect */
    void displayError(in string errorMsg);

    /* use AString to allow fragment to have a length */
    void parseFragment(in wstring fragment);
  • Good:
    void displayError(in AUTF8String errorMsg);
    void parseFragment(in AString fragment);

Rule: Avoid out parameters, especially when a method has only one out parameter. Use the return value of a function instead
Why: out parameters are extra work for scripts, which must create a temporary object to hold the resulting value.

  • Bad:
    /* This will be frustrating to call from a script */
    void getHeaderValue(in ACString header, out AString value);
  • Good:
    AString getHeaderValue(in ACString header);

Rule: Try to #include only other .idl files. If you need access to a C++0only type, try to predeclare it and rely on C++ consumers to #include the correct header.
Why: Generated C++ headers will differ from the IDL, causing confusion as to what classes have been defined. If you predeclare a type and then #include a .h file in order to get the definition, you may have problems with the generated header if the #included .h file changes later.

  • Bad:
    %{C++
    #include "nsIInputStream.h"
    %}
  • Good:
    interface nsIInputStream;

Alec Flett
Last modified: Wed Sep 4 17:15:00 PDT 2002
Copyright © 1998-2002 The Mozilla Organization.
Last modified September 4, 2002.
Document History.
Edit this Page.

Reply via email to