Project Structure

Coco code can be organised in a number of different ways:

  • A module is a Coco source file, written filename.coco, which defines a namespace and groups together declarations within it.
  • Modules can be organised into packages, where a package contains a collection of Coco modules, together with a configuration file that describes various settings about the package. Packages can depend on other packages to facilitate code reuse.
  • Packages can be organised into workspaces. A workspace contains a collection of Coco packages, and a configuration file specifying the packages within it, together with default settings that apply to them.

Modules

A module defines a namespace and groups together a number of declarations within it. Each source file automatically creates a module in Coco.

A module can be labelled with attributes to make them applicable across the whole module. To achieve this, the keyword module has to be explicitly included, and then labelled with the corresponding attributes.

The visibility of a module can also be set. For example:

private module

specifies that the module is not visible from outside the package within which it is defined.

A module can refer to definitions in another module, in which case one module depends on the other. However, there must not be any cyclic dependencies between modules. Including modules with cyclic dependencies is a static error.

Declarations

A module may contain the following:

All declarations are lexically scoped: they are visible with the context in which they occur and any of its nested declarations.

Namespaces and Imports

Each module has its own namespace, so a single name may be used in several different modules, with a distinct meaning in each. In order to use a name declared in another module, the module must be imported.

declarationImport
import [unqualified] «module name» [as «new module name»]

In its simplest form, import X, all names declared in X may then be used as X.«name». It is not possible to import only some of the names in a module.

As in Java, the module M must be stored in the file M.coco. A dot (.) in the module name will be converted into a directory separator, so import M.N looks for the file M/N.coco.

Modules can also be imported with a different name using the as keyword followed by a new module name. For example:

import X as Y

In this case, names declared in the imported module X may be used as Y.«name».

Names declared in the current module may not be used qualified (prefixed with the name of the current module).

Alternatively, modules may be imported unqualified, using the keyword unqualified. For example:

import unqualified X

In this case, names declared in the imported module X may be used unqualified in the current module.

It is a static error to use an unqualified name in the current module if it is ambiguous; i.e. if it could refer to two different declarations. An unqualified import of a module that contains declarations of names that are also used in the current module is likely to lead to ambiguous references and thus static errors.

Note

The use of unqualified imports is generally not recommended. However, the standard library is imported unqualified by default into every module.

Packages and Workspaces

Coco modules can be organised into packages, where a package contains a collection of Coco modules, together with a configuration file called “Coco.toml” that describes various settings about the package. Packages can depend on other packages to facilitate code reuse.

Packages can be organised into workspaces. A workspace contains a collection of Coco packages, and a “Coco.toml” configuration file that contains references to packages, together with default settings for that workspace.

The remainder of this section provides a brief introduction to the TOML format used in the configuration files, together with a summary of the tables and key/value pairs supported by Coco. Further configuration settings relating to code generation can be found in Code Generation Options.

TOML format

Coco.toml files are written in TOML, which is a format for specifying configuration files. It is intended to be easy to write and understand, and its syntax primarily consists of key/value pairs, tables, and comments. TOML files are organised by grouping together common configuration settings in tables, where a table is a collection of key/value pairs.

Key/value pairs are written as:

key = value

where value is the configuration value assigned to the key.

In Coco.toml files, values will either be of type Int, Bool, String, or an Array of String elements.

A table is a collection of key/value pairs, written as:

[table]

Comments are written as:

# This is a comment.

For example:

[package]
# Package name
name = "lift_system"
# Location of Coco source files belonging to this package
sources = "src"

[generator.cpp]
# C++ standard generated by the code generator
standard = "C++17"

[verification]
# Remote verification cannot be used for files belonging to this package
allowRemote = false

Inline tables are also supported in Coco.toml files to provide a more compact syntax, where tables can be expressed on one line. An inline table is specified as a comma-separated list of zero or more key/value pairs within curly braces:

table = { key = value, ... }

For example, the package table above can be written inline as follows:

package = { name = "lift_system", sources = "src" }

Coco also supports multi-line basic strings to allow long strings to be written across multiple lines, as illustrated in the following example:

description = """
This is how you can break up a
long string over multiple lines
"""

A multi-line basic string is enclosed by three quotation marks denoting the start and end of the string. The string can include newlines, which are preserved, apart from a newline immediately after the opening three quotation marks that is trimmed.

Package

This section gives an overview of the settings that are exclusively used for packages only.

