2.4. RD-VBA Type System - Static Types
Note
This specification may be incomplete at this time.
The type system begins with VBType and the abstractions that formalize the implicit classifications in MS-VBAL:
These abstract types and interfaces are very useful for pattern-matching types and values in both static and runtime semantics implemantations.
All representations of a data type inherit the VBType class, often indirectly through other abstract types that semantically specialize it.
2.4.1 VBIntrinsicType
In RD-VBA, a type is an intrinsic type if MS-VBAL mentions it, irrespective of its specified semantics or modelization.
The non-numeric intrinsic types are:
- VBArrayType
- VBFixedSizeArrayType
- VBResizableArrayType
- VBResizableByteArrayType
- VBBooleanType
- VBDateType
- VBEmptyType
- VBErrorType
- VBLongPtr_x64
- VBLongPtr_x86
- VBMissingType
- VBNullType
- VBObjectType
- VBStringType
- VBFixedStringType
- VBVariantType
2.4.1.1 VBNumericType
Numeric types are intrinsic types that represent a numeric value, regardless of its representation. All numeric types additionally implement one of the following marker interfaces:
- IIntegralNumericType for all integer types;
- IFixedPointNumericType for all fixed-point numeric types;
- IFloatingPointNumericType for all floating-point numeric types.
The intrinsic numeric data types are the following (showing the managed/.NET min/max values for simplicity):
| Type | Interface | Description | MinValue | MaxValue |
|---|---|---|---|---|
| VBBypeType | IIntegralNumericType |
8-bit Byte unsigned integer |
Byte.MinValue (0) |
Byte.MaxValue (255) |
| VBIntegerType | IIntegralNumericType |
16-bit Integer signed integer |
Int16.MinValue (-32,768) |
Int16.MaxValue (32,767) |
| VBLongType | IIntegralNumericType |
32-bit Long signed integer |
Int32.MinValue (-2,147,483,648) |
Int32.MaxValue (2,147,486,647) |
| VBLongLongType | IIntegralNumericType |
64-bit LongLong signed integer |
Int64.MinValue (-9,223,372,036,854,775,808) |
Int64.MaxValue (9,223,372,036,854,775,807) |
| VBSingleType | IFloatingPointNumericType |
32-bit single-precision floating-point | Single.MinValue |
Single.MaxValue |
| VBDoubleType | IFloatingPointNumericType |
64-bit double-precision floating-point | Double.MinValue |
Double.MaxValue |
2.4.1.2 VBStringType
String types are internally represented using a UTF-16 standard .NET System.String value.
2.4.1.3 VBArrayType
Array types include the following implementations:
Notes:
ReDimis illegal to use with anyVBFixedSizeArrayValue, but may be use to declare or redimension an already-declaredVBResizableArrayValue.- If the item type of a resizable array value is
VBByteType, the data type of the array isVBResizableByteArrayType. This array type has specific let-coercion semantics attached, allowing implicit conversion to and fromVBStringType. - The type itself does not encode any dimensions; but the associated value type does. See VBArrayValue and its derived types.
2.4.2 Non-intrinsic Types
These data types are additional RD-VBA internal data types that are not exposed to (or directly usable in) workspace source code but help complete the modelization of the system.
They include:
- [VBStdModuleType]
- [VBClassType]
- [VBCollectionType]
- [VBEnumType]
- [VBProjectType]
- [VBUnknownType]
- [VBVoidType]
2.4.2.1 VBStdModuleType
Represents a standard module, which is functionally equivalent to a managed static class. Defined by workspace source code or imported from a referenced library.
2.4.2.2 VBClassType
Represents an object type defined by workspace source code in a class module. This type implements IVBMemberOwnerType, which makes it expose an immutable array of VBTypeMemberSymbol where each element describes a member of the class type.
2.4.2.2.1 SuperTypes
While class modules defined in the workspace source code have no means to inherit another class module in the Object-Oriented Programming sense of "Inheritance", all VBA classes still inherit a base class that exposes Initialize and Terminate internal events, respectively fired by the host upon instantiation and destruction of an instance (object) of a given class type.
If a class module specifies any Implements directives, the interfaces specified by such directives are included in this array.
2.4.2.2.1.1 Extensible ("Document") Modules
ℹ️ extensible class modules have host-defined interfaces in their
SuperTypesarray that require information that is unavailable to the RD-VBA host without a library reference to the library that defines these types. In other words RD-VBA code that depends on for example the Microsoft Excel type library, requires the Microsoft Excel type library to correctly resolve the members and expressions inside such class modules.
Warning
Extensible modules cannot specify any Implements directives. This specification is not strictly enforced in MS-VBA, which can cause host application instabilities, source project corruption, and host application crashes for what should be statically caught early on as normal compile-time errors; RD-VBA must explicitly, statically deny Implements directives in these modules.
2.4.2.2.2 Default Member
Members of a class can contain a VB_UserMemId attribute that can specify a number of flags that modify the behavior. A class can have exactly one member with a VB_UserMemId attribute value of 0, making that member the class type's default member.
The default member of a class type can be implicitly invoked through let-coercion, yielding the data value of the object, recursively as needed if the default member also yields an object data type.
2.4.2.3 VBCollectionType
🧩 Object value types (inheriting VBObjectValue) representing an instance of a collection type should implement IEnumerableObject.
A subclass of VBClassType that exposes a NewEnum member and can be efficiently iterated using a For Each...Next loop structure.
Tip
For Each...Next enumeration is intended to be used with collections containing objects. Performance-related diagnostics should be issued when a VBCollectionType is being accessed by index within the body of a For...Next loop.
Note
The VBA language specification (MS-VBAL) sometimes refers to the elements (or items) of a collection as "data members". This term sometimes appears in error messages (see VBR00461 MethodOrDataMemberNotFound), but is objectively confusing terminology that RD-VBAL is discarding: in RD-VBA a "member" is always a direct child symbol of a module, user-defined type, or enum. Regardless of the message content, RD-VBA must still raise the MS-VBA equivalent error code in the relevant contexts.
2.4.2.4 VBProjectType
The symbol at the top of the abstract syntax tree (AST) of an entire VBA project is of a type inherited from VBProjectType. These correspond to the project types defined in MS-VBAL§4.1:
2.4.2.4.1 VBSourceProject
This type corresponds to the RD-VBA workspace folder (.rdproj) content, representing the workspace source code of a VBA project.
2.4.2.4.2 VBLibraryProject
This type corresponds to a referenced library, referenced by a VBSourceProjectType (source project). A project of this type is defined in an implementation-defined manner and exposes the types and members of the library to RD-VBA source code through the means available to any other VBA source code, making it feel as though workspace source code is manipulating objects and members defined in VBA source code - but the library itself may or may not have been compiled from such.
2.4.2.4.3 VBHostProjectType
This type of project can be introduced into the RD-VBA environment by the host (rdc.exe) in an implementation-defined manner. Additional workspace source code may be added to this project if it is open ("an open host project"), by agents other than the host application.
👉
RDCoreReferencefor references of this type must have the "unremovable" flag set.
2.4.2.5 VBUnknownType
A special data type that represents an unresolved type. This is the fallback data type used when type resolution semantics fail to identity a valid data type for a given value.
Warning
Unknown types represent a compile-time binding failure and should raise error RDC009311 UserDefinedTypeNotDefined (which is arguably a confusing wording; verbose messages should help clarify the meaning).
2.4.2.6 VBVoidType
A special data type that represents the absence of return value semantics; this is the data type returned by Sub, Property Let, and Property Set procedures.
👉 The internal representation of this type being a managed
Int32value (0), because the intent is to ultimately supportHRESULTinteroperability.
2.4.3 Meta and Advanced Types
These data types are introspective types that can reflectively describe the type system itself, and as such MUST NOT BE EXPOSED directly to RD-VBA source code: doing so would BREAK THE LANGUAGE on a fundamental level.
🧩 They DO, however, provide extremely powerful language-level extension possibilities.
These types include:
2.4.3.1 VBTypeDesc
Represents (describes) a VBType within the type system.
👉 A value (see VBTypeDescValue) of this meta-type is notably used in the implementation of the Is relational operator and of let-coercion, where semantics demand knowledge of a data type where a value is normally required.
None of the other descriptor types are currently in use, but language core or future language extension features may eventually use them as needed.
2.4.3.2 VBMemberDesc
An abstract descriptor that represents (describes) any VBTypeMemberSymbol.
2.4.3.2.1 VBProcedureMemberDesc
A descriptor that represents (describes) any VBProcedureMemberSymbol.
2.4.3.2.2 VBPropertyLetMemberDesc
A descriptor that represents (describes) a VBProprertyLetMemberSymbol.
2.4.3.2.3 VBPropertySetMemberDesc
A descriptor that represents (describes) a VBProprertySetMemberSymbol.
2.4.3.2.4 VBReturningMemberDesc
An abstract descriptor that represents (describes) any VBReturningMemberSymbol.
2.4.3.2.4.1 VBFunctionProcedureDesc
A descriptor that represents (describes) a VBFunctionMemberSymbol.
2.4.3.2.4.2 VBPropertyGetProcedureDesc
A descriptor that represents (describes) a VBFunctionMemberSymbol.
2.4.3.3 VBParameterDesc
A descriptor that represents (describes) a VBParameterSymbol.
2.4.4 Deferred Types
The RD-VBA type system defines a category of deferred data types. These types are not currently in use, but their presence intends to prepare the ground for supporting IntelliSense and other features in late-bound and other cases where MS-VBA would fail to resolve a valid compile-time data type.
A deferred type is a valid RD-VBA data type representing an undefined type that may statically be one of the following data types:
An undefined type is a workspace-defined data type that does not have any associated source code.
Deferred names
- The name of a deferred type is a candidate name that can change depending on how the deferred type is being used.
- The name of a deferred member is the identifier name identifying it in the workspace source code. Any given two symbols should be resolved to the same deferred member if the resolved qualifying module is the same for both symbols. Without a qualifier, the deferred symbol is deemed to be an undeclared local variable as per MS-VBAL scoping rules, meaning if a global-scope deferred symbol with the same identifier name exists, then the undeclared local variable should resolve to the global-scope deferred symbol.
- The name of a deferred parameter is
Argfollowed by its 1-based position in the deferred member signature, in sequence such that the first parameter is namedArg1, the second is namedArg2, and so on. If a call site supplies a named argument that is not a defined deferred paraemter, then a deferred parameter with that name is defined at the end of the deferred member signature (multiple such named parameters would then be materialized in alphabetical order), and deemedOptional.
Tip
Deferred types cannot implement IVBMemberOwnerType, because the related symbols are unbound. Instead they implement IVBInferableType, exposing an immutable hashset of candidate types that would be legal to materialize the type with.
2.4.4.1 VBDeferredModuleType
Represents a deferred VBStdModuleType.
A deferred member is presumed to belong to a deferred module unless it is qualified, in which case it is added to the resolved module type's IVBMemberOwnerType.DeferredMembers array if the resolved module has a bound symbol. If the symbol is unbound, then it's a named deferred module. Only ONE single unnamed deferred module may be semantically (but not statically) defined at any given time in a source project.
2.4.4.2 VBDeferredClassType
Represents a deferred VBClassType.
👉 Deferred class types cannot be presumed to have a default instance (set by a VB_PreDeclaredId module attribute with the value True).
A deferred class is semantically defined when an unbound member call is made against an object variable of a class type that may or may not be defined in the workspace source code. The default name of a deferred class is the word Class followed by as many numeric digits as needed to make the class name unique in the workspace, in numerical order. In other words the default name of a deferred class type is Class1, unless there's already a Class1 module in the workspace, in which case the default name of the deferred class type is Class2, and so on until a unique, non-existing name is found.
⚠️ The names of any deferred type defined in workspace source code must be considered as "in use" for all operations involving the naming of a module, including the addition of new (bound) modules in the workspace or project.
2.4.4.3 VBDeferredTypeDesc
Represents (describes) a VBDeferredType within the type system.
👉 A value (see VBTypeDescValue) of this meta-type is used in the implementation of the Is relational operator, where semantics demand knowledge of a data type where a value is normally required.
None of the other descriptor types are currently in use, but language core or future language extension features may eventually use them as needed. All deferred descriptor types inherit the corresponding non-deferred descriptor type and explicitly shadow (hide) the static TypeInfo property (when the descriptor describes a type).
2.4.4.4 VBDeferredMemberDesc
A descriptor that represents (describes) any VBDeferredTypeMemberSymbol.
2.4.4.4.1 VBDeferredProcedureMemberDesc
A descriptor that represents (describes) a non-returning VBDeferredProcedureMemberSymbol.
2.4.4.4.2 VBDeferredPropertyLetProcedureDesc
A descriptor that represents (describes) a deferred Property Let member.
2.4.4.4.3 VBDeferredPropertySetProcedureDesc
A descriptor that represents (describes) a deferred Property Set member.
2.4.4.4.4 VBDeferredFunctionProcedureDesc
A descriptor that represents (describes) a deferred Function member.
2.4.4.4.5 VBDeferredPropertyGetProcedureDesc
A descriptor that represents (describes) a deferred Function member.
2.4.4.4.6 VBDeferredParameterDesc
A descriptor that represents (describes) a single parameter of a deferred member.
👉 Deferred parameters are inferred from the arguments provided at the call sites of deferred members.
The data type of a deferred parameter depends on how many call sites supply an argument for it, and the data types of these arguments.
- Given only
VBBooleanValuevalues, the data type is VBBooleanType; - Given only
VBObjectValuevalues, the data type is VBObjectType;- If the class type is resolvable (whether deferred or not), the data type is of that specific class type.
- Given any number of
VBStringTypevalues, the data type is VBStringType; - Given any number of
VBEnumTypevalues, the data type is VBIntegerType; - Given any number of
IIntegralNumericTypevalues, the data type is the largest of the candidate types; - Given any number of
IFixedPointNumericTypevalues, the data type is VBCurrencyType; - Given any number of
IFloatingPointNumericTypevalues, the data type is VBDoubleType;
All of the above define a deferred ByVal parameter that is passed by value; the following define a ByRef parameter that must be passed by reference:
- Given a specific
VBUserDefinedTypeValue, the data type is that of the specified UDT. - Given any number of
VBArrayValueor any mixed-bag heterogenous call site arguments, the data type isVariant. This case may not be materializable and should issue semantic flags as appropriate to signal it to any listening language-level extensions.
⏮️ RD-VBAL §2.3 Application Host | ⏭️ RD-VBAL§2.5 Runtime Values