W3C

Language Bindings for DOM Specifications

W3C Working Draft 17 October 2007

This Version:
http://www.w3.org/TR/2007/WD-DOM-Bindings-20071017/
Latest Version:
http://www.w3.org/TR/DOM-Bindings/
Editor:
Cameron McCormack, Invited Expert <cam@mcc.id.au>

Abstract

This specification defines an Interface Definition Language (IDL) to be used by specifications that define a Document Object Model (DOM). How interfaces described with this IDL correspond to constructs within ECMAScript and Java execution environments is also detailed.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is the 17 October 2007 First Public Working Draft of the “Language Bindings for DOM Specifications” specification. Please send comments about this document to public-webapi@w3.org (archived) with “[Bindings]” at the start of the subject line.

“Language Bindings for DOM Specifications” is intended to specify in detail the IDL language used by W3C specifications to define DOM interfaces, and to provide precise conformance requirements for ECMAScript and Java bindings of such interfaces. It is expected that this document acts as a guide to implementors of already-published DOM specifications, and that newly published DOM specifications reference this document to ensure conforming implementations of DOM interfaces are interoperable.

This document is produced by the Web API Working Group, part of the Rich Web Clients Activity in the W3C Interaction Domain. Changes made to this document can be found in the W3C public CVS server.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1. Introduction

This section is informative.

Specifications published by the W3C that include Document Object Model (DOM) interfaces are typically described using the Object Management Group’s Interface Definition language (IDL) [OMGIDL]. The IDL provides a means to describe these interfaces in a language independent manner. Usually, additional language binding appendices are included in such specifications which detail how the interfaces described with the IDL correspond to constructs in the given language.

However, the bindings in these specifications for the language most commonly used on the web, ECMAScript, are consistently specified with low enough precision as to result in interoperability issues. In addition, each specification must describe the same basic information, such as DOM interfaces described in IDL corresponding to properties on the ECMAScript global object, or the unsigned long IDL type mapping to the Number type in ECMAScript.

This specification defines a subset of OMG IDL version 3.0 for use by DOM specifications. A number of extensions are given to the IDL to support common functionality that previously must have been written in prose. In addition, precise language bindings for ECMAScript 3rd Edition and Java are given.

2. Conformance

Everything in this specification is normative except for diagrams, examples, notes and sections marked as being informative.

The keywords “must“, “must not”, “required”, “shall”, “shall not”, “recommended”, “may” and “optional” in this document are to be interpreted as described in [RFC2119].

The following conformance classes are defined by this specification:

conforming IDL fragment

An IDL fragment is considered to be a conforming IDL fragment if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to IDL fragments.

conforming implementation

A user agent is considered to be a conforming implementation with respect to a conforming IDL fragment if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to implementations for all language bindings that the user agent supports.

conforming ECMAScript implementation

A user agent is considered to be a conforming ECMAScript implementation with respect to a conforming IDL fragment if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to implementations for the ECMAScript language binding.

conforming Java implementation

A user agent is considered to be a conforming Java implementation with respect to a conforming IDL fragment if it satisfies all of the must-, required- and shall-level criteria in this specification that apply to implementations for the Java language binding.

3. Interface definition language

This section describes a language with which interfaces can be defined in a language independent manner. This language is based on the Object Management Group’s Interface Definition Language [OMGIDL], and is syntactically a subset thereof.

An IDL fragment is a sequence of definitions that matches the Definitions non-terminal in the grammar. See Appendix A for the complete grammar and an explanation of the notation used.

Each definition (matching Definition) can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how the definition will be handled in language bindings. The extended attributes defined by this specification are discussed in section 3.8 below.

A definition is said to be declared at the outermost scope if there is no Module ancestor of the non-terminal representing the definition in the parse tree for the IDL fragment. Conforming IDL fragments should not have any non-module definitions declared at the outermost scope.

A definition has been declared previously, relative to a given scoped name that resolved to the definition, if:

[1]DefinitionsExtendedAttributeList Definition Definitions
 | ε
[2]DefinitionModule
 | Interface
 | Exception
 | Typedef
 | Valuetype
 | Const
Editorial note

Each of the sections below needs examples.

3.1. Names

The first identifier terminal in a derivation of a Definition, InterfaceMember or ExceptionMember determines the identifier of that definition, interface member or exception member (respectively) as follows:

  • If the value of the identifier terminal begins with a U+005F LOW LINE ("_") character, then the identifier of the definition, interface member or exception member is the value of the identifier terminal without that leading U+005F LOW LINE ("_") character.
  • Otherwise, the value of the identifier terminal does not begin with a U+005F LOW LINE ("_") character. The identifier of the definition, interface member or exception member is the value of the identifier terminal.

The identifier of a definition must be locally unique to the module in which the definition occurred.

Every definition also has a qualified name, which must be globally unique to the IDL fragment in which it is defined. The qualified name of a definition is defined as follows:

A scoped name is a string formed from the concatenation of the terminal values (removing any leading U+005F LOW LINE ("_") characters from the value of identifier terminals, as in the rules for identifiers) in the derivation of a ScopedName non-terminal. The scoped name can be either an absolute scoped name if it begins with two consecutive U+003A COLON (":") characters, or a relative scoped name if it does not.

A scoped name can be resolved, with respect to a given module, to a definition as follows:

  • If the scoped name is a relative scoped name, then:
    • If there exists a definition whose qualified name is equal to the concatenation of the qualified name of the module, two U+003A COLON (":") characters and the scoped name, then the scoped name resolves to that definition.
    • Otherwise, if there exists a definition whose qualified name is equal to the concatenation of two U+003A COLON (":") characters and the scoped name, then the scoped name resolves to that definition.
    • Otherwise, the scoped name does not resolve to a definition.
  • Otherwise, the scoped name is an absolute scoped name:
    • If there exists a definition whose qualified name is equal to the scoped name, then the scoped name resolves to that definition.
    • Otherwise, the scoped name does not resolve to a definition.
[40]ScopedName"::" identifier ScopedNameParts
 | identifier ScopedNameParts
[41]ScopedNameParts"::" identifier ScopedNameParts
 | ε

3.2. Modules

A module is a definition that matches the Module non-terminal, and which serves as a container for other definitions.

The enclosing module of a definition is defined as follows:

The relevant language binding determines how modules affect the naming of constructs that correspond to definitions in the language. If the language supports some form of namespacing mechanism, then a module will correspond to a namespace.

The following extended attributes are applicable to modules: [ExceptionConsts].

[3]Module"module" identifier "{" Definitions "}" ";"

3.3. Interfaces

An interface is a definition that matches the Interface non-terminal whose InterfaceBody is not empty (i.e., it is not the case that InterfaceBody ⇒ ε). An interface is a specification of a set of interface members, which are the constants, attributes and operations given by the InterfaceMembers part of the InterfaceBody. Objects implementing the interface need to have members that correspond to each of the interface’s members.

The identifier of an interface member is given by the first identifier terminal in a derivation of the non-terminal that represents the interface member. The identifier of an interface member must be unique within the interface on which it is defined.

An interface inherits from another if there is a scoped name in the ScopedNameList that, with respect to the enclosing module of the interface, resolves to that inherited interface. Every scoped name in the ScopedNameList must resolve to an interface whose definition occurs before the definition of the inheriting interface. An object that implements an interface that inherits from another also implements that inherited interface. The object therefore needs also to have members that correspond to the interface members from the inherited interface.

Each interface member can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how the interface member will be handled in language bindings.

The relevant language binding determines how interfaces correspond to constructs in the language. Many object-oriented languages support interfaces, in which case the mapping of IDL interfaces to language interfaces is simple.

An interface forward declaration is a definition that matches the Interface non-terminal whose InterfaceBody is empty (i.e., InterfaceBody ⇒ ε). A forward declaration is used to introduce an interface name to allow for the definition of mutually recursive interfaces, since scoped names need to resolve to types that have been declared previously.

The following extended attributes are applicable to interfaces: [Constructor].

[4]Interface"interface" identifier InterfaceBody ";"
[5]InterfaceInheritance":" ScopedNameList
 | ε
[6]InterfaceBodyInterfaceInheritance "{" InterfaceMembers "}"
 | ε
[7]InterfaceMembersExtendedAttributeList InterfaceMember InterfaceMembers
 | ε
[8]InterfaceMemberConst
 | Attribute
 | Operation
[38]ScopedNameListScopedName ScopedNames
[39]ScopedNames"," ScopedName ScopedNames
 | ε

3.3.1. Constants

A constant is a definition that matches the Const non-terminal, and is used to bind a constant value to a name. Constants can appear on interfaces and also at the module or outermost scope.

The ConstExpr part of a constant definition gives the value of the constant, which can be one of the two boolean literal terminals ("TRUE" and "FALSE"), an integer terminal or a float terminal.

The value of the boolean literal terminals are as follows:

  • The value of the "TRUE" terminal is a value of type boolean: true.
  • The value of the "FALSE" terminal is a value of type boolean: false.

The value of an integer terminal is determined as follows:

  1. Let S be the string value of the integer terminal.
  2. Let n be the length of S.
  3. Initialize mag to 0.
  4. Initialize sign to 1.
  5. Initialize base to 10.
  6. Initialize i to 0.
  7. If the first character of S is not U+002D HYPHEN-MINUS ("-"), then go to step 10.
  8. Set sign to −1.
  9. Set i to 1.
  10. If the ith zero-based character of S is not U+0030 DIGIT ZERO ("0"), then go to step 16.
  11. Set base to 8.
  12. Set i to i + 1.
  13. If the ith zero-based character of S is not U+0058 LATIN CAPITAL LETTER X ("X") or U+0078 LATIN SMALL LETTER X ("x"), then go to step 16.
  14. Set base to 16.
  15. Set i to i + 1.
  16. Let digit be the value obtained by looking up the ith zero-based character of S in the table below:
    CharacterValue of digit
    U+0030 DIGIT ZERO ("0")0
    U+0031 DIGIT ONE ("1")1
    U+0032 DIGIT TWO ("2")2
    U+0033 DIGIT THREE ("3")3
    U+0034 DIGIT FOUR ("4")4
    U+0035 DIGIT FIVE ("5")5
    U+0036 DIGIT SIX ("6")6
    U+0037 DIGIT SEVEN ("7")7
    U+0038 DIGIT EIGHT ("8")8
    U+0039 DIGIT NINE ("9")9
    U+0041 LATIN CAPITAL LETTER A ("A")10
    U+0041 LATIN CAPITAL LETTER B ("B")11
    U+0041 LATIN CAPITAL LETTER C ("C")12
    U+0041 LATIN CAPITAL LETTER D ("D")13
    U+0041 LATIN CAPITAL LETTER E ("E")14
    U+0041 LATIN CAPITAL LETTER F ("F")15
    U+0061 LATIN SMALL LETTER A ("a")10
    U+0061 LATIN SMALL LETTER B ("b")11
    U+0061 LATIN SMALL LETTER C ("c")12
    U+0061 LATIN SMALL LETTER D ("d")13
    U+0061 LATIN SMALL LETTER E ("e")14
    U+0061 LATIN SMALL LETTER F ("f")15
  17. Set mag to mag * base + digit.
  18. Set i to i + 1.
  19. If i < n, go to step 16.
  20. The value of the integer terminal is sign * mag.

