I was thinking about a lookup scheme first. Below is a draft indicating how far I got before I abandoned that line of thought.
The problem with a lookup based scheme is that it complicates further what is already complicated: lookup. This means many interactions with other parts of the compiler. By contrast, the forwarder scheme is simple in the sense of being independent from the rest of the compiler. Once forwarders are generated in Namer we are done; no other part of the compiler needs to be concerned with exports. Also, the Tasty format does not need to have entries for them.
About size of generated code: Yes it’s a concern, but not worse than what we already do for mixins. If size of the generated byte code was of primary importance we could decree that all export alias methods are inline
, which means no byte code is generated for them. That would give us power roughly on par with a lookup based scheme. But it would mean that export aliases would be invisible to Java and that they could not implement interface methods.
layout: doc-page
title: “Export”
Syntax changes:
TemplateStat ::= ...
| Export
Export ::= ‘export’ ImportExprs
Similarly to imports, an export with several parts
export iexpr_1, ..., iexpr_n`
is a shorthand for
export iexpr_1
...
export iexpr_n`
To explain how export clauses influence type checking we explain in the following one possible scheme. As always, compilers are free to pick a different scheme if the observable results are the same.
An export export prefix . selectors
in a template is legal if prefix
is a path that refers either to a member of the template or to a globally accessible object.
Such an export generates a public “export” member with a compiler-generated name that’s inaccessible to user programs and globally unique, and a special type
ExportType(PT, E)
where E
is the export clause itself and PT
is the type of prefix
. The PT
part of an ExportType
behaves as usual with regards to type maps such as substitution or as-seen-from.
When typing a selection p.m
, if p
does not have a member named m
, the following adaptation is tried before searching for an implicit conversion of p
:
Let es
be all the export members of p
. We first search all explicit exports and then, if that returns no results, all wildcard exports for a match with m
, exactly as it is done when processing import statements. If there are several matching members they all must have the same prefix type PT
, or an ambiguity error is reported. Otherwise, pick an arbitary element of the set of matching members, say member e
defined in class C
with type ExportType(PT, export q . ss)
. The selection p.m
is then rewritten to one of the following alternatives, depending on the form of q
.
- If
q
refers to a globally accessible object:q.m
- If
q
is of the formC.this . q_1 . ... q _n
:p . q_1 . ... . q_n . m