package setting package
Type:Table

This table specifies the package name, the location of the Coco source files that belong to it, and any of the other settings listed below as required.

package setting package.name
Type:String

Identifier representing the package name.

For example:

[package]
name = "lift_system"
package setting package.sources
Type:Array(String)

Comma-separated list of directories relative to the Coco.toml file that contain the Coco source files belonging to the package.

For example:

[package]
name = "lift_system"
sources = ["src"]

This means that the package called lift_system applies to the Coco source files in the directory src.

package setting package.testSources
Type:Array(String)

Comma-separated list of directories relative to the Coco.toml file that contain .coco files that should be considered as test sources.

Test sources are treated like regular sources (i.e. like package.sources), but have some special features:

  • When generating code, they are output into a separate directory (e.g. generator.cpp.testOutputDirectory) alongside other Coco-generated source files that are relevant to testing, such as mocks;
  • They can depend on files in package.sources, but not the other way around.

This permits .coco files related to testing to be kept as part of the main package, but ensures they are kept separate when generating code.

package setting package.exportConfig
Type:Boolean

Exports configuration settings from a package to other packages that depend on it.

If a setting is specified in both a package P and a package Q that depends on P, then the setting in Q takes precedence. Not all of the configuration settings are exported. For example, the package name and its dependencies are not exported, whereas the the option settings for the code generation are.

package setting package.workspace
Type:String

A reference to the directory (relative to this package’s Coco.toml file) containing the Coco workspace that this package belongs to.

For example:

[package]
name = "lift_system"
sources = ["src"]
workspace = "../bridge_system"

This specifies that the package called lift_system belongs to the workspace in the directory specified.

Workspace

This section gives an overview of the settings that are exclusively used for workspaces only.

package setting workspace
Type:Table

This table specifies the location of the packages that belong to this workspace, and any default settings that apply to them.

package setting workspace.members
Type:Array(String)

Comma-separated list of references to directories (relative to the Coco.toml file) that contain the Coco packages belonging to the workspace.

For example:

[workspace]
members = [
  "lift_system",
  "light_network",
]

This means that the packages in the directories lift_system and light_network belong to this workspace.

A workspace can define default configuration settings for all of the packages that belong to it. For example:

[workspace]
members = [
  "lift_system",
  "light_network",
]

[language]
standard = "1"

In this example, the language settings will be applied as the default to all of the packages that belong to this workspace, namely those in the directories lift_system and light_network. Any configuration settings defined in the Coco.toml file of the packages themselves will override the default ones set by the workspace they belong to. For example, if the Coco.toml file for the package lift_system is defined as follows:

[package]
name = "lift_system"
sources = ["src"]

[language]
standard = "1.1"

then the language standard applied for the Coco modules in this package will be version 1.1 and not the default setting of 1 specified in the workspace it belongs to.

Note

It is recommended that packages are organised in sub-directories of the workspace directory to which they belong. However, a workspace can also include packages that are located elsewhere, for example, the workspace member could be listed as "../bridge_control". In cases where the packages are located elsewhere, then Coco.toml files for those packages must also include a reference to the directory of the workspace they belong to. See package.workspace for further details.

Dependencies

This table captures dependencies between packages, and can be used in packages or workspaces. If a package has many dependencies on other packages in the same workspace, then it is recommended to specify these dependencies in the Coco.toml file of the workspace.

package setting dependencies
Type:Table

Short form dependencies are specified as key-value pairs of the form:

[dependencies]
package_name = "*"

where package_name is the name of the package that this one depends on. This means that there must exist a Coco.toml file whose package.name property is equal to package_name. The string refers to which version of the package should be depended on. Currently, the only supported constraint is *, which means any version, as written above.

Dependencies can also be specified in a longer form, for example, the short form dependency above is equivalent to:

[dependency.package_name]
version = "*"

Language

This table consists of all of the configuration settings related to the Coco language, which can be used in packages or workspaces.

package setting language
Type:Table
package setting language.disabledWarnings
Type:Array(String)
Value:The string name of any enum case from Warning (e.g. "IncompleteMatch").
package setting language.profiles
Type:

Array(String)

Values:
  • "C" – Restricts Coco to features that are supported by the C generator.
  • "C++" – Restricts Coco to features that are supported by the C++ generator.
  • "C#" – Restricts Coco to features that are supported by the C# generator.
Default value:

