10.8. Attributes

Attributes allow you to specify special information about declarations of classes, properties and methods in a generic way. For example, the C++ function specifiers virtual and const would be implemented as method attributes in the IDL (those method attributes actually exist, although the const attribute has a slightly different semantics).

You can think of attributes as type key-value pair. The attributes are divided into three kinds: class attributes, property attributes and method attributes. Because the IDL has only single namespace for all identifiers within given scope, it's impossible to define two attributes of different kind with the same name.

Each class, property or method always has the same set of class, property or method attributes, with possibly different attribute values. All attributes must be declared before any class, property or method declaration.

The IDL language itself does not define any attributes, attributes are defined directly in the idl files. However, some attributes are required by the IDL processor, and other attributes are required by the Core. All these attributes are declared in src/core/object/object.idl, and the IDL processor will reject all idl files that do not include declarations of those attributes. The attributes are described in Section 10.9.3, “Class Attributes”, Section 10.10.1, “Property Attributes” and Section 10.11.1, “Method Attributes”.

Values of all non-internal class, property and method attributes are queriable at run-time. Names of the C++ attribute variables are derived from fully-qualified names of the attribute identifiers: the leading :: is stripped and other :: are replaced by the underscore character. See Chapter 12, Metaobjects for more information about metaobjects and object introspection.

[Note]Note

All attributes defined in src/core/object/object.idl are declared in the root scope, therefore their C++ names are the same as their IDL names.

[Note]Note

Unless you want to modify the Massiv Core, you won't have to define your own attributes. Actually, currently the only way to define new attributes is to modify src/core/object/object.idl directly. However, the following sections should help you to understand how the attributes work in general and how to specify their values.

10.8.1. Attribute Definition

Attribute definition satisfies the following syntax:


 (7)            <attribute> ::= <attr_kind>
                                <attr_type>
                                <identifier>
                                "="
                                <const_expr>
                                ";"

Whether the attribute is a class, property or method attribute is specified by <attr_kind>, which can be one of “classattr”, “propattr”, or “methodattr”, optionally followed by attribute flags enclosed in the < and > characters. Attribute flags are simple literals separated by commas that further specify behavior of the attribute. Each attribute kind can be flagged as “idl_internal”, which instructs the IDL processor not to export its value to metaobject introspection structures. If class attribute flag “inherit” is set, the attribute value lookup will change as described in Section 10.8.6, “Attribute Value Lookup”.

The <attr_type> specified attribute type, the <identifier> specified its name. The <const_expr> defines default value of the attribute. It must be a constant expression of type equal to the type of the attribute.

10.8.2. Attribute Types

All attributes are typed. Attribute type definition satisfies the following syntax:


(18)            <attr_type> ::= <buildin_type>
                              | <enum_name>
(19)         <buildin_type> ::= "bool"
                              | "int"
                              | "string"

The following table describes all attribute types that can be used, and to which C++ types they map in the metaobject introspection structures:

Table 10.2. Attribute Type
IDL TypeC++ TypeDescription
boolbool A boolean attribute. Can be either true or false.
intint An integral attribute. Can be assigned an arbitrary int value.
stringstd::string A string attribute.
name of an enumeration type indentifierint An enumeration type attribute. Can be assigned any constant enumeration expression of given enumeration type.

10.8.3. Attribute Default Values

Attribute values are specified by a constant expression of given type, as documented in the next section. Each attribute has a default value, specified in its definition. This default value can be overridden using the following syntax:


(22)         <attr_default> ::= "attribute"
                                <attr_name>
                                "="
                                <const_expr>
                                ";"

The attribute override is valid until the end of the current scope, where it reverts back to override valid before the scope beginning, or until it's overridden by another “attribute” keyword.

[Warning]Warning

The attribute default value overridde can cross file boundaries. You should never override the default within a scope that may cross file boundaries.

The following example shows how the overriding works:

/* Define a class attribute with default value set to 1. */
classattr int attr = 1;

namespace foo {
/* Default value is still 1. */

attribute attr = 2;
/* Default value is 2 now. */

attribute attr = 3;
/* Default value is 3 now. */

namespace bar {
/* Default value is still 3. */

attribute attr = 4;
/* Default value is 4 now. */

} // namespace foo::bar

/* Default value is 3 again. */

} // namespace foo

/* Default value is 1. */

10.8.4. Attribute Value Assignment

In each class definition and property or method declaration, values of attributes of corresponding kind can be specified using the following syntax:


(27)         <class_header> ::= "class"
                                [ "<" [ <classattr_vals> ] ">" ]
                                <identifier>
                                [ <class_inheritance> ]
(28)       <classattr_vals> ::= <classattr_val>
                                { "," <classattr_val> }*
(29)        <classattr_val> ::= <boolclassattr_name>
                              | <classattr_name> "=" <const_expr>
(30)   <boolclassattr_name> ::= <scoped_name>
(31)       <classattr_name> ::= <scoped_name>

Similar syntax is used to specify property and method attributes.

Class, method or property attribute values are specified directly after the “class”, “method” or “property” keyword, respectively, as a list of name=value assignments separated by commas, enclosed in < and > characters. The attribute specification is optional. Assigning true to a boolean attribute can be equally written as the attribute name without any value assignment (i.e. just foo instead of foo = true).

10.8.5. Expressions

Attribute value can be specified in several context:

  • Default value specification in attribute definition.

  • Default value override.

  • Attribute value assignment in class defintion and property or method declaration.

In each of these contexts, constant expression of corresponding type is used on the right side of the assignment. Currently, the IDL parser can only evaluate primitive constants in place of expressions.

10.8.5.1. Boolean Expressions

In the context of assignment to a boolean, the following values can be used:

  • true or 1

  • false or 0

10.8.5.2. Integer Expressions

In the context of assignment to an integer, a integer literal (see Section 10.2.4.1, “Integer Literals”), optionally beginning with any numbers of minus (-) characters, may be used.

10.8.5.3. String Expressions

In the context of assignment to a string, a string literal can be used.

10.8.5.4. Enumeration Expressions

In the context of assignment to an attribute of enumeration type, identifier of any enumerant defined withing the enumeration type may be used. Note that in this case name lookup and scoping rules do not apply, an identifier of an enumerant is used directly.

10.8.6. Attribute Value Lookup

For each class, property and method, values for all attributes of given kind are always defined. If an attribute is not assigned a value in a class, property or method declaration, the default value of the attribute is used. The default is specified in attribute definition and can be overridden as described in Section 10.8.3, “Attribute Default Values”.

The only exception to this lookup rule are class attributes with the “inherit” attribute flag set. If a class has a base class (all classes except Massiv::Core::Object do) and value of an “inherit” class attribute is not specified in the definiton of the derived class, attribute value from the base class is used, even if it's not directly specified in its definition and has been determined by applying this rule recursively. If a class inherits multiple base classes, and value of an unassigned “inherit” attribute is not the same in all base classes, the IDL is ill-formed - class attribute value must be always explicitly assigned in this case.

[Note]Note

Default attribute value lookup is never done for “inherit” class attributes, except for the defintion of the Massiv::Core::Object class. Therefore it's pretty useless to override defaults of “inherit” class attributes.