Skip to content

Commit

Permalink
Add support for semicolon delimiters to wit-parser (#1212)
Browse files Browse the repository at this point in the history
* Add support for semicolon delimiters to `wit-parser`

This commit is an implementation of WebAssembly/component-model#142 to
add semicolon delimiters to the WIT text format. The intention of this
change is to be rolled out gradually to minimize ecosystem disruption
(although some is inevitable). The strategy implemented in this commit
is to add support to parse semicolons but optionally do so. Requiring
semicolons is configured via:

* A new `WIT_REQUIRE_SEMICOLONS` environment variable is now read. If
  set to `1` then semicolons are required during parsing.
* A new `SourceMap::set_require_semicolons` is provided to
  programmatically indicate what to do.

When semicolons are not required they are still parsed, but a failure is
not generated if they're not present. This should allow semicolon-using
WIT to coexist with non-semicolon-using WIT for a transitionary period.
After a release or two the default for requiring semicolons will
switch to `true` from the current `false`. That means that
`WIT_REQUIRE_SEMICOLONS=0` can be used to keep old WITs compiling. The
after a few releases of that support for optionally parsing semicolons
will be removed and they'll be unconditionally required.

* Update all in-repo tests to use semicolons

Additionally add environment-variable support to WIT printing to
optionally print semicolons, disabled for now.
  • Loading branch information
alexcrichton authored Sep 26, 2023
1 parent 113d753 commit 553ec51
Show file tree
Hide file tree
Showing 394 changed files with 1,273 additions and 1,194 deletions.
33 changes: 31 additions & 2 deletions crates/wit-component/src/printing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use std::fmt::{self, Write};
use std::mem;
use wit_parser::*;

// NB: keep in sync with `crates/wit-parser/src/ast/lex.rs`
const PRINT_SEMICOLONS_DEFAULT: bool = false;

/// A utility for printing WebAssembly interface definitions to a string.
pub struct WitPrinter {
output: Output,
Expand All @@ -14,6 +17,8 @@ pub struct WitPrinter {

// Whether to print doc comments.
emit_docs: bool,

print_semicolons: bool,
}

impl Default for WitPrinter {
Expand All @@ -22,6 +27,10 @@ impl Default for WitPrinter {
output: Default::default(),
any_items: false,
emit_docs: true,
print_semicolons: match std::env::var("WIT_REQUIRE_SEMICOLONS") {
Ok(s) => s == "1",
Err(_) => PRINT_SEMICOLONS_DEFAULT,
},
}
}
}
Expand Down Expand Up @@ -68,6 +77,12 @@ impl WitPrinter {
Ok(std::mem::take(&mut self.output).into())
}

fn print_semicolon(&mut self) {
if self.print_semicolons {
self.output.push_str(";");
}
}

fn new_item(&mut self) {
if self.any_items {
self.output.push_str("\n");
Expand Down Expand Up @@ -106,6 +121,7 @@ impl WitPrinter {
self.print_name(name);
self.output.push_str(": ");
self.print_function(resolve, func)?;
self.print_semicolon();
self.output.push_str("\n");
}

Expand Down Expand Up @@ -181,7 +197,9 @@ impl WitPrinter {
self.print_name(my_name);
}
}
writeln!(&mut self.output, "}}")?;
write!(&mut self.output, "}}")?;
self.print_semicolon();
self.output.push_str("\n");
}

for id in types_to_declare {
Expand All @@ -205,6 +223,7 @@ impl WitPrinter {
self.output.push_str("resource ");
self.print_name(ty.name.as_ref().expect("resources must be named"));
if funcs.is_empty() {
self.print_semicolon();
self.output.push_str("\n");
return Ok(());
}
Expand All @@ -228,6 +247,7 @@ impl WitPrinter {
FunctionKind::Freestanding => unreachable!(),
}
self.print_function(resolve, func)?;
self.print_semicolon();
self.output.push_str("\n");
}
self.output.push_str("}\n");
Expand Down Expand Up @@ -362,6 +382,7 @@ impl WitPrinter {
}
WorldItem::Function(f) => {
self.print_function(resolve, f)?;
self.print_semicolon();
self.output.push_str("\n");
}
// Types are handled separately
Expand All @@ -374,6 +395,7 @@ impl WitPrinter {
_ => unreachable!(),
}
self.print_path_to_interface(resolve, *id, cur_pkg)?;
self.print_semicolon();
self.output.push_str("\n");
}
}
Expand Down Expand Up @@ -616,6 +638,7 @@ impl WitPrinter {
self.print_name(name);
self.output.push_str(" = ");
self.print_type_name(resolve, inner)?;
self.print_semicolon();
self.output.push_str("\n");
}
None => bail!("unnamed type in document"),
Expand Down Expand Up @@ -646,6 +669,7 @@ impl WitPrinter {
// own<b>`. By forcing a handle to be printed here it's staying
// true to what's in the WIT document.
self.print_handle_type(resolve, handle, true)?;
self.print_semicolon();
self.output.push_str("\n");

Ok(())
Expand Down Expand Up @@ -690,6 +714,7 @@ impl WitPrinter {
self.print_name(name);
self.output.push_str(" = ");
self.print_tuple_type(resolve, tuple)?;
self.print_semicolon();
self.output.push_str("\n");
}
Ok(())
Expand Down Expand Up @@ -751,6 +776,7 @@ impl WitPrinter {
self.print_name(name);
self.output.push_str(" = ");
self.print_option_type(resolve, payload)?;
self.print_semicolon();
self.output.push_str("\n");
}
Ok(())
Expand All @@ -767,6 +793,7 @@ impl WitPrinter {
self.print_name(name);
self.output.push_str(" = ");
self.print_result_type(resolve, result)?;
self.print_semicolon();
self.output.push_str("\n");
}
Ok(())
Expand Down Expand Up @@ -795,7 +822,9 @@ impl WitPrinter {
self.print_name(name);
self.output.push_str(" = list<");
self.print_type_name(resolve, ty)?;
self.output.push_str(">\n");
self.output.push_str(">");
self.print_semicolon();
self.output.push_str("\n");
return Ok(());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
thunk-that-is-not-called: func()
thunk-that-is-not-called: func();
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
world adapt-old {
export entrypoint: func()
export entrypoint: func();
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
interface new {
entrypoint: func()
entrypoint: func();
}

world adapt-old {
export new
export new;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
world adapt-old {
import new: interface {
read: func(amt: u32) -> list<u8>
read: func(amt: u32) -> list<u8>;
}
export entrypoint: func(args: list<string>)
export entrypoint: func(args: list<string>);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
world adapt-old {
export entrypoint: func(nargs: u32)
export entrypoint: func(nargs: u32);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
interface new {
foo: func() -> string
foo: func() -> string;
}

world adapt-old {
export new
export new;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
interface adapter-imports {
foo: func(x: string)
foo: func(x: string);
}

world adapt-unused {
import adapter-imports
import adapter-imports;

export adapter-bar: func(x: string)
export adapter-bar: func(x: string);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package foo:foo

world module {
import foo: func(x: string)
export bar: func()
import foo: func(x: string);
export bar: func();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
get-two: func() -> (a: u32, b: u32)
get-two: func() -> (a: u32, b: u32);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
get-two: func() -> (a: u32, b: u32)
get-two: func() -> (a: u32, b: u32);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
get-two: func() -> (a: u32, b: u32)
get-two: func() -> (a: u32, b: u32);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
get-two: func() -> (a: u32, b: u32)
get-two: func() -> (a: u32, b: u32);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
get-two: func() -> (a: u32, b: u32)
get-two: func() -> (a: u32, b: u32);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
read: func() -> list<u8>
read: func() -> list<u8>;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
log: func(s: string)
log: func(s: string);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
world adapt-foo {
import other1: interface {
foo: func()
foo: func();
}
import other2: interface {
bar: func()
bar: func();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// to implement the `wasi_snapshot_preview1` interface.

interface my-wasi {
random-get: func(size: u32) -> list<u8>
proc-exit: func(code: u32)
something-not-used: func()
random-get: func(size: u32) -> list<u8>;
proc-exit: func(code: u32);
something-not-used: func();
}

world adapt-wasi-snapshot-preview1 {
import my-wasi
import my-wasi;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package foo:foo

world module {
import foo: interface {
foo: func()
foo: func();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
log: func(s: string)
log: func(s: string);
}
}
8 changes: 4 additions & 4 deletions crates/wit-component/tests/components/bare-funcs/module.wit
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package foo:foo
world module {
import foo: func()
import bar: func() -> string
export baz: func()
export foo2: func(x: string) -> option<list<u8>>
import foo: func();
import bar: func() -> string;
export baz: func();
export foo2: func(x: string) -> option<list<u8>>;
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package foo:foo

interface foo {
type foo = u8
type foo = u8;

record bar {
x: foo
}

a: func(b: bar)
a: func(b: bar);
}

world module {
import foo
import foo;

export a: func(b: u8)
export a: func(b: u8);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
world adapt-old {
import new: interface {
log: func(s: string)
log: func(s: string);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package foo:foo

world module {
export a: func(x: string) -> string
export a: func(x: string) -> string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package foo:foo

world module {
export foo: interface {
a: func(x: string) -> string
a: func(x: string) -> string;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package foo:bar

world module {
resource a
resource a;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package foo:bar

world module {
resource a
resource a;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package foo:foo

world module {
import foo: interface {
bar: func(s: string)
bar: func(s: string);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package test:test

interface test {
foo: func(v: s32) -> s32
foo: func(v: s32) -> s32;
}

world lib-foo {
import test
export test
import test;
export test;
}
Loading

0 comments on commit 553ec51

Please sign in to comment.