The type of an integer terminal is the same as the type of the constant it is being used as the value of. The value of the integer terminal must not lie outside the valid range of values for its type, as given in section 3.7 below.

The type of a float terminal is float, and its value is determined as follows:

  1. Let S be the string value of the float terminal.
  2. Let n be the length of S.
  3. Initialize mant to 0.
  4. Initialize sign to 1.
  5. Initialize exp1 to 0.
  6. Initialize exp2 to 0.
  7. Initialize expSign to 1.
  8. Iniitalize afterDot to false.
  9. Initialize i to 0.
  10. If the first character of S is not U+002D HYPHEN-MINUS ("-"), then go to step 13.
  11. Set sign to −1.
  12. Set i to 1.
  13. If the ith zero-based character of S is U+0045 LATIN CAPITAL LETTER E ("E") or U+0045 LATIN SMALL LETTER E ("e"), then go to step 23.
  14. If the ith zero-based character of S is not U+002E FULL STOP ("."), then go to step 17.
  15. Set afterDot to true.
  16. Go to step 20.
  17. Let digit be the Unicode codepoint of the ith zero-based character of S minus 48.
  18. Set mant to mant * 10 + digit.
  19. If afterDot is true, set exp1 to exp1 − 1.
  20. Set i to i + 1.
  21. If i < n, go to step 13.
  22. Go to step 33.
  23. Set i to i + 1.
  24. If the ith zero-based character of S is not U+002D HYPHEN-MINUS ("-"), then go to step 27.
  25. Set expSign to −1.
  26. Set i to i + 1.
  27. If the ith zero-based character of S is not U+002B PLUS SIGN ("+"), then set i to i + 1.
  28. Let digit be the Unicode codepoint of the ith zero-based character of S minus 48.
  29. Set exp2 to exp2 * 10 + digit.
  30. Set i to i + 1.
  31. If i < n, go to step 33.
  32. Go to step 28.
  33. The value of the float terminal is the IEEE 754 floating point number closest to sign * mant * 10expSign * exp2 + exp1. [IEEE-754]

A constant must be assigned a value of the same type that the constant is declared to be.

No extended attributes are applicable to constants.

[13]Const"const" DeclarationType identifier "=" ConstExpr ";"
[14]ConstExprBooleanLiteral
 | integer
 | float
[15]BooleanLiteral"TRUE"
 | "FALSE"

3.3.2. Attributes

An attribute is an interface member that matches the Attribute non-terminal, and is used to declare that objects implementing the interface will have an attribute with the given identifier that can be assigned and retrieved.

The type of the attribute is given by the DeclarationType non-terminal. If the DeclarationType is a scoped name, then it must resolve, with respect to the enclosing module of the interface on which the attribute is defined, to an interface, typedef or boxed valuetype that has been declared previously.

The attribute is read only if the "readonly" terminal is used in the definition. An object that implements the interface on which a read only attribute is defined will not allow assignment to that attribute. It is language binding specific whether assignment is simply disallowed by the language, ignored or an exception is thrown.

The GetRaises and SetRaises clauses are used to declare the possible exceptions that can be thrown when retrieving the value of and assigning a value to the attribute, respectively. Each scoped name in the GetRaises and SetRaises clauses must resolve, with respect to the enclosing module of the interface on which the attribute is defined, to an exception that has been declared previously.

Editorial note

Should conforming implementations have a requirement that they must not raise an exception (that was defined in the IDL) that is not in the getraises/setraises list?

The following extended attributes are applicable to attributes: [NoNull], [PutForwards].

[16]AttributeReadOnly "attribute" DeclarationType identifier GetRaises SetRaises ";"
[17]ReadOnly"readonly"
 | ε
[18]GetRaises"getraises" ExceptionList
 | ε
[19]SetRaises"setraises" ExceptionList
 | ε
[22]ExceptionList"(" ScopedNameList ")"

3.3.3. Operations

An operation is an interface member that matches the Operation non-terminal, and is used to declare that objects implementing the interface will have a method with the given identifier.

The return type of the operation is given by the ReturnType non-terminal. A return type of "void" indicates that the operation returns no value. If the DeclarationType is a scoped name, then it must resolve, with respect to the enclosing module of the interface on which the operation is defined, to an interface, typedef or boxed valuetype that has been declared previously.

The ArgumentList non-terminal gives the list of arguments for the operation. The identifier of an argument is given by the identifier terminal in the Argument, and the type of the argument is given by the DeclarationType. If the DeclarationType is a scoped name, then it must resolve, with respect to the enclosing module of the interface on which the operation is defined, to an interface, typedef or boxed valuetype that has been declared previously.

Each argument can be preceded by a list of extended attributes (matching ExtendedAttributeList), which can control how a value passed as the argument value will be handled in language bindings.

The Raises clause is used to declare the possible exceptions that can be thrown when invoking the operation. Each scoped name in the Raises clause must resolve, with respect to the enclosing module of the interface on which the operation is defined, to an exception that has been declared previously.

The following extended attributes are applicable to operations: [IndexGetter], [IndexSetter], [NameGetter], [NameSetter], [NoNull], [Overloads].

The following extended attributes are applicable to operation arguments: [NoNull], [Variadic].

[20]OperationReturnType identifier "(" ArgumentList ")" Raises ";"
[21]Raises"raises" ExceptionList
 | ε
[23]ArgumentListArgument Arguments
 | ε
[24]Arguments"," Argument Arguments
 | ε
[25]ArgumentExtendedAttributeList "in" DeclarationType identifier
[37]ReturnTypeDeclarationType
 | "void"

3.4. Exceptions

An exception is a definition that matches the Exception non-terminal, and is used to declare a type of exception that can be thrown by implementations. The identifier of the exception is given by the identifier terminal.

Exceptions are different from interfaces in that they can have only exception members (matching ExceptionMember) declared on them, rather than the three types of interface members. An exception member’s type is given by the DeclarationType non-terminal of the ExceptionMember. If the DeclarationType is a scoped name, then it must resolve, with respect to the enclosing module of the exception on which the exception member is declared, to an interface, typedef or boxed valuetype that has been declared previously.

The identifier of an exception member is given by the first identifier terminal in a derivation of ExceptionMember. The identifier of an interface member must be unique within the exception on which it is defined.

Exception members are similar to attributes in that they will correspond to attributes of the same name and type on exception objects that are thrown by implementations.

No extended attributes are applicable to exceptions or exception members.

[9]Exception"exception" identifier "{" ExceptionMembers "}" ";"
[10]ExceptionMembersExtendedAttributeList ExceptionMember ExceptionMembers
 | ε
[26]ExceptionMemberDeclarationType identifier ";"

3.5. Typedefs

A typedef is a definition that matches the Typedef non-terminal, and is used to declare a new name for a type.

The type is given by the Type non-terminal, and the new name for the type is the identifier of the typedef, as given by the identifier terminal.

Using a typedef is the only way to utilize the sequence<T> type, since interface members, exception members and operation return types and argument types must be specified with a DeclarationType, which does not allow a sequence<T>.

[11]Typedef"typedef" Type identifier ";"

3.6. Valuetypes

Valuetypes in OMG IDL are used to define types similar to structs in C. That is, they define composite types that can have zero or more member variables that are passed by value. OMG IDL valuetypes have the additional feature of allowing null to be passed in place of an object with those member variables. An OMG IDL boxed valuetype is a special case, where the valuetype has a single member.

The IDL defined in this specification supports only boxed valuetypes, which are definitions that match the Valuetype non-terminal. The identifier of the valuetype is given by the identifier terminal, and the type being boxed is given by the DeclarationType non-terminal.

Boxed valuetypes are essentially used just for allowing a null value to be used where normally a non-object value could only be used.

[12]Valuetype"valuetype" identifier DeclarationType ";"

3.7. Types

This section lists the types supported by the IDL.

[32]DeclarationTypeUnsignedIntegerType
 | ScopedName
 | "any"
 | "boolean"
 | "octet"
 | "float"
 | "Object"
[33]TypeDeclarationType
 | "sequence" "<" Type ">"
[34]UnsignedIntegerType"unsigned" IntegerType
 | IntegerType
[35]IntegerType"short"
 | "long" OptionalLong
[36]OptionalLong"long"
 | ε

3.7.1. any

The any type is the union of all other possible types.

3.7.2. boolean

The boolean type has two values: true and false.

boolean constant values in IDL are represented with the "TRUE" and "FALSE" terminals.

3.7.3. octet

The octet type is an unsigned integer type that has values in the range [0, 255].

octet constant values in IDL are represented with integer terminals.

3.7.4. short

The short type is a signed integer type that has values in the range [−32768, 32767].

short constant values in IDL are represented with integer terminals.

3.7.5. unsigned short

The unsigned short type is an unsigned integer type that has values in the range [0, 65535].

unsigned short constant values in IDL are represented with integer terminals.

3.7.6. long

The long type is a signed integer type that has values in the range [−2147483648, 2147483647].

long constant values in IDL are represented with integer terminals.

3.7.7. unsigned long

The unsigned long type is an unsigned integer type that has values in the range [0, 4294967295].

unsigned long constant values in IDL are represented with integer terminals.

3.7.8. long long

The long long type is a signed integer type that has values in the range [−9223372036854775808, 9223372036854775807].

long long constant values in IDL are represented with integer terminals.

3.7.9. unsigned long long

The unsigned long long type is an unsigned integer type that has values in the range [0, 18446744073709551615].

