Attributes

Attributes have two major functions:

  • they can act as instructions to compiler to influence how code is generated, or
  • to annotate Forms, Modules, Classes, Types, Enums, Declares, and procedures i.e. Subs/Functions/Properties.

Previously in VBx, these attributes, such as the procedure description, hidden, default member, and others, were set via hidden text the IDE’s editor didn’t show you, configured via the Procedure Attributes dialog or some other places. In tB, these are all visible in the code editor. The legacy ones from VBx are supported for compatibility, but new attributes utilize the following syntax:
[Attribute] or [Attribute(value)]


The available attributes are listed below in alphabetic order. Not every attribute applies to every language element. The applicability of each attribute is given below its syntax.


AppObject

Syntax: [AppObject]

Applicable to: CoClass

Indicates the class is part of the global namespace. You should not include this attribute without a full understanding of the meaning.

ArrayBoundsChecks(Bool)

Syntax: ArrayBoundsChecks( True | False)

Applicable to: Class, Module, procedure

Disables array element access bounds checking. Used on performance-critical routines. The default value is True.

CoClassCustomConstructor(String)

Syntax: [CoClassCustomConstructor(“ fully qualified path to factory method ”)]

Applicable to: CoClass

Allows custom logic for creating and returning a new instance of the coclass’ implementation.

Example:

[CoClassId("7980D953-10BF-478C-93BB-DD0093315D96")]
[CoClassCustomConstructor("FooFactory.CreateFoo")]
[COMCreatable(True)]
Public CoClass Foo
   ' ...
End CoClass

For an overview of coclasses in tB, see Defining coclasses.

CoClassId(String)

Syntax: [CoClassId(“00000000-0000-0000-0000-000000000000”)]

Applicable to: CoClass

In addition to interfaces, twinBASIC also allows defining coclasses – creatable classes that implement one or more defined interfaces. Like interfaces, these too must be in .twin files and not legacy .bas/.cls files, and must appear prior to the Class or Module statement. The generic form is:

[CoClassId("00000000-0000-0000-0000-000000000000")]
*<attributes>*
CoClass <name>
    [Default] Interface <interface name>
    *[Default, Source] Interface <event interface name>*
    *<additional Interface items>*
End CoClass

The methods are procedures.

For an overview of coclasses in tB, see Defining coclasses.

ComCreatable(Bool)

Syntax: [ComCreatable(True | False)]

Applicable to: CoClass

Indicates that this coclass can be created with the New keyword. This attribute is is True by default.

ComExtensible(Bool)

Syntax: [ComExtensible(True | False)]

Applicable to: Interface, procedure in an Interface

Specifies whether new members added at runtime can be called by name through an interface implementing IDispatch. This attribute is set to False by default.

ComImport

Syntax: [ComImport]

Applicable to: Interface

Specifies that an interface is an import from an external COM library, for instance, the Windows shell.

CompileIf(Bool)

Syntax: [CompileIf( condition )]

Applicable to: procedure definitions

Controls the conditional compilation of a procedure definition. Has no default value.

ConstantFoldable

Syntax: [ConstantFoldable]

Applicable to: Function

Specify this attribute for functions where when called with non-variable input, will be computed at compile time, rather than runtime. For example, a function to converted string literals to ANSI. The result would never change, so the resulting ANSI string is stored, rather than recomputing every run. Such functions are also called pure functions, because their output only depends on the arguments, and not on the state of the program.

Debuggable(Bool)

Syntax: [Debuggable(True | False)]

Applicable to: Module, procedure in a Class or Module

When false, turns of breakpoints and stepping for the method or module. The default value is True.

DebugOnly

Syntax: [DebugOnly]

Applicable to: procedure definitions

Excludes calls to this procedure from the Build. They are only available when running from the IDE, i.e. debugging.

Description(String)

Syntax: [Description(“ arbitrary text ”)]

Applicable to: Class, CoClass, Const, Declare (API declaration), Interface, Module, Type (UDT)

Provides a description in information popups in the IDE, and is exported as a helpstring attribute in the type library (if applicable).

DispId(Integer)

Syntax: [DispId( 123 )]

Applicable to: procedure in an Interface

Defines a dispatch ID associated with the procedure.

DllExport

Syntax: [DllExport]

Applicable to: procedures and variables in a module.

It’s possible to export a function or variable from standard modules. Example:

[DllExport]
Public Const MyExportedSymbol As Long = &H00000001

DllStackCheck(Bool)

Syntax: DllStackCheck( True | False)

Applicable to: Declare (API declaration)

Gives minor codegen size reduction on 32-bit API calls on the Intel platform. Has no effect on other platforms.

EnumId(String)

Syntax: [EnumId(“ 00000000-0000-0000-0000-000000000000 ”)]

Applicable to: Enum

Specifies a GUID to be associated with an enum in type libraries.

Flags

Syntax: [Flags]

Applicable to: Enum

