Skip to content

Commit

Permalink
Require a semicolon after augment decorator statements (#2343)
Browse files Browse the repository at this point in the history
This PR fixes #2059 by requiring that a semicolon appear after an
augment decorator statement. This is a breaking change but it should be
mitigated by the fact that the TypeSpec formatter already adds a
semicolon for all augment decorator statements.
  • Loading branch information
daviwil authored Sep 5, 2023
1 parent c42321c commit ae07658
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@typespec/compiler",
"comment": "**Breaking Change** A semicolon is now required after augment decorator statements.",
"type": "none"
}
],
"packageName": "@typespec/compiler"
}
2 changes: 1 addition & 1 deletion docs/language-basics/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ model Dog {}

## Augment decorators

Decorators can also be used from a different location by referring to the type being decorated. For this you can declare an augment decorator using the `@@` prefix. The first argument of an augment decorator is the type reference that should be decorated.
Decorators can also be used from a different location by referring to the type being decorated. For this you can declare an augment decorator using the `@@` prefix. The first argument of an augment decorator is the type reference that should be decorated. As the augment decorator is a statement, it must end with a semicolon (`;`).

```typespec
model Dog {}
Expand Down
2 changes: 1 addition & 1 deletion docs/language-basics/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ _Details: [Decorators](./decorators.md)_
| Use decorator with arguments | `@tag("abc")` |
| Declare a decorator in JS | `export function $tag(context: DecoratorContext, target: Type, name: string) {...}` |
| Save state in decorator | `context.program.stateMap(key).set(target, <value>)` |
| Augment decorator | `@@tag(MyType, "abc")` |
| Augment decorator | `@@tag(MyType, "abc");` |

## Scalars

Expand Down
3 changes: 3 additions & 0 deletions packages/compiler/src/core/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,9 @@ function createParser(code: string | SourceFile, options: ParseOptions = {}): Pa
...finishNode(pos),
};
}

parseExpected(Token.Semicolon);

return {
kind: SyntaxKind.AugmentDecoratorStatement,
target,
Expand Down
14 changes: 7 additions & 7 deletions packages/compiler/test/checker/augment-decorators.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ describe("compiler: checker: augment decorators", () => {

it("namespace", () => expectTarget(`@test("target") namespace Foo {}`, "Foo"));

it("global namespace", () => expectTarget(`@@test(global, "target")`, "global"));
it("global namespace", () => expectTarget(`@@test(global, "target");`, "global"));

it("model", () => expectTarget(`@test("target") model Foo {}`, "Foo"));
it("model property", () =>
Expand Down Expand Up @@ -288,7 +288,7 @@ describe("compiler: checker: augment decorators", () => {
}
namespace MyService {
@@customName(Lib.Foo, "FooCustom")
@@customName(Lib.Foo, "FooCustom");
}
`);
});
Expand All @@ -298,12 +298,12 @@ describe("compiler: checker: augment decorators", () => {

await expectAugmentTarget(`
import "./lib.tsp";
@@customName(Foo, "FooCustom")
@@customName(Foo, "FooCustom");
`);
});

it("augment type in another file checked after", async () => {
testHost.addTypeSpecFile("lib.tsp", `@@customName(Foo, "FooCustom") `);
testHost.addTypeSpecFile("lib.tsp", `@@customName(Foo, "FooCustom"); `);

await expectAugmentTarget(`
import "./lib.tsp";
Expand Down Expand Up @@ -345,7 +345,7 @@ describe("compiler: checker: augment decorators", () => {
@test("target")
@customName("Foo")
model Foo {}
@@customName(Foo, "FooCustom")
@@customName(Foo, "FooCustom");
`);
});

Expand All @@ -354,8 +354,8 @@ describe("compiler: checker: augment decorators", () => {
@test("target")
@customName("Foo")
model Foo {}
@@customName(Foo, "NonCustom")
@@customName(Foo, "FooCustom")
@@customName(Foo, "NonCustom");
@@customName(Foo, "FooCustom");
`);
});
});
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/test/checker/enum.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ describe("compiler: enums", () => {
@test enum Base {@doc("base doc") one}
@test enum Spread {...Base}
@@doc(Spread.one, "override for spread")
@@doc(Spread.one, "override for spread");
`
);
const { Base, Spread } = (await testHost.compile("main.tsp")) as {
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/test/checker/interface.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ describe("compiler: interfaces", () => {
`
@test interface Base {@doc("base doc") one(): void}
@test interface Extending extends Base {}
@@doc(Extending.one, "override for spread")
@@doc(Extending.one, "override for spread");
`
);
const { Base, Extending } = (await testHost.compile("main.tsp")) as {
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/test/checker/model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ describe("compiler: models", () => {
@test model Base {@doc("base doc") one: string}
@test model Spread {...Base}
@@doc(Spread.one, "override for spread")
@@doc(Spread.one, "override for spread");
`
);
const { Base, Spread } = (await testHost.compile("main.tsp")) as {
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler/test/checker/operations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe("compiler: operations", () => {
@test op a(@doc("base doc") one: string): void;
@test op b is a;
@@doc(b::parameters.one, "override for b")
@@doc(b::parameters.one, "override for b");
`
);
const { a, b } = (await testHost.compile("main.tsp")) as { a: Operation; b: Operation };
Expand All @@ -80,7 +80,7 @@ describe("compiler: operations", () => {
@test op b is a<string>;
@test op c is a<string>;
@@doc(b::parameters.one, "override for b")
@@doc(b::parameters.one, "override for b");
`
);
const { b, c } = (await testHost.compile("main.tsp")) as { b: Operation; c: Operation };
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler/test/decorator-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ describe("compiler: decorator utils", () => {
@bar
model Foo {}
@@bar(Foo)
@@bar(Foo);
`);

expectDiagnosticEmpty(diagnostics);
Expand Down Expand Up @@ -293,7 +293,7 @@ describe("compiler: decorator utils", () => {
@red
model Foo {}
@@blue(Foo)
@@blue(Foo);
`);

expectDiagnostics(diagnostics, [
Expand Down

0 comments on commit ae07658

Please sign in to comment.