@@ -645,8 +645,8 @@ instancedecl ::= core-prefix(<core:type>)
645645 | <type>
646646 | <alias>
647647 | <exportdecl>
648- importdecl ::= (import <externnamelit> <attribute>* bind-id(<externtype>))
649- exportdecl ::= (export <externnamelit> <attribute>* bind-id(<externtype>))
648+ importdecl ::= (import <externnamelit> <attributes> bind-id(<externtype>))
649+ exportdecl ::= (export <externnamelit> <attributes> bind-id(<externtype>))
650650externtype ::= (<sort> (type <idx>) )
651651 | core-prefix(<core:moduletype>)
652652 | <functype>
@@ -1121,9 +1121,10 @@ and `$C1` is a subtype of `$C2`:
11211121)
11221122```
11231123
1124- 🏷️/🔗 Note that all ` attribute ` s on ` import ` s and ` export ` s are ignored by type
1125- checking and so any ` external-id ` , ` implements ` or ` versionsuffix ` attribute can
1126- be added to any of the ` func ` s above without changing the result.
1124+ 🏷️/🔗 Note that all ` attributes ` on ` import ` s and ` export ` s are ignored by type
1125+ checking and so adding, removing or changing any ` external-id ` attribute on the
1126+ ` func ` s above (or any ` implements ` or ` version-suffix ` attribute on ` instance `
1127+ imports or exports) does not change the result.
11271128
11281129When we next consider type imports and exports, there are two distinct
11291130subcases of ` typebound ` to consider: ` eq ` and ` sub ` .
@@ -2661,17 +2662,15 @@ exported (e.g., `(export $x "x" (func $f))` binds a new identifier `$x`).
26612662
26622663Given this, the syntax of imports and exports are defined as follows:
26632664``` ebnf
2664- import ::= (import <externnamelit> <attribute>* bind-id(<externtype>))
2665- export ::= (export <id>? <externnamelit> <attribute>* <externidx> <externtype>?)
2666- attribute ::= <versionsuffix> 🔗
2667- | <implements> 🏷️
2668- | <externid> 🏷️
2669- versionsuffix ::= (versionsuffix <semversuffixlit>) 🔗
2665+ import ::= (import <externnamelit> <attributes> bind-id(<externtype>))
2666+ export ::= (export <id>? <externnamelit> <attributes> <externidx> <externtype>?)
2667+ attributes ::= <implements>? <versionsuffix>? <externid>?
26702668implements ::= (implements <interfacenamelit>) 🏷️
2669+ versionsuffix ::= (version-suffix <semversuffixlit>) 🔗
26712670externid ::= (external-id <name>) 🏷️
26722671```
26732672Imports and exports both have a * name* (` externnamelit ` ) and a list of
2674- * attributes* (` attribute* ` ). Imports always include a type (` externtype ` ).
2673+ * attributes* (` attributes ` ). Imports always include a type (` externtype ` ).
26752674Exports always refer to a preceding definition (` externidx ` ) whose type is used
26762675by default as the type of the export. However, this "inferred" type can be
26772676overridden with an optional type ascription (` externtype ` ) which must be
@@ -2689,10 +2688,19 @@ and exports and instead provide extra semantic information *about* imports and
26892688exports that hosts or tools can automatically interpret to determine * how* to
26902689supply imports and call exports. In particular:
26912690
2692- 🔗 The ` versionsuffix ` attribute provides the minor/patch/pre-release/build
2693- information that was stripped from the [ Canonical interface name] ( #-canonical-interface-name )
2694- so that this information can be used in error messages to reconstruct the full
2695- original semantic version.
2691+ 🔗 The ` version-suffix ` attribute provides the minor/patch/build information that
2692+ was stripped from the [ Canonical interface name] ( #-canonical-interface-name ) so
2693+ that this information can be used in error messages to reconstruct the full
2694+ original semantic version. A ` version-suffix ` may only be attached to an
2695+ ` instance ` import or export and applies to the ` interfacename ` of the
2696+ ` implements ` attribute, if present, and otherwise to the ` interfacename ` of the
2697+ import or export itself. For example:
2698+ ``` wat
2699+ (component
2700+ (import "wasi:http/types@0.2" (version-suffix ".6") (instance ...))
2701+ (import "primary" (implements "wasi:keyvalue/store@0.2") (version-suffix ".1") (instance ...))
2702+ )
2703+ ```
26962704
26972705🏷️ The ` implements ` attribute indicates that an imported or exported ` instance `
26982706implements a particular WIT interface. This enables a component to semantically
@@ -2780,8 +2788,9 @@ canonversion ::= [1-9] [0-9]* 🔗
27802788 | '0.' [1-9] [0-9]* 🔗
27812789 | '0.0.' [1-9] [0-9]* 🔗
27822790 | '0.0.0' 🔗
2791+ | <version core> '-' <pre-release> 🔗
27832792semversuffixlit ::= '"' <semversuffix> '"' 🔗
2784- semversuffix ::= [0-9A-Za-z.+-]* 🔗
2793+ semversuffix ::= [0-9A-Za-z.+-]+ 🔗
27852794```
27862795The names of component imports and exports provide two options:
27872796* a ** plain name** that leaves it up to the developer to "read the docs"
@@ -2824,8 +2833,9 @@ annotations trigger additional type-validation rules (listed in detail in
28242833 parameter from ` [method] ` ) whose type matches the getter's return type, and
28252834 must return either nothing or ` (result (error <valtype>)?) ` .
28262835
2827- The ` valid semver ` production is as defined by the [ Semantic Versioning 2.0]
2828- spec and is meant to be interpreted according to that specification. The use of
2836+ The ` valid semver ` production (along with its ` version core ` and ` pre-release `
2837+ sub-productions) is as defined by the [ Semantic Versioning 2.0] spec and is
2838+ meant to be interpreted according to that specification. The use of
28292839` valid semver ` in ` interfaceversion ` is temporary for backward compatibility;
28302840see [ Canonical interface name] ( #-canonical-interface-name ) below (🔗).
28312841
@@ -2991,12 +3001,19 @@ the `<major>.<minor>.<patch>(-<pre>)(+<build>)` syntax of [Semantic Versioning
29913001 - ` 0.0.1+sha.5114f85 ` &rarr ; ` 0.0.1 ` / ` +sha.5114f85 `
29923002
29933003When a version is canonicalized, any ` semversuffix ` that was split off of the
2994- version should be preserved in the ` versionsuffix ` field of any resulting
2995- ` import ` s and ` export ` s. This gives component runtimes and other tools access to
2996- the original version for error messages, documentation, and other development
2997- purposes. Where a ` versionsuffix ` is present the preceding ` interfacename ` must
2998- have a ` canonversion ` , and the concatenation of the ` canonversion ` and
2999- ` versionsuffix ` must be a ` valid semver ` .
3004+ version must be preserved in the ` version-suffix ` attribute of any resulting
3005+ ` import ` s and ` export ` s to give component runtimes and other tools access to the
3006+ original version for error messages, documentation, and other development
3007+ purposes. Validation checks this by requiring that the ` interfaceversion `
3008+ concatenated with the ` version-suffix ` (if present) is a ` valid semver ` and that,
3009+ when a ` version-suffix ` is present, canonicalizing the concatenated ` valid semver `
3010+ splits it into exactly the ` interfaceversion ` and the ` version-suffix ` . Thus,
3011+ for example:
3012+ - ` a:b/c@1 ` is invalid (` 1 ` is not a ` valid semver ` )
3013+ - ` a:b/c@1 ` with ` .2.3 ` and ` a:b/c@0.0.1-alpha ` with ` +sha ` are valid
3014+ - ` a:b/c@1 ` with ` .2.3-alpha ` is invalid (` 1.2.3-alpha ` is not split)
3015+ - ` a:b/c@1.2 ` with ` .3 ` and ` a:b/c@1.2.3 ` with ` +sha ` are invalid (` 1.2.3 ` and
3016+ ` 1.2.3+sha ` are split after ` 1 ` )
30003017
30013018For compatibility with older versions of this spec, non-canonical
30023019` interfacename ` s (with ` interfaceversion ` s matching any ` valid semver ` ) are
0 commit comments