unsigned long long constant values in IDL are represented with integer terminals.

3.7.10. float

The float type is a floating point numeric type that corresponds to the set of possible single-precision 32 bit IEEE 754 floating point numbers. [IEEE-754]

float constant values in IDL are represented with float terminals.

Editorial note

Do we need to mention anything about different NaNs, zeroes, infinities or denormalised numbers?

3.7.11. sequence<T>

The sequence<T> type is a parameterized type whose values are (possibly zero-length) sequences of values of type T. Sequences can have an arbitrary length that is immutable. However, sequence element values are mutable.

There is no way to represent a sequence constant value in IDL.

3.7.12. Object

The Object type corresponds to the set of all possible object references, plus the special value null, which indicates no object reference.

There is no way to represent an Object constant value in IDL.

3.7.13. Object implementing an interface

A scoped name that resolves to an interface is used to refer to a type that corresponds to the set of all possible references to objects that implement that interface, plus the special value null, which indicates no object reference.

There is no way to represent an Object constant value in IDL.

3.7.14. Boxed valuetype

A scoped name that resolves to a boxed valuetype is used to refer to a type that corresponds to the set of values for the type being boxed, plus the special value null, which indicates no value.

There is no way to represent a boxed valuetype constant value in IDL.

3.8. Extended attributes

An extended attribute is an annotation that can appear on definitions, interface members, exception members and operation arguments, and are used to control how language bindings will handle those constructs. Extended attributes are specified with an ExtendedAttributeList, which is a square bracket enclosed, comma separated list of ExtendedAttributes.

An extended attribute is specified as an identifier. Some extended attributes are defined to take an argument. The argument is given by following the identifier with a "=" terminal and the identifier argument.

This specification defines a number of extended attributes, which are listed in the sub-sections below.

Editorial note

Have an extended attribute that specifies what properties get enumerated in a for..in loop?

[27]ExtendedAttributeList"[" ExtendedAttribute ExtendedAttributes "]"
[28]ExtendedAttributes"," ExtendedAttribute ExtendedAttributes
 | ε
[29]ExtendedAttributeidentifier ExtendedAttributeAssignment
[30]ExtendedAttributeAssignment"=" ExtendedAttributeArgument
 | ε
[31]ExtendedAttributeArgumentidentifier

3.8.1. [Constructor]

If the [Constructor] extended attribute appears on an interface, it indicates that there must be a way to construct objects that implement this interface. How such objects can be constructed is specific to the language binding.

The [Constructor] extended attribute must take no argument.

Example

The following IDL defines two interfaces. The second has the [Constructor] extended attribute, while the first does not.

IDL
interface NodeList {
  Node item(in unsigned long index);
  readonly attribute unsigned long length;
};

[Constructor]
interface Circle {
  attribute float r;
  attribute float cx;
  attribute float cy;
  readonly attribute float circumference;
};

An ECMAScript implementation supporting these interfaces would have a [[Construct]] property on the Circle interface object which would return a new object that implements the interface. The NodeList interface object would not have a [[Construct]] property.

ECMAScript
var x = new Circle();    // x is now a reference to a host object that implements the Circle interface.
var y = new NodeList();  // This would throw a TypeError.
Editorial note

This doesn’t allow for constructors which take arguments, and that’s probably something that will be wanted. Maybe the extended attribute should be on operations instead, e.g.:

IDL
interface Circle {
  attribute float r;
  attribute float cx;
  attribute float cy;
  readonly attribute float circumference;

  [Constructor] Circle createCircle(in float r, in float cx, in float cy);
};

For ES, such operations map to a [[Construct]] property with a function that takes the given arguments. For other languages, this could perhaps map to a static method somewhere.

3.8.2. [ExceptionConsts]

If the [ExceptionConsts] extended attribute appears on a module, it indicates that any constants declared on that module are intended to exist on the language construct that corresponds to the exception given by the extended attribute’s argument (for languages that support constants on exceptions). Exactly how these constants are exposed is language binding specific.

The [ExceptionConsts] must take a single argument, an identifier, which must be the identifier of an exception, defined in that module, on which the constants declared at the module scope should live.

Example

The following IDL fragment declares an exception and a number of constants at the module scope:

IDL
[ExceptionConsts=FileIOException]
module fileio {

  exception FileIOException {
    unsigned short code;
  };

  const unsigned short FILE_NOT_FOUND = 1;
  const unsigned short READ_ERROR = 2;
  const unsigned short WRITE_ERROR = 3;
};

In the ECMAScript binding, this will result in properties on the exception interface object for each of the constants:

ECMAScript
typeof FileIOException;          // evaluates to "object"
FileIOException.FILE_NOT_FOUND;  // evaluates to 1

3.8.3. [IndexGetter]