Calculate implicit enum values as a flag set (powers of 2).

Note

To prevent confusion, once an explicit value is used, all remaining values after it must also be explicit)

image

FloatingPointErrorChecks(Bool)

Syntax: FloatingPointErrorChecks( True | False)

Applicable to: Class, Module, procedure

Disables floating point error checks. Used on performance-critical routines. The default value is True.

Hidden

Syntax: [Hidden]

Applicable to: CoClass, Interface

Hides the interface or coclass from certain Intellisense and other lists.

IntegerOverflowChecks(Bool)

Syntax: IntegerOverflowChecks( True | False)

Applicable to: Class, Module, procedure

Disables integer overflow checks. Used on performance-critical routines. The default value is True.

InterfaceId(String)

Syntax: [InterfaceId(“00000000-0000-0000-0000-000000000000”)]

Applicable to: Interface

twinBASIC supports defining COM interfaces using BASIC syntax, rather than needing an type library with IDL and C++. These are only supported in .twin files, not in legacy .bas or .cls files. They must appear before the Class or Module statement, and will always have a project-wide scope. the The generic form for is as follows:

[InterfaceId ("00000000-0000-0000-0000-000000000000")]
*<attributes>*
Interface <name> Extends <base-interface>
    *<attributes>*
	<method 1>
	*<attributes>*
	<method 2>
	' ...
End Interface

The methods are procedures.

For an overview of interfaces in tB, see Defining interfaces.

OleAutomation(Bool)

Syntax: [OleAutomation(True | False)]

Applicable to: Interface

Controls whether this attribute is applied in the typelibrary. This attribute is set to True by default.

PopulateFrom(…)

Syntax: [PopulateFrom(“json”, “internal path to .json”, “ table field ”, “ name field ”, “ value field ” )]

Applicable to: Enum

Populates an Enum with values from a json file bundled with the project.

The path to the .json file, and the field names, are arbitrary. Thus, the json file doesn’t have to be in the Resources folder within the project.

In the future, this attribute may be expanded to allow more data file types, and more context of use besides Enum.

For example, consider this enum declaration in a .twin file:

[PopulateFrom("json", "/Resources/MESSAGETABLE/Strings.json", "events", "name", "id")]
Enum EVENTS
End Enum

Then, there should be a /Resources/MESSAGETABLE/Strings.json file with following structure:

{
    "events": 
    [
        {
            "id": -1073610751,
            "name": "service_started",
            "LCID_0000": "%1 service started"
        },
    ],
}

The result is as-if we hand-typed the following Enum definition:

Enum EVENTS
    service_started = -1073610751
End Enum

PredeclaredID

Syntax: [PredeclaredId]

Applicable to: Class

When set, a global instance of the class is created when the application starts.

This attribute is equivalent to the VB_PredeclaredId attribute in VBx .cls files.

PreserveSig(Bool)

Syntax: [PreserveSig [ ( True | False ) ] ]

Applicable to: Method in an Interface, API Declarations.

Default value: False in an Interface, True in an API Declare.

In COM interfaces, the default value of this attribute is False, since normally methods return an HRESULT that the language hides from you. [PreserveSig [ (True) ] ] overrides this behavior and defines the function exactly as you provide. This is necessary if you need to define it as returning something other than a 4-byte Long, or want to handle the result yourself, bypassing the normal runtime error raised if the return value is negative (this is helpful when a negative value indicates an expected, acceptable failure, rather than a true error, like when an enum interface is out of items).

In APIs, the default value of this attribute is True. So therefore, you can specify False in order to rewrite the last parameter as a return. Example:

Public Declare PtrSafe Function SHGetDesktopFolder Lib "shell32" (ppshf As IShellFolder) As Long

can be rewritten as

[PreserveSig(False)] 
Public Declare PtrSafe Function SHGetDesktopFolder Lib "shell32" () As IShellFolder`

Restricted

Syntax: [Restricted]

Applicable to: Interface

Restricts the interface methods from being called in most contexts.

This is attribute has the same function as the restricted MIDL attribute.

RunAfterBuild

Syntax: [RunAfterBuild]

Applicable to: Function, Sub

Specifies a function that runs after your exe is built. Tthere’s App.LastBuildPath to know where it is if you’re e.g. signing the executable.

SetDllDirectory(Bool)

Syntax: [SetDllDirectory( True | False)]

Applicable to: Declare (API declaration), Module

Allows an explicitly loaded DLL to load its own dependencies from it’s load path. Also has the effect of allowing searching the app path for the DLLs in the base app’s declare statements. It can be used per-declare or within a module.

TypeHint(EnumType)

Syntax: [TypeHint( an enum type )]

Applicable to: procedure parameters

Allows populating Intellisense with an enum for types other than Long.

Unimplemented

Syntax: [Unimplemented]

Applicable to: procedure definitions

Makes the compiler issue a warning about the procedure being unimplemented wherever it’s called. You can upgrade it to an error too.