“[]”

The Coco Platform supports the generation of multiple target languages, but not all Coco features are supported by all of them. To avoid unsupported features being diagnosed late during code generation, Coco uses profiles to define additional rules that Coco source files must adhere to. This means that diagnostics can be provided to users as early as possible during type checking of their Coco source files.

For example, the following setting:

[language]
profiles = ["C++"]

means that the profile for C++ applies to the Coco source files belonging to the package. As an example of an additional rule this introduces, when this profile is applied to the following valid Coco port declaration:

port Conflict {
  struct Conflict {}
}

a static error will be raised during type checking stating that types cannot have the same name as their parent port when the C++ profile is enabled. C++ does not support a class and nested class having the same identifier, and would therefore lead to a compilation error of the generated C++. Rather than discovering this problem during compilation, the Coco profiles help users catch these errors earlier in Coco, which is much more efficient.

package setting language.standard
Type:

String

Values:
  • "1"1
  • "1.1"1.1

Sets the language standard to be used by the Coco source files belonging to this package.

For example, the following setting:

[language]
standard = "1"

will set the Coco language to version 1.

See also

Language Standards for descriptions of Coco language versions.

Format

This table consists of all of the configuration settings related to the formatting of the Coco source files. These settings can be used in packages or workspaces.

package setting format
Type:Table
package setting format.allowShortBlocksOnASingleLine
Type:Boolean
Default value:false
package setting format.allowShortCaseLabelsOnASingleLine
Type:Boolean
Default value:false
package setting format.allowShortFunctionsOnASingleLine
Type:

String

Values:
  • "All" – All functions that are short can be placed onto a single line.
  • "Empty" – Only empty functions can be placed onto a single line.
  • "None" – No functions can be placed onto a single line.
Default value:

“All”

package setting format.allowShortIfStatementsOnASingleLine
Type:Boolean
Default value:true

If true, then all short if statements can be placed onto a single line.

package setting format.allowShortLoopsOnASingleLine
Type:Boolean
Default value:false

If true, then all short loops can be placed onto a single line.

package setting format.columnLimit
Type:Int
Default value:120

Sets the column width limit to the specified length.

package setting format.sortImports
Type:Boolean
Default value:true
package setting format.indentWidth
Type:Int
Default value:2

Sets the indent width to the specified length.

package setting format.tabWidth
Type:Int
Default value:8

Sets the tab width to the specified length.

package setting format.useTabs
Type:

String

Values:
  • "Always" – Always use tabs.
  • "ContinuationAndIndentation" – Only use tabs for continuation and indentation.
  • "Indentation" – Only use tabs for indentation.
  • "Never" – Never use tabs.
Default value:

“Never”

Generator

This table consists of all of the configuration settings related to the generation of code from Coco. These settings can be used in packages or workspaces.

package setting generator
Type:Table
package setting generator.defaultLanguage

Sets the language that will be generated by default when pressing Generate Code in one of the Coco GUI tools (e.g. Eclipse).

Type:

String

Values:
  • "C"
  • "C++"
Default value:

“C++”

package setting generator.cpp

Sets the settings used when generating C++. See Code Generation Options for further information.

Type:Table:

Tool

package setting tool
Type:Table

This table consists of all of the configuration settings related to the tool itself.

package setting tool.requiredVersion
Type:String

Specifies the version of the Coco Platform that is required by this package. This must be a version constraint of the form >= version or > version, where version is a partial semantic version; i.e. it is a string of the form x.y.z-p where x, y and z are integers, and p is a string. Any suffix of this may be omitted. For example: >= 1, >= 1.0, >= 1.0.0 are all equivalent. Pre-releases can also be included, such as >= 1.0.0-beta.3.

package setting tool.selectedVersion
type:String

Specifies the preferred version of the Coco Platform as a string of the form x.y.z. Tools that can automatically download the Coco Platform on-demand will use this version.

Note that you should not attempt to parse this value using your own scripts, as the values supported here might change over time. Instead use coco metadata --selected-tool-version to extract the value.

Verification

This table consists of all of the configuration settings related to the verification. These settings can be used in packages or workspaces.

package setting verification
Type:Table
package setting verification.allowRemote
Type:Boolean
Default value:true

Sets the access rights to the remote verification service.

For example, the following setting:

[verification]
allowRemote = false

will prohibit the Coco source files that belong to this package from using the remote verification service.