///|
/// A possibly qualified type name.
///
/// The simple ATD type name `a` is represented as `TN(["a"])`.
/// The composite ATD type name `a.b.c` is represented as `TN(["a", "b", "c"])`.
/// The list of path components may not be empty. Two components indicate a
/// type provided by an external module.
pub(all) struct TypeName {
path : Array[String]
} derive(Eq, Hash, Debug)
///|
/// Build a type name from its path components.
pub fn TypeName::new(path : Array[String]) -> TypeName {
{ path, }
}
///|
/// Build an unqualified type name.
pub fn TypeName::simple(name : String) -> TypeName {
{ path: [name], }
}
///|
/// Total order on type names, same as OCaml's polymorphic comparison.
pub impl Compare for TypeName with fn compare(a, b) {
compare_string_lists(a.path, b.path)
}
///|
/// Format to a string in ATD syntax. For example, `TN(["a", "b"])` gives
/// `a.b`.
pub fn TypeName::to_string(self : TypeName) -> String {
self.path.join(".")
}
///|
pub impl Show for TypeName with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
/// Return the base name, i.e. the last component in the path.
pub fn TypeName::basename(self : TypeName) -> String {
match self.path.last() {
Some(x) => x
None => abort("TypeName::basename: empty name")
}
}
///|
/// Test whether the type name is the unqualified name `name`.
pub fn TypeName::is_simple(self : TypeName, name : String) -> Bool {
self.path is [n] && n == name
}
///|
/// Return the module name if any, and the base name.
pub fn TypeName::split(self : TypeName) -> (String?, String) raise AtdError {
match self.path {
[base_name] => (None, base_name)
[local_module_name, base_name] => (Some(local_module_name), base_name)
[] => error("Type_name.split: empty name")
_ =>
error("Type_name.split: more than two components in " + self.to_string())
}
}