5.2.4 Class Module Declarations
Note
This section describes the implementation of MS-VBAL §5.2.4 Class Module Declarations.
Class modules defined in workspace source code have no means to inherit another class module in the Object-Oriented Programming sense of inheritance (RD-VBAL §2.4.2 Non-intrinsic Types).
A public Enum and a public user-defined type declared in a class module reach the project scope. A class module's
other members need an instance to be reached through, but a declared type needs none
(RD-VBAL §5.2.3 Module Declarations, §5.2.3.3 and §5.2.3.4).
5.2.4.1 Non-Syntactic Class Characteristics
Note
This section describes the implementation of MS-VBAL §5.2.4.1 Non-Syntactic Class Characteristics.
VBClassModuleSymbol.AutomationKind
(VBAutomationKind) distinguishes an Automation-capable
class module from an IUnknown-only class module:
AutomationKind |
Class module |
|---|---|
Dispatch |
Automation-capable (VT_DISPATCH). This is the default. |
Unknown |
IUnknown-only. |
Every RD-VBA class module has AutomationKind Dispatch (VT_DISPATCH). See
RD-VBAL §6.1.1 Predefined Enums (§6.1.1.16 VbVarType).
5.2.4.1.1 Class Accessibility and Instancing
Note
This section describes the implementation of MS-VBAL §5.2.4.1.1 Class Accessibility and Instancing.
The accessibility and instancing of a class module are determined by two module attributes (RD-VBAL §3.1.1 Attributes, §3.1.1.2 and §3.1.1.3):
| Attribute | Determines | Value |
|---|---|---|
VB_Exposed |
Whether a class module is visible at all to a referencing project. | False for private modules, True for public modules. |
VB_Creatable |
Whether a class module can be directly instantiated using a New (or CreateObject) expression from a referencing project. |
Must be False in a VBA module. May be True in a VB6 module, for RD-VBA clients that support the VB6 language. |
A public module may be consumed by a referencing project. Whether a new instance of a public module can be created
outside the enclosing project that defines it depends on the value of its VB_Creatable attribute.
A not-creatable class module can only be directly instantiated within the project it is defined in (the enclosing project). An instance of a not-creatable class may be consumed by any referencing project if the class module is exposed.
👉 Together, VB_Creatable and VB_Exposed determine the instancing mode of a class module:
| Instancing mode | VB_Exposed |
VB_Creatable |
|---|---|---|
Private |
False |
False |
PublicNotCreatable |
True |
False |
PublicCreatable |
True |
True |
The PublicCreatable instancing mode is not a legal VBA configuration. RD-VBA implementations may allow it,
with semantic flags issued, if the host environment is configured to allow building library projects.
5.2.4.1.2 Default Instance Variables Static Semantics
Note
This section describes the implementation of MS-VBAL §5.2.4.1.2 Default Instance Variables Static Semantics.
The VB_PredeclaredId attribute (RD-VBAL §3.1.1 Attributes, §3.1.1.6)
determines whether the environment host declares a global auto-object instance of the class with a predeclared
ID. The identifier name of that global auto-object is the same as the name of the class module it is a
predeclared instance of.
Static Semantics
The static semantics of VB_PredeclaredId are modeled:
- A class module with
VB_PredeclaredId = Truehas a VBPredeclaredInstanceSymbol: a global variable named after the class, whose declared type is that class. - The predeclared instance variable is created as if declared
As New. It is an automatic instantiation variable (SymbolProperties.AutoInstantiated, MS-VBAL §2.5.1 Automatic Object Instantiation; RD-VBAL §2.5.1 Runtime Entities), like any variable declared with anAs Newclause (RD-VBAL §5.2.3 Module Declarations, §5.2.3.1.1). - In the default binding context (
ISymbolResolver.ResolveValue), a class name binds to the class module's predeclared instance variable. A class is a value in that context only through its predeclared instance (RD-VBAL §2.3.1.3 Name Resolution). - A class that is not predeclared has no default instance.
👉 Deferred class types cannot be presumed to have a default instance (RD-VBAL §2.4.4 Deferred Types).
It is invalid for the default instance variable to be the target of a Set assignment, whatever is assigned to it
(MS-VBAL §5.2.4.1.2; see RD-VBAL §5.4.3.9 Set Statement).
Runtime Semantics
In MS-VBA:
- Setting an auto-object (predeclared instance) to
Nothingdestroys its internal state. - An auto-object reference is re-created as soon as it is referred to, including within an
Is Nothingreference check.
Note
Not implemented. The run-time behavior of the default instance (it is never Nothing; it is re-created on
reference) is not modeled.
5.2.4.2 Implements Directive
Note
This section describes the implementation of MS-VBAL §5.2.4.2 Implements Directive.
The Implements directive specifies that the (class) module implements an interface class
(RD-VBAL §3.1 Attributes and Directives).
If a class module specifies any Implements directives, the interfaces specified by those directives are included
in the class type's SuperTypes array
(VBClassType;
RD-VBAL §2.4.2 Non-intrinsic Types).
A class module also implements Class implicitly, which is among its implemented interfaces without a directive
(RD-VBAL §5.3.1.10). The directives below are the ones the source writes:
its ImplementedInterfaceNames.
Static Semantics
ImplementsSemantics checks the directives of a class module and what they require of it.
- The class a directive names must exist (
VBC09311otherwise, as for any type that does not), cannot be the class of the module itself, and cannot be named by more than one directive of the module. A class whose public variables or methods have an underscore in their names cannot be an interface class, and the implemented interface name prefix of an interface, its name and an underscore, cannot begin that of another: VBC09328. - The module must declare an implemented name declaration,
InterfaceName_MemberName, for each public method of the interface class, of the same kind, and for each public variable the property accessors its declared type calls for: aProperty Getand aProperty Let, aProperty Setin place of theLetwhen the variable is anObjector a class, and all three when it is aVariant: VBC09329. ThePrivatemembers of the interface class are not part of its interface.
What an implemented name declaration must be is RD-VBAL §5.3.1.9.
What is wrong with a directive is reported where the directive is written: the class module symbol carries the range of each directive
(VBClassModuleSymbol.ImplementedInterfaceRanges, one for each of the ImplementedInterfaceNames), and an interface the module does not
implement completely is reported at the directive that names it. A symbol that was not read from source has no ranges, and is reported at the module.
A directive in an extensible module (VB_Extensible = True, RD-VBAL §3.1.1.8) is invalid:
VBC09328.
The environment host learns of the directives from the language server: DefineSymbolsParams.ImplementedInterfaceNames carries the
interface names a module's directives name, and the host composes the module's class symbol from them and from the members it has been
sent (ISessionSymbols.TryComposeClassModule), resolving the interfaces again over every class module it knows whenever one is
composed, so the order the modules are defined in does not matter.
Warning
Extensible ("document") modules cannot specify any Implements directives.
MS-VBA does not strictly enforce this rule. In MS-VBA, an Implements directive in an extensible module can cause
host application instabilities, source project corruption, and host application crashes.
RD-VBA must explicitly and statically deny Implements directives in extensible modules, as a normal
compile-time error.
5.2.4.3 Event Declaration
This section corresponds to MS-VBAL §5.2.4.3 Event Declaration.
An Event declaration defines an event member of the class module. It is a VBEventMemberSymbol: its name, and its parameters, which describe the arguments a RaiseEvent (RD-VBAL §5.4.2.20) must give and the parameter list a handler must have (RD-VBAL §5.3.1.8); it defines no variable. An Event without an access modifier is Public. VBClassModuleSymbol.Events lists them, and FindEvent finds one by name, without regard to case.
The event symbols and their parameters are among the member descriptors the environment host receives, so a class's events are known where RaiseEvent runs.
An event name must be unique within the class module, reported as a duplicate declaration (VBC09303) when it is not, and
must not contain an underscore, which is what separates a handler's variable from its event:
VBC09325. Both are reported by
ClassModuleEventSemantics.
⏮️ RD-VBAL §5.2.3 Module Declarations | ⏭️ RD-VBAL §5.3 Module Code Section Structure