@@ -13,13 +13,17 @@ There are two kinds of classfiles:
1313The following terms are used throughout this document:
1414- Class extension: the normalized classfile suffix used for framework lookup, e.g., ` _app.gox ` and ` .gsh `
1515- Class file stem: the filename without the class extension
16+ - Project classfile: the framework file that represents the project-level class
17+ - Project file kind: a framework file kind declared by one ` project ` directive and used for project classfiles
18+ - Work classfile: a framework file that represents a non-project class within the same framework
19+ - Work file kind: a framework file kind declared by one ` class ` directive and used for work classfiles
1620- Class type: the generated named type for a classfile
21+ - Base class: an embedded framework type declared by classfile metadata
22+ - Work prototype type: an exported type declared by classfile metadata and associated with one work file kind
23+ - Work surface type: an exported interface type declared by classfile metadata and associated with one work file kind
1724- Field declaration block: the unique top-level ` var ` declaration that is interpreted as class fields rather than
1825 package variables
1926- Shadow entry: the synthetic function created from top-level statements
20- - Project classfile: the framework file that represents the project-level class
21- - Work classfile: a framework file that represents a non-project class within the same framework
22- - Base class: an embedded framework type declared by classfile metadata
2327
2428## File classification
2529
@@ -172,8 +176,8 @@ Examples:
172176- ` get_p_#id_app.gox ` has class file stem ` get_p_#id ` and normalized type name ` get_p_id `
173177
174178Framework metadata may further transform the type name:
175- - A project file whose class file stem is ` main ` , or a framework that has no explicit project file , uses the project
176- base-class name as its default class type name. A leading ` * ` on the base- class name is removed
179+ - A project classfile whose class file stem is ` main ` , or a framework that has no explicit project classfile , uses the
180+ name of the project base type as its default class type name
177181- A non-empty work-class ` -prefix= ` is prepended to the normalized work-file stem
178182- If neither of the previous rules applies and the class type name would otherwise equal one of the reserved names
179183 ` init ` , ` main ` , ` go ` , ` goto ` , ` type ` , ` var ` , ` import ` , ` package ` , ` interface ` , ` struct ` , ` const ` , ` func ` , ` map ` ,
@@ -194,7 +198,7 @@ For a framework classfile, framework-added fields precede user fields.
194198
195199Framework-added fields are inserted in the following order:
196200- For a project classfile, the embedded project base class
197- - For a project classfile, each embedded work-class field requested by the ` -embed ` flag, in work-class declaration
201+ - For a project classfile, each embedded work-class field requested by the ` -embed ` flag, in work file-kind declaration
198202 order and lexicographic source-file path order
199203- For a work classfile, the embedded work base class
200204- For a work classfile, an embedded pointer to the project class type, if a project class type exists and its field name
@@ -359,18 +363,18 @@ The classfile loader recognizes the following module directives:
359363ProjectDirective = "project" [ ProjectExt ExportedName ] PackagePath { PackagePath } .
360364ClassDirective = "class" { ClassDirectiveFlag } WorkExt ExportedName [ ExportedName ] .
361365ImportDirective = "import" [ ImportName ] PackagePath .
362- ClassDirectiveFlag = "-embed" | "-prefix=" string_without_space .
366+ ClassDirectiveFlag = "-embed" | "-prefix=" string_without_space | "-surface=" ExportedName .
363367```
364368
365369Every ` class ` or ` import ` directive belongs to the most recent preceding ` project ` directive.
366370
367371A project group consists of one ` project ` directive together with all ` class ` and ` import ` directives that belong to it.
368372
369- The first package path of a ` project ` directive is the framework package used to resolve any base- class symbols named by
370- that project group.
373+ The first package path of a ` project ` directive is the framework package used to resolve the project base class, each
374+ work base class, each work prototype type, and each work surface type named by that project group.
371375
372- Any additional package paths participate in implicit framework-package export lookup but are not searched for
373- base-class symbols.
376+ Any additional package paths participate in implicit framework-package export lookup but are not searched for those
377+ symbols.
374378
375379### Extension forms and normalization
376380
@@ -410,18 +414,49 @@ For each `project` directive:
410414
411415For each ` class ` directive:
412416- The exported symbol names the work base class
417+ - The first package path is the package from which that symbol is resolved
413418- The optional final exported symbol is the work prototype type
414- - If a project group declares more than one work class kind, every work class in that group must declare a prototype
419+ - If a project group declares more than one work file kind, every work file kind in that group must declare a prototype
415420 type
421+ - When a work prototype type is named, the first package path is the package from which that symbol is resolved
422+ - ` -embed ` causes the project class type to embed a field for each generated work class instance of that work file kind
416423- ` -prefix= ` prepends the given string to every generated work class type name
417- - ` -embed ` causes the project class type to embed a field for each generated work class instance of that work kind
424+ - ` -surface= ` names the work surface type of the declared work file kind and may appear at most once in a ` class `
425+ directive
426+ - When ` -surface= ` is present, the named symbol must resolve to an exported interface type in the framework package of
427+ the containing project group
428+ - Within one project group, no two work file kinds may declare the same work surface type
418429
419430For each ` import ` directive:
420431- The imported package becomes available to classfiles as an auto-imported package name
421432- If no explicit import name is supplied, the package's declared package name is used
422433- If multiple ` import ` directives in the same project group resolve to the same auto-import name, the last directive
423434 wins
424435
436+ ## Work surface types
437+
438+ For a work file kind that declares ` -surface= ` , the named interface type is the work surface type of that work file
439+ kind. The work surface type defines the public semantic surface of that work file kind. It is additional classfile
440+ metadata associated with that work file kind.
441+
442+ The work surface type is not a base class. It is not embedded into the generated work class type. It does not alter the
443+ lowered class type or its lowered methods.
444+
445+ The work surface type does not affect:
446+ - File classification
447+ - Class type naming
448+ - Field layout
449+ - Name resolution inside class methods
450+ - Project ` Main ` assembly
451+ - Synthesized helper-method generation
452+
453+ For every generated work class type ` T ` of that work file kind, ` *T ` must implement the work surface type of that work
454+ file kind. It is an error if, for any generated work class type ` T ` of that work file kind, ` *T ` does not implement the
455+ work surface type of that work file kind.
456+
457+ If no ` -surface= ` is declared for a work file kind, this specification defines no work surface type for that work file
458+ kind.
459+
425460## Project and work-class assembly
426461
427462A test framework registration is a framework registration whose project extension has the suffix ` test.gox ` .
@@ -434,8 +469,8 @@ For each framework registration, a package may contain at most one explicit proj
434469
435470It is an error for a package to contain more than one explicit project classfile for the same framework registration.
436471
437- If a framework registration provides a project base class but the package contains no explicit project file for that
438- framework, the compiler still synthesizes a default project class type.
472+ If a framework registration provides a project base class but the package contains no explicit project classfile for
473+ that framework, the compiler still synthesizes a default project class type.
439474
440475The synthesized project class has no source file of its own. Its type name is derived by the project type-naming rules
441476described earlier.
@@ -448,21 +483,21 @@ The generated project method constructs work-class instances and forwards them t
448483` Main ` .
449484
450485The grouping rule is:
451- - If the framework has exactly one work class kind and that ` Main ` parameter is variadic, all work files of that kind
452- are passed as variadic arguments
453- - Otherwise, work files are grouped by their declared prototype type and passed as slices in ` Main ` parameter order
486+ - If the framework has exactly one work file kind and that ` Main ` parameter is variadic, all work files of that kind are
487+ passed as variadic arguments
488+ - Otherwise, work files are grouped by their declared work prototype type and passed as slices in ` Main ` parameter order
454489
455490The project ` Main ` method constructs one fresh work-class instance for each work file in the package. When ` -embed ` is
456- present on a work class declaration , the freshly created work instance is also assigned into the corresponding embedded
457- field on the project instance before the project ` Main ` call.
491+ present on the corresponding ` class ` directive , the freshly created work instance is also assigned into the
492+ corresponding embedded field on the project instance before the project ` Main ` call.
458493
459494## Synthesized helper methods
460495
461- The compiler may synthesize additional work-class methods when the declared work prototype requires them.
496+ The compiler may synthesize additional work-class methods when the declared work prototype type requires them.
462497
463498### ` Classfname `
464499
465- If the work prototype contains a method named ` Classfname ` , the compiler generates:
500+ If the work prototype type contains a method named ` Classfname ` , the compiler generates:
466501
467502``` xgo
468503func (this *T) Classfname() string
@@ -476,9 +511,9 @@ Examples:
476511
477512### ` Classclone `
478513
479- If the work prototype contains a method named ` Classclone ` , the compiler generates a shallow-clone method named
480- ` Classclone ` with no parameters other than the receiver. Its result list is adopted from the prototype's ` Classclone `
481- declaration.
514+ If the work prototype type contains a method named ` Classclone ` , the compiler generates a shallow-clone method named
515+ ` Classclone ` with no parameters other than the receiver. Its result list is adopted from the work prototype type's
516+ ` Classclone ` declaration.
482517
483518The generated implementation copies ` *this ` by value into a temporary variable and returns the address of that temporary
484519value.
@@ -492,7 +527,7 @@ If one exists, no class-based package `main` is synthesized.
492527
493528If none exists, the compiler selects a class entrypoint as follows:
4945291 . It considers only non-test framework registrations
495- 2 . Among framework project groups, it prefers a unique project group whose explicit project file has a shadow entry
530+ 2 . Among framework project groups, it prefers a unique project group whose explicit project classfile has a shadow entry
4965313 . If no such group exists, it prefers a unique remaining project group, including one that is represented only by a
497532 synthesized default project class
4985334 . If no project group is selected, it selects the unique normal classfile that has a shadow entry, if exactly one
0 commit comments