If the [IndexGetter] extended attribute appears on an operation with a single unsigned long argument, it indicates that an object that implements the interface can be indexed with an unsigned long, resulting in the same effect as calling the operation with the given index (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [IndexGetter], then which operation is invoked when an object is indexed with an unsigned long value is undefined.

The [IndexGetter] extended attribute must take no argument.

Example

The following IDL fragment defines an interface OrderedMap which allows retrieving and setting values by name or by index number:

IDL
valuetype DOMString sequence<unsigned short>;

interface OrderedMap {
  readonly attribute unsigned long size;

  [IndexGetter] any getByIndex(in unsigned long index);
  [IndexSetter] void setByIndex(in unsigned long index, in any value);

  [NameGetter] any get(in DOMString name);
  [NameSetter] void set(in DOMString name, in any value);
};

An ECMAScript implementation would have an internal [[Get]] method that allows values to be retrieved from the map as properties, and a corresponding [[Put]] method for setting values in the map:

ECMAScript
var map = getOrderedMap();  // Assume map is a host object implementing the OrderedMap interface.
var x, y;

x = map[0];                 // Same as: x = map.getByIndex(0)
map[1] = false;             // Same as: map.setByIndex(1, false)

y = map.apple;              // Same as: y = map.get('apple')
map.banana = 123;           // Same as: map.set('banana', 123)

3.8.4. [IndexSetter]

If the [IndexSetter] extended attribute appears on an operation with two arguments, the first of which is unsigned long, it indicates that an object that implements the interface can be indexed with an unsigned long for assignment, resulting in the same effect as calling the operation with the given index and value to assign (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [IndexSetter], then which operation is invoked when an object is indexed with an unsigned long value for assignment is undefined.

The [IndexSetter] extended attribute must take no argument.

Example

See section 3.8.3 for an example of the use of [IndexSetter].

3.8.5. [NameGetter]

If the [NameGetter] extended attribute appears on an operation with a single sequence<unsigned short> valuetype argument, it indicates that an object that implements the interface can be indexed with a string, resulting in the same effect as calling the operation with the given index name (for languages that support such object indexing). If an object has both a [NameGetter]- and [IndexGetter]-annotated operation, then which operation is invoked when an object is indexed is language binding specific.

The [NameGetter] extended attribute must take no argument.

Example

See section 3.8.3 for an example of the use of [NameGetter].

Editorial note

I’m slightly uncomfortable giving sequence<unsigned short> such special status here.

3.8.6. [NameSetter]

If the [NameSetter] extended attribute appears on an operation with a two arguments, the first of which is a sequence<unsigned short> boxed valuetype, it indicates that an object that implements the interface can be indexed with a string for assignment, resulting in the same effect as calling the operation with the given index and value to assign (for languages that support such object indexing). If an object implements interfaces such that it has more than one operation annotated with [NameSetter], then which operation is invoked when an object is indexed with a boxed sequence<unsigned short> value for assignment is undefined.

The [NameSetter] extended attribute must take no argument.

Example

See section 3.8.3 for an example of the use of [NameSetter].

3.8.7. [NoNull]

If the [NoNull] extended attribute appears on an attribute, an operation or an operation argument, whose type is a boxed valuetype, it indicates that a null value is not expected and will never be returned. How implementations treat the assignment of a null value to an attribute with the [NoNull] extended attribute, or passing a null value as a [NoNull] operation argument, is specific to the language binding.

The [NoNull] extended attribute must take no argument.

Example

The following IDL fragment defines an interface that has one attribute with the [NoNull] extended attribute, and one operation with an argument that has the extended attribute:

IDL
valuetype DOMString sequence<unsigned short>;

interface Dog {
  [NoNull] attribute DOMString name;
  attribute DOMString shortName;

  boolean isMemberOfBreed([NoNull] in DOMString breedName);
};

An ECMAScript implementation implementing the Dog interface would not allow the null value to be assigned to the name property or passed as the argument to the isMemberOfBreed function:

ECMAScript
var d = getDog();         // Assume d is a host object implementing the Dog interface.

d.name = null;            // This assigns the string "null" to the .name property.
d.isMemberOfBreed(null);  // This passes the string "null" to the isMemberOfBreed function.
Editorial note

Perhaps instead of having a [NoNull] extended attribute on DOMString arguments/attributes, different types could be used, e.g.:

IDL
typedef sequence<unsigned short> DOMString;
valuetype DOMStringOrNull DOMString;

3.8.8. [Overloads]

If the [Overloads] extended attribute appears on an operation, it indicates that the operation is to be considered to overload the operation with the identifier given as the extended attribute argument. The extent to which a language supports method overloading determines whether an object implementing an interface with overloaded operations must implement the operation using the overloaded name or the original name, and is specific to the language binding.

The [Overloads] extended attribute must take a single argument, an identifier, which must be the identifier of another operation defined on the interface, which this operation overloads. The identifier must not identify an operation that itself is declared with an [Overloads] extended attribute.

Example

The following IDL fragment defines an interface with overloaded operations:

IDL
interface Person;

interface PersonFactory {
  Person createPerson();
  [Overloads=createPerson] Person createPersonWithAge(in short age);
};

Since the ECMAScript binding allows overloading, a host object implementing the PersonFactory interface will have a single property createPerson:

ECMAScript
var f = getFactory();          // Assume f is a host object implementing the PersonFactory interface.

typeof f.createPerson;         // Evaluates to "function".
typeof f.createPersonWithAge;  // Evaluates to "undefined".

var p1 = f.createPerson();     // Corresponds to the createPerson operation.
var p2 = f.createPerson(26);   // Corresponds to the createPersonWithAge operation.

However, a hypothetical C language binding would not, since C does not support overloading. Separate functions would likely be used for the two operations:

C
PersonFactory* f = getFactory();

Person* p1 = PersonFactory_createPerson(f);             // Corresponds to the createPerson operation.
Person* p2 = PersonFactory_createPersonWithAge(f, 26);  // Corresponds to the createPersonWithAge operation.

3.8.9. [PutForwards]

If the [PutForwards] extended attribute appears on a read only attribute declaration whose type is an object implementing an interface, it indicates that assigning to the attribute will have specific behavior. Namely, the assignment is “forwarded” to the attribute (specified by the extended attribute argument) on the object that is currently the value of the attribute being assigned to.

It is binding language specific what behavior occurs when assigning to such an attribute when its value is null.

The [PutForwards] extended attribute must take a single argument, an identifier, which must be the identifier of an attribute that exists on the interface that is the type of this attribute, which is the attribute that assignments will be forward to.

Example

The following IDL fragment defines interfaces for names and people. The [PutForwards] extended attribute is used on the name attribute of the Person interface to indicate that assignments to that attribute result in assignments to the full attribute of the Person object:

IDL
valuetype DOMString sequence<unsigned short>;

interface Name {
  attribute DOMString full;
  attribute DOMString family;
  attribute DOMString given;
};

interface Person {
  [PutForwards=full] readonly attribute Name name;
  attribute unsigned short age;
};

In the ECMAScript binding, this would allow assignments to the name property:

ECMAScript
var p = getPerson();           // Assume p is a host object implementing the Person interface.

p.name = 'John Citizen';       // This statement...
p.name.full = 'John Citizen';  // ...has the same behavior as this one.

3.8.10. [Variadic]

If the [Variadic] extended attribute appears on the final argument of an operation, it indicates that the operation is variadic, and can be passed zero or more arguments after the regular arguments. Each of these extra arguments will have to be of the type specified by that final argument. How such arguments are passed is specific to the language binding.

The [Variadic] extended attribute must take no argument.

Example

The following IDL fragment defines an interface that has a variadic operation:

IDL
interface IntegerSet {
  readonly unsigned long cardinality;

  void union([Variadic] in long integers);
  void intersection([Variadic] in long integers);
};

In the ECMAScript binding, variadic operations are implemented by functions that can accept the subsequent arguments:

ECMAScript
var s = getIntegerSet();  // Assume s is a host object implementing the IntegerSet interface.

s.union();                // Passing no arguments corresponding to 'integers'.
s.union(1, 4, 7);         // Passing three arguments corresponding to 'integers'.

A binding for a language that does not support variadic functions may specify that an explicit array or list of integers be passed to such an operation.

Editorial note

HTML 5 may want to use [Variadic] in the middle of the argument list, something like this:

IDL
any executeSql(DOMString q, [Variadic] DOMString p, Callback c);
any executeSql(Array a, Callback f);

Having [Variadic] in the middle isn’t so common in languages, as it tends to cause ambiguities.

4. ECMAScript binding

This section describes how definitions written with the IDL in section 3 correspond to particular ECMAScript constructs.

Unless otherwise specified, every object described in this section has internal properties [[Get]], [[Put]], [[CanPut]], [[HasProperty]], [[Delete]] and [[DefaultValue]] with the same behavior as specified for native objects, as described in section 8.6.2 of [ECMA-262].

If a value for the internal property [[Class]] is not given for a particular object, its value is implementation specific.

4.1. ECMAScript type mapping

This sub-section describes how types in the IDL map to types in ECMAScript. The phrase “to pass a value to a host object expecting type T” is used in this sub-section to describe passing an ECMAScript value as an argument to a function whose corresponding operation in the IDL specifies that the argument is of type T, or assigning to a property whose corresponding attribute in the IDL is of type T. Conversely, the phrase “to return a value of type T from a host object” is used to describe obtaining the ECMAScript return value from a function whose corresponding operation in the IDL specifies a return type T, or retrieving a property whose corresponding attribute in the IDL is of type T.

Editorial note

The above should become two <dfn>s that are linked to from the sub-sections below.

4.1.1. any

The any IDL type can correspond to any ECMAScript type.

4.1.2. void

The only place that the void type may appear in IDL is as the return type of an operation. Functions on host objects that implement an operation whose IDL specifies a void return type must return the undefined value.

ECMAScript functions that implement an operation whose IDL specifies a void return type may return any value, which will be discarded.

4.1.3. boolean

Values passed to a host object that expects a boolean must first be converted to an ECMAScript Boolean value by the ToBoolean operator defined in section 9.2 of [ECMA-262].

boolean values returned from a host object must be ECMAScript Boolean values.

4.1.4. octet

Values passed to a host object that expects an octet must first be converted to an ECMAScript Number value by the ToUint8 operator, which functions, analagously to the ToUint32 operator defined in section 9.6 of [ECMA-262], as follows:

  1. Call ToNumber on the input argument.
  2. If Result(1) is NaN, +0, −0, +∞, or −∞, return +0.
  3. Compute sign(Result(1)) * floor(abs(Result(1))).
  4. Compute Result(3) modulo 28.
  5. Return Result(4).

octet values returned from a host object must be ECMAScript Number values.

4.1.5. short

Values passed to a host object that expects a short must first be converted to an ECMAScript Number value by the ToInt16 operator, which functions, analagously to the ToInt32 operator defined in section 9.5 of [ECMA-262], as follows:

  1. Call ToNumber on the input argument.
  2. If Result(1) is NaN, +0, −0, +∞, or −∞, return +0.
  3. Compute sign(Result(1)) * floor(abs(Result(1))).
  4. Compute Result(3) modulo 216.
  5. If Result(4) is greater than or equal to 215, return Result(4) − 216. Otherwise, return Result(4).

short values returned from a host object must be ECMAScript Number values.

4.1.6. unsigned short

Values passed to a host object that expects an unsigned short must first be converted to an ECMAScript Number value by the ToUint16 operator defined in section 9.7 of [ECMA-262].

unsigned short values returned from a host object must be ECMAScript Number values.

4.1.7. long

Values passed to a host object that expects an long must first be converted to an ECMAScript Number value by the ToInt32 operator defined in section 9.5 of [ECMA-262].

long values returned from a host object must be ECMAScript Number values.

4.1.8. unsigned long

Values passed to a host object that expects an unsigned long must first be converted to an ECMAScript Number value by the ToUint32 operator defined in section 9.5 of [ECMA-262].

unsigned long values returned from a host object must be ECMAScript Number values.

4.1.9. long long

Values passed to a host object that expects a long long must first be converted to an ECMAScript Number value by the ToInt64 operator, which functions, analagously to the ToInt32 operator defined in section 9.5 of [ECMA-262], as follows:

  1. Call ToNumber on the input argument.
  2. If Result(1) is NaN, +0, −0, +∞, or −∞, return +0.
  3. Compute sign(Result(1)) * floor(abs(Result(1))).
  4. Compute Result(3) modulo 264.
  5. If Result(4) is greater than or equal to 263, return Result(4) − 264. Otherwise, return Result(4).

long long values returned from a host object must be ECMAScript Number values. If the long long value cannot be represented exactly by a Number value (i.e., it is less than or equal to −253 or greater than or equal to 253), the Number value returned must be the number representable by a Number closest to the given long long.

Editorial note

Should check that range of signed integers representable in a double.

4.1.10. unsigned long long

Values passed to a host object that expects an unsigned long long must first be converted to an ECMAScript Number value by the ToUint64 operator, which functions, analagously to the ToUint32 operator defined in section 9.6 of [ECMA-262], as follows:

  1. Call ToNumber on the input argument.
  2. If Result(1) is NaN, +0, −0, +∞, or −∞, return +0.
  3. Compute sign(Result(1)) * floor(abs(Result(1))).
  4. Compute Result(3) modulo 264.
  5. Return Result(4).

unsigned long long values returned from a host object must be ECMAScript Number values. If the unsigned long long value cannot be represented exactly by a Number value (i.e., it is greater than or equal to 253), the Number value returned must be the number representable by a Number closest to the given unsigned long long.

Editorial note

Should we do something other than choosing the closest double value to represent the long long?

4.1.11. float

Values passed to a host object that expects a float must first be converted to an ECMAScript Number value by the ToNumber operator defined in section 9.3 of [ECMA-262].

float values returned from a host object must be ECMAScript Number values.

4.1.12. sequence<T>

Values passed to a host object that expects a sequence<T> must be objects with a length property whose value is a non-negative integer Number that specifies the number of elements in the sequence. Such objects must return the element in the sequence at position n when their [[Get]] internal method is invoked with n as its argument. (An ECMAScript Array is an object that matches this description.) When the host object gets an element of the sequence using the [[Get]] method, the returned value must first be handled according to the rules in this section for the type T.

Editorial note

The above paragraph needs to have tighter language for the behaviour of [[Get]], like the definition for [[Get]] in section 4.3.1.

If a host object expecting a sequence<T> is passed a value which is not an object with a non-negative integer Number length property, a TypeError exception must be thrown.

Sequences are passed by reference. If a reference to a sequence passed to a host object is kept (whether internally or as the value of an attribute), and the passed sequence is not an ECMAScript Array object, the kept reference must be a newly created ECMAScript Array object whose contents is the elements of the sequence.

Editorial note

Change the above para according to comments in this thread.

Example

The following IDL and ECMAScript code fragments illustrate how sequences are handled:

IDL
typedef sequence<unsigned short> Integers;

[Constructor]
interface LotteryResults {
  attribute Integers numbers;
};
ECMAScript
var results = new LotteryResults();  // results is a new host object implementing the LotteryResults interface.
var a = [4, 8, 15, 16, 23, 42];      // An object that can serve as a sequence<unsigned short>.

results.numbers = a;                 // Assign the sequence.
a[0] = 5;                            // Change the array.
results.numbers[0];                  // Evaluates to 5, since results.numbers is a reference to 'a'.

4.1.13. sequence<unsigned short>

As a special case, a sequence<unsigned short> is represented by an ECMAScript String value.

Values passed to a host object that expects a sequence<unsigned short> value must first be converted to an ECMAScript String value by the ToString operator defined in section 9.8 of [ECMA-262].

sequence<unsigned short> values returned from a host object must be ECMAScript String values.

4.1.14. Object

If a host object that expects an Object is passed the null value, then that value must passed without modification. Otherwise, the value being passed must first be converted to an ECMAScript Object value by the ToObject operator defined in section 9.9 of [ECMA-262].

If a host object returns an Object that is null, then the ECMAScript null value must be returned. Otherwise, an ECMAScript Object value must be returned.

4.1.15. Object implementing an interface

If a host object that expects an object that implements an interface I is passed the null value, then that value must passed without modification. Otherwise, the value being passed must first be converted to an ECMAScript Object value by the ToObject operator defined in section 9.9 of [ECMA-262]. If after that conversion the object is not one that implements I (either intrinsically for a host object, or as described in section 4.4 below for a native object), then a TypeError must be thrown.

If a host object returns an object that implements an interface I that is null, then the ECMAScript null value must be returned. Otherwise, an ECMAScript Object value that implements I must be returned.

4.1.16. Boxed valuetype

A boxed valuetype is represented by either the ECMAScript type corresponding to the IDL type being boxed, or the ECMAScript null value.

If a host object that expects a boxed valuetype that is not annotated with the [NoNull] extended attribute is passed the null value, then that value must be passed without modification. However, if the [NoNull] extended attribute does apply and the null value is passed to the host object, the behavior depends on the type being boxed. If the type being boxed is sequence<unsigned short>, then the ECMAScript String "null" must be passed to the host object. If the type being boxed is anything else, the behavior is implementation specific.

If a host object that expects a boxed valuetype is passed an ECMAScript Object value, the value must first be handled according to the rules in this section corresponding to the IDL type being boxed.

If a host object returns a boxed valuetype that is null, then the ECMAScript null value must be returned. If the operation or attribute is annotated with the [NoNull] extended attribute, the host object must not return null. If the value returned is not null, it must be handled according to the rules in this section corresponding to the IDL type being boxed.

Editorial note

Perhaps there should be an example here for the real-world case that boxed valuetypes are actually used for (DOMString).

4.2. Interfaces

Editorial note

This section does not have RFC2119-style conformance wording yet.

Every interface corresponds to a property on the global object, whose name is the same as its identifier in the IDL. This identifier is not the qualified name of the interface, but the final identifier in a derivation of the ScopedName production that forms the complete qualified name. The value of this property is an object called the interface object, which provides access to the constants and functions defined on the interface. The property has the attributes { DontDelete, DontEnum }.

4.2.1. Interface object

The interface object for a particular interface has an internal [[Prototype]] object whose value is the Object prototype object.

In addition, there is a property on the interface object for each constant defined on the interface with the same name as that constant. These properties have the attributes { DontDelete }.

If the interface is declared with the [Constructor] extended attribute, then the interface object also has a [[Construct]] internal property, which allows construction of objects that implement the given interface. The behavior of this [[Construct]] method is not necessarily the same as that described for Function objects in section 13.2.2 of [ECMA-262].

The interface object also has a property named prototype with attributes { DontDelete, ReadOnly } whose value is an object called the interface prototype object. This object provides access to the functions that correspond to the operations defined on the interface.

4.2.1.1. Interface object [[HasInstance]] method

The internal [[HasInstance]] method of every interface object I behaves, assuming V is the object argument passed to [[HasInstance]], as follows:

  1. If V is not an object, return false.
  2. Call the [[Get]] method of I with property name "prototype".
  3. Let O be Result(2).
  4. If O is not an object, throw a TypeError exception.
  5. If V is a host object that implements the interface for which O is the interface prototype object, return true.
  6. Let V be the value of the [[Prototype]] property of V.
  7. If V is null, return false.
  8. If O and V refer to the same object or if they refer to objects joined to each other (see section 13.1.2 of [ECMA-262]), return true.
  9. Go to step 6.

4.2.2. Interface prototype object

The interface prototype object for a particular interface has properties that correspond to the operations defined on that interface. Each such property has attribute { DontEnum }. These properties are described in more detail in section 4.2.3 below.

If the interface is declared with the [Constructor] extended attribute, the interface prototype object also has a property named constructor with attribute { DontEnum } whose value is a reference to the interface object for the interface.

Editorial note

Haven’t checked what attributes browsers use on the constructor property.

Also, should the constructor property exist even for non-constructable objects?

Constants should be in here as well as in the interface object.

No particular value must be used for the internal [[Prototype]] property of the interface prototype object. However, it must be an object that provides access to the properties defined on all superinterfaces of the interfaces. Changes made to the interface prototype objects of superinterfaces must be reflected through this object. If more than one superinterface has a given property, it is implementation specific which one is accessed.

Example

Assume the following IDL:

IDL
interface A {
  void f();
};

interface B {
  void g();
};

interface C : A, B {
  void f();
};

interface D : C {
  void h();
};

The following is one way for an implementation to set up the prototype chain for the interface objects:

  • The [[Prototype]] internal property of the interface prototype objects for A and B is the Object prototype object, since neither of these interfaces has a superinterface.
  • The [[Get]], [[CanPut]] and [[HasProperty]] internal methods of the interface prototype object for A are the standard ones defined in section 8.6.2 of [ECMA-262].
  • The [[Prototype]] internal prototype of the interface prototype object for C is null.
  • The [[Get]] internal method of the interface prototype object for C behaves as follows (where O is the object and P is the property name):
    1. If O doesn’t have a property with name P, go to step 4.
    2. Get the value of the property.
    3. Return Result(2).
    4. Call the [[HasProperty]] method of the interface prototype object for A with property name P.
    5. If Result(4) is false, go to step 8.
    6. Call the [[Get]] method of the interface prototype object for A with property name P.
    7. Return Result(6).
    8. Call the [[HasProperty]] method of the interface prototype object for B with property name P.
    9. If Result(8) is false, go to step 12.
    10. Call the [[Get]] method of the interface prototype object for B with property name P.
    11. Return Result(10).
    12. Return undefined.
  • The [[CanPut]] internal method of the interface prototype object for C behaves as follows (where O is the object and P is the property name):
    1. If O doesn’t have a property with name P, go to step 4.
    2. If the property has the ReadOnly attribute, return false.
    3. Return true.
    4. Call the [[CanPut]] method of the interface prototype object for A with property name P.
    5. If Result(4) is false, return false.
    6. Call the [[CanPut]] method of the interface prototype object for B with property name P.
    7. If Result(6) is false, return false.
    8. Return true.
  • The [[HasProperty]] internal method of the interface prototype object for C behaves as follows (where O is the object and P is the property name):
    1. If O has a property with name P, return true.
    2. Call the [[HasProperty]] method of the interface prototype object for A with property name P.
    3. If Result(3) is true, return true.
    4. Call the [[HasProperty]] method of the interface prototype object for B with property name P.
    5. If Result(5) is true, return true.
    6. Return false.
  • The [[Prototype]] internal property of the interface prototype object for D is the interface prototype object for C, since D has only a single superinterface.
  • The [[Get]], [[CanPut]] and [[HasProperty]] internal methods of the interface prototype object for D are the standard ones defined in section 8.6.2 of [ECMA-262].
Editorial note

Should the prototype chain and internal methods given in the example above be mandated, or just left as an example of how to do it?

4.2.3. Operations

In order to describe how properties on the interface prototype object corresponding to operations are chosen in the presence of overloading, the notion of potential ambiguity is first defined. Two operations on an interface, O1 and O2, are potentially ambiguous if the following algorithm returns true:

Editorial note

A useful way to handle method overloading is not obvious.

Three patterns of overloading seem to be desired, at least. The first is overloading to handle optional arguments, such as with XMLHttpRequest’s open method. Handling this is reasonably simple.

The second is distinguishing based on argument type, where the values of those types do not intersect. XHR’s send method is an example of this, where there are two versions that take an argument: one a DOMString, the other a Document. It’s impossible for a non-null value to be both a DOMString and a Document, so distinguishing these at run time seems fine. It would be ambiguous for null though. This could be avoided by, say, putting a [NoNull] extended attribute on one of those arguments, which would mean that the other method is invoked when null is passed.

The third is distinguishing based on argument type, where the values of those types do intersect. This can be seen with the createPattern methods on HTML 5’s CanvasRenderingContext2D interface, which are currently defined as:

IDL
interface CanvasRenderingContext2D {
  …
  CanvasPattern createPattern(in HTMLImageElement image, DOMString repetition);
  CanvasPattern createPattern(in HTMLCanvasElement image, DOMString repetition);
  …
};

While in a normal web browser environment there’ll be no object that implements both HTMLImageElement and HTMLCanvasElement, in the general case objects can implement more than one interface. To disallow overloading like this for all languages seems excessive, since there are languages that can handle this sort of things (e.g. C++ will allow calls to createPattern as long as it’s not ambiguous based on the type of the value being passed, or the ambiguity can be resolved explicitly). Perhaps some sort of declaration in the IDL that if the object does implement both interfaces, then one of the operations is preferred (or defaults to arbitrary selection by the UA). It seems a little hacky, because there’d be no way to explicitly disambiguate the call as you can do in other languages.

Editorial note

The definitions in this section should be factored out to apply to all language bindings. Overloading then could be specified in terms of a potentially ambiguous definition specific to a language binding.

The overload set for an operation O is defined as follows:

  • If O is not declared with an [Overloads] extended attribute, then the set is equal to the union of { O } and all other operations declared on the interface with the [Overloads] extended attribute whose argument is the name of O.
  • Otherwise, if O is declared with an [Overloads] extended attribute with argument N, then the set is equal to the overload set for the operation with identifier N declared on the interface.

An operation O is a non-overloadable operation if it matches one of the following two criteria:

  1. The overload set of O is equal to { O }.
  2. There exists two operations O1 and O2 in the overload set for O such that O1 and O2 are potentially ambiguous.

An operation is an overloaded operation if it is not declared with an [Overloads] extended attribute and the cardinality of its overload set is greater than 1.

For each non-overloadable operation O defined on the interface, a property exists on the interface prototype object whose name is the name of the operation and whose value is a Function object that behaves as follows:

  1. Let n be the number of arguments passed to the function.
  2. Let arity be the number of arguments that O is declared with if the final argument does not have the [Variadic] extended attribute, or the number of arguments that O is declared with minus 1 otherwise.
  3. If n < arity, an implementation specific exception is thrown and these steps are ended.
  4. Let arg0‥n−1 be the arguments passed to the function.
  5. Initialize i to 0.
  6. While i < arity:
    1. Convert argi, according to the type of the formal argument in position i, by following the relevant steps from section 4.1 above.
    2. If the type of the formal argument in position i is a boxed sequence<unsigned short> valuetype and is declared with the [NoNull] extended attribute, and argi is null, set argi to the String value "null".
    3. Set i to i + 1.
  7. Let j be n if the final argument of O is declared with the [Variadic] extended attribute, or arity otherwise.
  8. While i < j:
    1. Convert argi, according to the type of the formal argument in position arity + 1, by following the relevant steps from section 4.1 above.
    2. If the type of the formal argument in position arity + 1 is a boxed sequence<unsigned short> valuetype and is declared with the [NoNull] extended attribute, and argi is null, set argi to the String value "null".
    3. Set i to i + 1.
  9. Perform the actions listed in the description of O with arg0‥j−1 as the argument values.

For each overloaded operation defined on the interface, a property exists on the interface prototype object whose name is the name of the operation and whose value is a Function object that behaves as follows:

Editorial note

This will be written once the overloading rules are more definite.

4.3. Host objects implementing interfaces

A host object that implements a particular interface has properties that correspond to the attributes declared on that interface. If the attribute is declared readonly, the corresponding property has attributes { DontDelete, ReadOnly }, while if it is not declared readonly, it is { DontDelete }. If a host object implements more than one interface with an attribute of a given name, it is implementation specific which attribute the property corresponds to.

No particular value must be used for the internal [[Prototype]] property of the host object. However, it must be an object that provides access to the properties corresponding to the operations and constants defined on all interfaces the host object implements. Changes made to the interface prototype objects of interfaces implemented by the host object must be reflected through this object. If more than one interface prototype object has a given property, it is implementation specific which one is accessed.

Example

Assume the IDL and interface prototype objects given in the section 4.2.2 example.

Now assume that ab is a host object that implements A and B and d is a host object that implements D. The following is one way for an implementation to connect the host objects to the interface prototype objects:

  • The [[Prototype]] internal property of the host object ab is an object that provides access to the properties from the interface prototype objects for both A and B:
    • The [[Prototype]] internal property of the [[Prototype]] object for ab is null.
    • The [[Get]] internal method of the [[Prototype]] object for ab behaves as follows (where O is the object and P is the property name):
      1. If O doesn’t have a property with name P, go to step 4.
      2. Get the value of the property P on object O.
      3. Return Result(2).
      4. Call the [[HasProperty]] method of the interface prototype object for A with property name P.
      5. If Result(4) is false, go to step 8.
      6. Call the [[Get]] method of the interface prototype object for A with property name P.
      7. Return Result(6).
      8. Call the [[HasProperty]] method of the interface prototype object for B with property name P.
      9. If Result(8) is false, go to step 12.
      10. Call the [[Get]] method of the interface prototype object for B with property name P.
      11. Return Result(10).
      12. Return undefined.
    • The [[CanPut]] internal method of the [[Prototype]] object for ab behaves as follows (where O is the object and P is the property name):
      1. If O doesn’t have a property with name P, go to step 4.
      2. If the property has the ReadOnly attribute, return false.
      3. Return true.
      4. Call the [[CanPut]] method of the interface prototype object for A with property name P.
      5. If Result(4) is false, return false.
      6. Call the [[CanPut]] method of the interface prototype object for B with property name P.
      7. If Result(6) is false, return false.
      8. Return true.

      Note that this method shouldn’t strictly be required, since there would be no way for script to get access to the [[Prototype]] object for ab.

    • The [[HasProperty]] internal method of the [[Prototype]] object for ab behaves as follows (where O is the object and P is the property name):
      1. If O has a property with name P, return true.
      2. Call the [[HasProperty]] method of the interface prototype object for A with property name P.
      3. If Result(2) is true, return true.
      4. Call the [[HasProperty]] method of the interface prototype object for B with property name P.
      5. If Result(5) is true, return true.
      6. Return false.
  • The [[Prototype]] internal property of the host object d is the interface prototype object for D, since D is the only interface the object directly implements.

4.3.1. Host object [[Get]] method

The internal [[Get]] method of every host object O that implements at least one IDL interface behaves, assuming P is the property name passed to [[Get]], as follows:

  1. Determine the name of an [IndexGetter]-annotated operation on the interfaces that O implements. If there is no such operation, go to step 8.
  2. Compute ToUint32(P).
  3. Compute ToString(Result(2)).
  4. If Result(3) is equal to P and Result(2) is not equal to 232 − 1, go to step 8.
  5. Invoke the [[Get]] method of object O with Result(1) as the argument.
  6. Invoke the [[Call]] method of Result(5), providing O as the this value and Result(2) as the single argument value.
  7. Return Result(5).
  8. Determine the name of a [NameGetter]-annotated operation on the interfaces that O implements. If there is no such operation, go to step 14.
  9. Invoke the [[HasProperty]] method of object O with P as the argument.
  10. If Result(8) is true, go to step 14.
  11. Invoke the [[Get]] method of object O with Result(7) as the argument.
  12. Invoke the [[Call]] method of Result(10), providing O as the this value and P as the single argument value.
  13. Return Result(11).
  14. If O doesn’t have a property with name P, go to step 17.
  15. Get the value of the property.
  16. Return Result(15).
  17. If the [[Prototype]] of O is null, return undefined.
  18. Call the [[Get]] method of [[Prototype]] with property name P.
  19. Return Result(18).

4.3.2. Host object [[Put]] method

The internal [[Put]] method of every host object O that implements at least one IDL interface behaves, assuming P is the property name and V is the property value passed to [[Put]], as follows:

  1. Determine the name of a [IndexSetter]-annotated operation on the interfaces that O implements. If there is no such operation, go to step 8.
  2. Compute ToUint32(P).
  3. Compute ToString(Result(2)).
  4. If Result(3) is equal to P and Result(2) is not equal to 232 − 1, go to step 8.
  5. Invoke the [[Get]] method of object O with Result(1) as the argument.
  6. Invoke the [[Call]] method of Result(5), providing O as the this value and Result(2) and V as the two argument values.
  7. Return Result(5).
  8. Determine the name of a [NameSetter]-annotated operation on the interfaces that O implements. If there is no such operation, go to step 14.
  9. Invoke the [[HasProperty]] method of object O with P as the argument.
  10. If Result(8) is true, go to step 14.
  11. Invoke the [[Get]] method of object O with Result(7) as the argument.
  12. Invoke the [[Call]] method of Result(10), providing O as the this value and P and V as the two argument values.
  13. Return Result(11).
  14. If O has a property with name P and that property does not correspond to an IDL operation declared readonly, then go to step 19.
  15. If the property on O with name P does not correspond to an IDL operation declared with a [PutForwards] extended attribute, then an implementation specific exception is thrown and these steps are ended.
  16. Call the [[Get]] method of O with name P.
  17. Call the [[Put]] method of Result(16) with the property name being the argument to the [PutForwards] extended attribute, and value V.
  18. Return.
  19. Call the [[CanPut]] method of O with name P.
  20. If Result(19) is false, return.
  21. If O doesn’t have a property with name P, go to step 23.
  22. Set the value of the property to V. The attributes of the property are not changed.
  23. Return.
  24. Create a property with name P, set its value to V and give it empty attributes.
  25. Return.

4.4. Native objects implementing interfaces

A native ECMAScript object is considered to implement a particular interface if it has a property corresponding to each operation on that interface whose value is a Function object. The rules for which operations correspond to properties in the presence of overloaded operations is the same as described for host objects in section 4.2.3 above.

Editorial note

How operations correspond to attributes on native objects could be fleshed out about, rather than just refering to the host object Operations section earlier.

Note that if the interface has attributes declared on it, properties are not required to be currently on the native object. Since native objects cannot have properties with attributes (such as ReadOnly), a property that does exist on the object that corresponds to a readonly attribute declared on the interface does not have to be read-only.

Since native objects cannot have custom internal properties, such objects implementing the interface are not required to honor the [IndexGetter], [IndexSetter], [NameGetter], [NameSetter] or [PutForwards] extended attributes.

As a special case, a Function object F is considered to implement an interface if that interface is declared with exactly one operation. The function itself is the implementation of the operation. If the Function object also has a property P whose name is the name of the operation and whose value is a Function object, then that P is used as the implementation of the operation rather than F.

4.5. Exceptions

Every exception corresponds to a property on the global object, whose name is the same as its identifier in the IDL. The value of this property is an object called the exception interface object, which provides access to any constants that have been associated with the exception. The property has the attributes { DontDelete, DontEnum }.

4.5.1. Exception interface object

The exception interface object for a particular exception has an internal [[Prototype]] object whose value is the Object prototype object.

If the enclosing module of the exception has been declared with the [ExceptionConsts] extended attribute, and the argument to that extended attribute is the identifier of the exception, then the exception interface object has a property for each constant declared at the enclosing module’s scope. These properties have the attributes { DontDelete }.

4.5.1.1. Exception interface object [[HasInstance]] method

The internal [[HasInstance]] method of every exception interface object E behaves, assuming V is the object argument passed to [[HasInstance]], as follows:

  1. If V is not an object, return false.
  2. If V is a host object that is an exception whose exception interface object is E, return true.
  3. Return false.
Editorial note

Do we also need an exception interface prototype object too, to put the constants on? The following script does alert 8:

ECMAScript
try {
  document.removeChild(document);
} catch (e) {
  alert(e.NOT_FOUND_ERR);
}

4.6. Host exception objects

Editorial note

The host exception object's [[Prototype]] should be set to the exception interface prototype object, and it should have a (read write) property for every exception member.

5. Java binding

This section describes how definitions written with the IDL in section 3 correspond to particular Java constructs.

Editorial note

This section needs tighter conformance wording, too.

5.1. Names

Since Java has a number of reserved words in the language, identifiers of Java constructs corresponding to IDL definitions need to be escaped to avoid conflicts. A name is Java escaped as follows:

  • If the name is a Java reserved word, then the Java escaped name is the name prefixed with a U+005F LOW LINE ("_") character.
  • Otherwise, the name is not a Java reserved word. The Java escaped name is simply the name.
Note

At the time of publication, the list of Java reserved words is the following: abstract, assert, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, enum, extends, final, finally, float, for, goto, if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while.

5.2. Java type mapping

This sub-section describes how types in the IDL map to types in Java.

5.2.1. any

The any IDL type corresponds to a Java java.lang.Object value. Values of IDL types that correspond to Java primitive types must be represented with an object according to the following table:

IDL type Java class
boolean java.lang.Boolean
octet java.lang.Byte
short java.lang.Short
unsigned short java.lang.Short
long java.lang.Integer
unsigned long java.lang.Integer
long long java.lang.Long
unsigned long long java.lang.Long
float java.lang.Float

5.2.2. void

The only place that the void type may appear in IDL is as the return type of an operation. Methods on Java objects that implement an operation whose IDL specifies a void return type must be declared to have a return type of void.

5.2.3. boolean

The IDL boolean type maps exactly to the Java boolean type.

5.2.4. octet

The IDL octet type corresponds to the Java byte type. Note that while the IDL octet type is unsigned, with a range of [0, 255], the Java byte type is signed, with a range of [−128, 127].

To encode an octet value in a byte, the following steps must be followed:

  1. Let x be the octet value to encode.
  2. If x < 128, return a byte whose value is x.
  3. Otherwise x ≥ 128. Return a byte whose value is x − 256.

Note that in Java this is the same as having the octet value stored in an int and casting it to a byte.

To decode an octet value from a byte, the following steps must be followed:

  1. Let x be the byte value to decode.
  2. If x ≥ 0, return an octet whose value is x.
  3. Otherwise x < 0. Return an octet whose value is x + 256.

Note that in Java this is the same as performing a bit-wise AND of the byte value with the int constant 0xff.

5.2.5. short

The IDL short type maps exactly to the Java short type.

5.2.6. unsigned short

The IDL unsigned short type corresponds to the Java short type. Note that while the IDL unsigned short type is unsigned, with a range of [0, 65535], the Java short type is signed, with a range of [−32768, 32767].

To encode an IDL unsigned short value in a Java short, the following steps must be followed:

  1. Let x be the IDL unsigned short value to encode.
  2. If x < 32768, return a Java short whose value is x.
  3. Otherwise x ≥ 32768. Return a Java short whose value is x − 65536.

Note that in Java this is the same as having the unsigned short value stored in an int and casting it to a short.

To decode an IDL unsigned short value from a Java short, the following steps must be followed:

  1. Let x be the Java short value to decode.
  2. If x ≥ 0, return an IDL unsigned short whose value is x.
  3. Otherwise x < 0. Return an IDL unsigned short whose value is x + 65536.

Note that in Java this is the same as performing a bit-wise AND of the short value with the int constant 0xffff.

5.2.7. long

The IDL long type maps exactly to the Java int type.

5.2.8. unsigned long

The IDL unsigned long type corresponds to the Java int type. Note that while the IDL unsigned long type is unsigned, with a range of [0, 4294967295], the Java int type is signed, with a range of [−2147483648, 2147483647].

To encode an IDL unsigned long value in a Java int, the following steps must be followed:

  1. Let x be the IDL unsigned long value to encode.
  2. If x < 2147483648, return a Java int whose value is x.
  3. Otherwise x ≥ 2147483648. Return a Java int whose value is x − 4294967296.

Note that in Java this is the same as having the unsigned long value stored in a Java long and casting it to an int.

To decode an IDL unsigned long value from a Java int, the following steps must be followed:

  1. Let x be the Java int value to decode.
  2. If x ≥ 0, return an IDL unsigned long whose value is x.
  3. Otherwise x < 0. Return an IDL unsigned long whose value is x + 4294967296.

Note that in Java this is the same as performing a bit-wise AND of the int value with the long constant 0xffffffffL.

5.2.9. long long

The IDL long long type maps exactly to the Java long type.

5.2.10. unsigned long long

The IDL unsigned long long type corresponds to the Java long type. Note that while the IDL unsigned long long type is unsigned, with a range of [0, 18446744073709551615], the Java long type is signed, with a range of [−9223372036854775808, 9223372036854775807].

To encode an IDL unsigned long long value in a Java long, the following steps must be followed:

  1. Let x be the IDL unsigned long long value to encode.
  2. If x < 18446744073709551616, return a Java long whose value is x.
  3. Otherwise x ≥ 18446744073709551616. Return a Java long whose value is x − 18446744073709551615.

To decode an IDL unsigned long long value from a Java long, the following steps must be followed:

  1. Let x be the Java long value to decode.
  2. If x ≥ 0, return an IDL unsigned long long whose value is x.
  3. Otherwise x < 0. Return an IDL unsigned long long whose value is x + 18446744073709551615.

5.2.11. float

The IDL float type maps exactly to the Java float type.

5.2.12. sequence<T>

The IDL sequence<T> type corresponds to a Java array of type T.

A Java object implementing an interface with an operation declared to return a sequence<T> value must not return null from the corresponding method. Similarly, a getter method for an IDL attribute must not return null if the attribute is declared to be of type sequence<T>.

A Java object implementing an interface with an operation declared to take an argument of type sequence<T> must throw a NullPointerException exception if null is passed as the corresponding argument to the corresponding method. Similarly, a setter method for an IDL attribute must throw a NullPointerException exception if the attribute is declared to be of type sequence<T>.

Editorial note

Should mention what to do with null values in nested sequences (e.g. sequence<sequence<short>>).

5.2.13. sequence<unsigned short>

As a special case, a sequence<unsigned short> is represented by a Java String object.

A Java object implementing an interface with an operation declared to return a sequence<unsigned short> value must not return null from the corresponding method. Similarly, a getter method for an IDL attribute must not return null if the attribute is declared to be of type sequence<unsigned short>.

A Java object implementing an interface with an operation declared to take an argument of type sequence<unsigned short> must throw a NullPointerException exception if null is passed as the corresponding argument to the corresponding method. Similarly, a setter method for an IDL attribute must throw a NullPointerException exception if the attribute is declared to be of type sequence<unsigned short>.

5.2.14. Object

The IDL Object type maps exactly to the Java java.lang.Object type.

5.2.15. Object implementing an interface

An IDL interface type maps exactly to the corresponding Java interface type.

5.2.16. Boxed valuetype

A boxed valuetype is represented differently depending on the type being boxed. Let T be the type being boxed.

If T maps to a Java object value, which is the case for any, sequence<T>, sequence<unsigned short>, Object and interface types, then a boxed valuetype is represented by the Java null value (if the value of the boxed valuetype is null) or by a value as described in this section for the mapping for T (if the value of the boxed valuetype is not null). Thus, a Java object whose method implements an operation declared to take an argument of a sequence type must not throw an exception simply for being passed a null value.

Editorial note

What to do if [NoNull] is used? Throw, or something else?

If T does not map to a Java object value, then the boxed valuetype maps to a Java class as specified in the table below:

T Java class
boolean java.lang.Boolean
octet java.lang.Byte
short java.lang.Short
unsigned short java.lang.Short
long java.lang.Integer
unsigned long java.lang.Integer
long long java.lang.Long
unsigned long long java.lang.Long
float java.lang.Float

If the value of the boxed valuetype is not null, then the value stored inside the object of the given class must be as specified by the rules in this section for type T.

5.3. Modules

Every IDL module corresponds to a Java package, whose name is derived as follows:

Declarations inside an IDL module correspond to Java constructs declared to be in the package for that module.

Example

The following IDL will cause a Java interface named HTMLDocument in package org.w3c.dom.html to exist:

IDL
[Prefix="org::w3c::dom"]
module html {
  interface HTMLDocument {
    // …
  };
};
Java
package org.w3c.dom.html;

interface HTMLDocument {
  // …
}
Editorial note

The example uses [Prefix] and doesn’t match the prose above. Is [Prefix] a reasonable way to map modules to Java packages? It seems to me that just using the module structure to map to the package name is more natural:

IDL
module org {
  module w3c {
    module dom {
      module html {
        // …
      };
    };
  };
};

But that’s pretty verbose. In C++ you can skip steps in one go, so something similar in IDL would be:

IDL
module org::w3c::dom::html {
  // …
};

But that is not syntactically compatible with OMG IDL.

5.4. Interfaces

A conforming Java implementation must have a public Java interface corresponding to to every IDL interface that is supported, whose name is the Java escaped identifier of the IDL interface and which resides in the Java package corresponding to the interface’s enclosing module.

The Java interface must be declared to extend every Java interface that corresponds to an interface from which this IDL interface inherits.

5.4.1. Constants

For each constant defined on the IDL interface, there must be a corresponding constant declared on the Java interface with the following properties:

  • The constant has no modifiers.
  • The type of the constant is the Java type that corresponds to the type of the IDL constant, according to the rules in section 5.2 above.
  • The name of the constant is the Java escaped identifier of the constant.
  • The value of the constant is the Java value that is equivalent to the constant’s IDL value, according to the rules in section 5.2 above.

5.4.2. Operations

For each operation defined on the IDL interface, there must be a corresponding method declared on the Java interface with the following properties:

  • The method has no modifiers.
  • The return type of the method is the Java type that corresponds to the operation return type, according to the rules in section 5.2 above.
  • If the operation is a non-overloadable operation, then the tentative name of the method is the Java escaped identifier of the operation. Otherwise, the tentative name of the method is the Java escaped identifier that is the argument to the [Overloads] extended attribute on the operation. The name of the method is the tenative name of the method prefixed with the smallest number of U+005F LOW LINE ("_") characters required to make the name not equal to the name of a constant declared on the Java interface or one of the methods on the java.lang.Object class.
  • The method has an argument for each argument on the operation. The type of the method argument is as follows. Let T be the Java type that corresponds to the operation argument type according to the rules in section 5.2 above. If the argument is the final argument on the operation, and it is declared with the [Variadic] extended attribute, then the type of the method argument will be an array of T (i.e., T[]). Otherwise, the type of the method argument will be T.

In addition, the method should have a throws clause specifying all of the Java exception classes that correspond to the IDL exceptions that are listed in the Raises clause of the operation, and no others.

5.4.3. Attributes

For each attribute defined on the IDL interface, there must be a corresponding getter method declared on the Java interface with the following properties:

  • The method has no modifiers.
  • The return type of the method is the Java type that corresponds to the attribute type, according to the rules in section 5.2 above.
  • The tentative name of the method is a U+0067 LATIN SMALL G ("g") character, followed by a U+0065 LATIN SMALL E ("e") character, followed by a U+0074 LATIN SMALL T ("t") character, followed by the first character of the identifier of the attribute uppercased (as if passed to the java.lang.Character.toUpperCase() method), followed by the remaining characters from the identifier of the attribute. The name of the method is the Java escaped tenative name of the method prefixed with the smallest number of U+005F LOW LINE ("_") characters required to make the name not equal to the name of a constant or method declared on the Java interface or one of the methods on the java.lang.Object class.
  • The method has no arguments.

In addition, the method should have a throws clause specifying all of the Java exception classes that correspond to the IDL exceptions that are listed in the GetRaises clause of the attribute, and no others.

For each attribute defined on the IDL interface that is not read only, there must be a corresponding setter method declared on the Java interface with the following properties:

  • The method has no modifiers.
  • The return type of the method is void.
  • The tentative name of the method is a U+0073 LATIN SMALL S ("s") character, followed by a U+0065 LATIN SMALL E ("e") character, followed by a U+0074 LATIN SMALL T ("t") character, followed by the first character of the identifier of the attribute uppercased (as if passed to the java.lang.Character.toUpperCase() method), followed by the remaining characters from the identifier of the attribute. The name of the method is the Java escaped tenative name of the method prefixed with the smallest number of U+005F LOW LINE ("_") characters required to make the name not equal to the name of a constant or method declared on the Java interface or one of the methods on the java.lang.Object class.
  • The method has a single argument whose type is the Java type that corresponds to the attribute type, according to the rules in section 5.2 above.

In addition, the method should have a throws clause specifying all of the Java exception classes that correspond to the IDL exceptions that are listed in the SetRaises clause of the attribute, and no others.

For each attribute defined on the IDL interface that is read only and is declared with the [PutForwards] extended attribute, there must be a corresponding setter method declared on the Java interface with the following properties:

  • The method has no modifiers.
  • The return type of the method is void.
  • The tentative name of the method is a U+0073 LATIN SMALL S ("s") character, followed by a U+0065 LATIN SMALL E ("e") character, followed by a U+0074 LATIN SMALL T ("t") character, followed by the first character of the identifier of the attribute uppercased (as if passed to the java.lang.Character.toUpperCase() method), followed by the remaining characters from the identifier of the attribute. The name of the method is the Java escaped tenative name of the method prefixed with the smallest number of U+005F LOW LINE ("_") characters required to make the name not equal to the name of a constant or method declared on the Java interface or one of the methods on the java.lang.Object class.
  • The method has a single argument whose type is the Java type that corresponds to the type of the attribute identified by the [PutForwards] extended attribute on the interface type that this attribute is declared to be of, according to the rules in section 5.2 above.

In addition, the method should have a throws clause specifying all of the Java exception classes that correspond to the IDL exceptions that are listed in the SetRaises clause of the attribute identified by the [PutForwards] extended attribute on the interface type that this attribute is declared to be of, and no others.

5.5. Objects implementing interfaces

A Java object that implements an IDL interface must be of a Java class that implements the Java interface that corresponds to the IDL interface.

5.6. Exceptions

A conforming Java implementation must have a Java class corresponding to every IDL exception that is supported, whose name is the Java escaped identifier of the IDL exception and which resides in the Java package corresponding to the exception’s enclosing module.

The Java class must have only the public modifier, and be declared to extend java.lang.RuntimeException.

5.6.1. Constants

For each constant defined on the enclosing module of the IDL exception, where that module has been declared with the [ExceptionConsts] extended attribute, there must be a corresponding constant declared on the Java class with the following properties:

  • The constant has no modifiers.
  • The type of the constant is the Java type that corresponds to the type of the IDL constant, according to the rules in section 5.2 above.
  • The name of the constant is the Java escaped identifier of the constant.
  • The value of the constant is the Java value that is equivalent to the constant’s IDL value, according to the rules in section 5.2 above.

5.6.2. Exception members

For each exception member defined on the exception, there must be a corresponding instance variable declared on the Java class with the following properties:

  • The instance variable has only the modifier public.
  • The type of the instance variable is the Java type that corresponds to the type of the IDL exception member, according to the rules in section 5.2 above.
  • The name of the instance variable is the Java escaped identifier of the exception member.
  • The instance variable is not declared with an initializer.

6. Extensibility

This section is informative.

7. Referencing this specification

This section is informative.

It is expected that other specifications that define DOM interfaces using a conforming IDL fragment will reference this specification. It is suggested that those specifications include a sentence such as the following, to indicate that the IDL is to be interpreted as described in this specification:

The IDL fragment in Appendix A of this specification must be interpreted as required for conforming IDL fragments, as described in the “Language Bindings for DOM Specifications” specification. [DOMBIND]

In addition, it is suggested that the conformance class for user agents in referencing specifications be linked to the conforming implementation class from this specification:

A conforming FooML user agent must also be a conforming implementation of the IDL fragment in Appendix A of this specification, as described in the “Language Bindings for DOM Specifications” specification. [DOMBIND]

8. Acknowledgements

This section is informative.

The editor would like to thank the following people for contributing to this specification: David Andersson, Robin Berjon, Gorm Haug Eriksen, Ian Hickson, Björn Höhrmann, Anne van Kesteren, Simon Pieters, Jonas Sicking, Maciej Stachowiak, Boris Zbarsky.

A. IDL grammar

This section defines an LL(1) grammar whose start symbol, Definitions, matches an entire IDL fragment.

Each production in the grammar has on its right hand side either a non-zero sequence of terminal and non-terminal symbols, or an epsilon (ε) which indicates no symbols. Symbols that begin with an uppercase letter are non-terminal symbols. Symbols within quotes are terminal symbols that are matched with the exact text between the quotes. Symbols that begin with a lowercase letter are terminal symbols that are matched by the regular expressions (using Perl 5 regular expression syntax [PERLRE]) as follows:

integer = -?0([0-7]*|[Xx][0-9A-Fa-f]+)|[1-9][0-9]*
float = -?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+
identifier = [A-Z_a-z][0-9A-Z_a-z]*
whitespace = [\t\n\r ]+|[\t\n\r ]*((//.*|/\*.*?\*/)[\t\n\r ]*)+
Editorial note

Should we require quoting (with an underscore) of identifiers that would match keywords used in OMG IDL 3.0 but not in this IDL?

When tokenizing, the longest possible match must be used. For example, if the input text is “a1”, it should be tokenized as a single identifier, and not as a separate identifier and integer. If the longest possible match could match both an identifier and one of the quoted terminal symbols from the grammar, it must be tokenized as the quoted terminal symbol. Thus, the input text “in” is tokenized as the quoted terminal symbol "in" rather than an identifier called “in”.

Implicitly, the whitespace terminal is allowed between every terminal in the input text being parsed. Such whitespace terminals, which actually encompass both whitespace and comments, are ignored while parsing.

The following LL(1) grammar matches an IDL fragment:

[1]DefinitionsExtendedAttributeList Definition Definitions
 | ε
[2]DefinitionModule
 | Interface
 | Exception
 | Typedef
 | Valuetype
 | Const
[3]Module"module" identifier "{" Definitions "}" ";"
[4]Interface"interface" identifier InterfaceBody ";"
[5]InterfaceInheritance":" ScopedNameList
 | ε
[6]InterfaceBodyInterfaceInheritance "{" InterfaceMembers "}"
 | ε
[7]InterfaceMembersExtendedAttributeList InterfaceMember InterfaceMembers
 | ε
[8]InterfaceMemberConst
 | Attribute
 | Operation
[9]Exception"exception" identifier "{" ExceptionMembers "}" ";"
[10]ExceptionMembersExtendedAttributeList ExceptionMember ExceptionMembers
 | ε
[11]Typedef"typedef" Type identifier ";"
[12]Valuetype"valuetype" identifier DeclarationType ";"
[13]Const"const" DeclarationType identifier "=" ConstExpr ";"
[14]ConstExprBooleanLiteral
 | integer
 | float
[15]BooleanLiteral"TRUE"
 | "FALSE"
[16]AttributeReadOnly "attribute" DeclarationType identifier GetRaises SetRaises ";"
[17]ReadOnly"readonly"
 | ε
[18]GetRaises"getraises" ExceptionList
 | ε
[19]SetRaises"setraises" ExceptionList
 | ε
[20]OperationReturnType identifier "(" ArgumentList ")" Raises ";"
[21]Raises"raises" ExceptionList
 | ε
[22]ExceptionList"(" ScopedNameList ")"
[23]ArgumentListArgument Arguments
 | ε
[24]Arguments"," Argument Arguments
 | ε
[25]ArgumentExtendedAttributeList "in" DeclarationType identifier
[26]ExceptionMemberDeclarationType identifier ";"
[27]ExtendedAttributeList"[" ExtendedAttribute ExtendedAttributes "]"
[28]ExtendedAttributes"," ExtendedAttribute ExtendedAttributes
 | ε
[29]ExtendedAttributeidentifier ExtendedAttributeAssignment
[30]ExtendedAttributeAssignment"=" ExtendedAttributeArgument
 | ε
[31]ExtendedAttributeArgumentidentifier
[32]DeclarationTypeUnsignedIntegerType
 | ScopedName
 | "any"
 | "boolean"
 | "octet"
 | "float"
 | "Object"
[33]TypeDeclarationType
 | "sequence" "<" Type ">"
[34]UnsignedIntegerType"unsigned" IntegerType
 | IntegerType
[35]IntegerType"short"
 | "long" OptionalLong
[36]OptionalLong"long"
 | ε
[37]ReturnTypeDeclarationType
 | "void"
[38]ScopedNameListScopedName ScopedNames
[39]ScopedNames"," ScopedName ScopedNames
 | ε
[40]ScopedName"::" identifier ScopedNameParts
 | identifier ScopedNameParts
[41]ScopedNameParts"::" identifier ScopedNameParts
 | ε
Editorial note

Still not sure how we should handle extensibility of extended attributes.

B. References

[ECMA-262]
ECMAScript Language Specification, 3rd Edition, M. Cowlishaw, Editor. Ecma International, December 1999. Available at http://www.ecma-international.org/publications/standards/Ecma-262.htm.
[IEEE-754]
IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985). Institute of Electrical and Electronics Engineers, 1985.
[OMGIDL]
CORBA 3.0 – OMG IDL Syntax and Semantics chapter. Object Management Group, June 2002. Available at http://www.omg.org/cgi-bin/apps/doc?formal/02-06-39.pdf.
[PERLRE]
Perl regular expressions (Perl 5.8.8). The Perl Foundation, February 2006. Available at http://www.perl.com/doc/manual/html/pod/perlre.html.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, March 1997. Available at http://ietf.org/rfc/rfc2119.