Namespace (as specialized)

Description
Constructs::Namespace reuses the definition of Abstractions::Constraints::Namespace.

A namespace has the ability to import either individial members or all members of a package, thereby making it possible
to refer to those named elements without qualification in the importing namespace. In the case of conflicts, it is necessary
to use qualified names or aliases to disambiguate the referenced elements.

Attributes
No additional attributes.

Associations

elementImport: ElementImport [*] References the ElementImports owned by the Namespace. Subsets
Element::ownedElement.
/importedMember: PackageableElement [*]References the PackageableElements that are members of this Namespace as
a result of either PackageImports or ElementImports. Subsets
Namespace::member.
/member: NamedElement [*] Redefines the corresponding property of Abstractions::Namespaces::Namespace.
/ownedMember: NamedElement [*]Redefines the corresponding property of Abstractions::Namespaces::Namespace.
packageImport: PackageImport [*] References the PackageImports owned by the Namespace. Subsets
Element::ownedElement.

Constraints

  1. The importedMember property is derived from the ElementImports and the PackageImports.
    self.importedMember->includesAll(self.importedMembers(self.elementImport.importedElement.asSet()-
    >union(self.packageImport.importedPackage->collect(p | p.visibleMembers()))))

Additional operations

  1. The query getNamesOfMember() is overridden to take account of importing. It gives back the set of names that an element
    would have in an importing namespace, either because it is owned, or if not owned then imported individually, or if not
    individually then from a package.
    Namespace::getNamesOfMember(element: NamedElement): Set(String);
    getNamesOfMember=
    if self.ownedMember ->includes(element)
    then Set{}->include(element.name)
    else let elementImports: ElementImport = self.elementImport->select(ei | ei.importedElement = element) in
    if elementImports->notEmpty()
    then elementImports->collect(el | el.getName())
    else self.packageImport->select(pi | pi.importedPackage.visibleMembers()->includes(element))->
    collect(pi | pi.importedPackage.getNamesOfMember(element))
    endif
    endif
  2. The query importMembers() defines which of a set of PackageableElements are actually imported into the namespace.
    This excludes hidden ones, i.e., those which have names that conflict with names of owned members, and also excludes
    elements which would have the same name when imported.
    Namespace::importMembers(imps: Set(PackageableElement)): Set(PackageableElement);
    importMembers = self.excludeCollisions(imps)->select(imp | self.ownedMember->forAll(mem |
    mem.imp.isDistinguishableFrom(mem, self)))
  3. The query excludeCollisions() excludes from a set of PackageableElements any that would not be distinguishable from
    each other in this namespace.
    Namespace::excludeCollisions(imps: Set(PackageableElements)): Set(PackageableElements);
    excludeCollisions = imps->reject(imp1 | imps.exists(imp2 | not imp1.isDistinguishableFrom(imp2, self)))

Semantics
No additional semantics.

Notation
No additional notation.