Skip to content

Commit

Permalink
Preserve leading whitespace in fenced blocks in doc comments (#3399)
Browse files Browse the repository at this point in the history
Fixes #3370.

This also updates the generated documentation and typescript code to fix
lack of indentation on existing fenced blocks in this repo.

---------

Co-authored-by: Timothee Guerin <timothee.guerin@outlook.com>
  • Loading branch information
Veetaha and timotheeguerin authored May 20, 2024
1 parent e316792 commit d14b0d7
Show file tree
Hide file tree
Showing 19 changed files with 251 additions and 163 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: internal
packages:
- "@typespec/http"
- "@typespec/protobuf"
- "@typespec/rest"
- "@typespec/versioning"
- "@typespec/xml"
---

Regen docs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/compiler"
---

Preserve leading whitespace in fenced blocks in doc comments
4 changes: 2 additions & 2 deletions docs/libraries/http/reference/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,8 @@ namespace PetStore;

```typespec
@server("https://{region}.foo.com", "Regional endpoint", {
@doc("Region name")
region?: string = "westus",
@doc("Region name")
region?: string = "westus",
})
```

Expand Down
32 changes: 16 additions & 16 deletions docs/libraries/xml/reference/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ model Blob {

```xml
<Blob>
<id>abcdef</id>
<id>abcdef</id>
</Blob>
```

Expand Down Expand Up @@ -85,9 +85,9 @@ model Book {

```xml
<XmlBook>
<XmlId>string</XmlId>
<XmlName>string</XmlName>
<content>string</content>
<XmlId>string</XmlId>
<XmlName>string</XmlName>
<content>string</content>
</XmlBook>
```

Expand Down Expand Up @@ -192,11 +192,11 @@ model Pet {

```xml
<XmlPet>
<ItemsTags>
<XmlTag>
<name>string</name>
</XmlTag>
</ItemsTags>
<ItemsTags>
<XmlTag>
<name>string</name>
</XmlTag>
</ItemsTags>
</XmlPet>
```

Expand All @@ -210,9 +210,9 @@ model Pet {

```xml
<XmlPet>
<XmlTag>
<name>string</name>
</XmlTag>
<XmlTag>
<name>string</name>
</XmlTag>
</XmlPet>
```

Expand All @@ -226,9 +226,9 @@ model BlobName {

```xml
<BlobName>
<content>
abcdef
</content>
<content>
abcdef
</content>
</BlobName>
```

Expand All @@ -242,6 +242,6 @@ model BlobName {

```xml
<BlobName>
abcdef
abcdef
</BlobName>
```
48 changes: 24 additions & 24 deletions docs/standard-library/built-in-decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ Provide an alternative name for this type when serialized to the given mime type

```typespec
model Certificate {
@encodedName("application/json", "exp")
@encodedName("application/xml", "expiry")
expireAt: int32;
@encodedName("application/json", "exp")
@encodedName("application/xml", "expiry")
expireAt: int32;
}
```

Expand All @@ -160,7 +160,7 @@ expireAt: int32;

```typespec
@encodedName("application/merge-patch+json", "exp")
^ error cannot use subtype
^ error cannot use subtype
```


Expand All @@ -183,8 +183,8 @@ None
```typespec
@error
model PetStoreError {
code: string;
message: string;
code: string;
message: string;
}
```

Expand Down Expand Up @@ -262,8 +262,8 @@ Specifies how a templated type should name their instances.
```typespec
@friendlyName("{name}List", T)
model List<Item> {
value: Item[];
nextLink: string;
value: Item[];
nextLink: string;
}
```

Expand Down Expand Up @@ -324,7 +324,7 @@ Mark a model property as the key to identify instances of that type

```typespec
model Pet {
@key id: string;
@key id: string;
}
```

Expand Down Expand Up @@ -352,8 +352,8 @@ Provide a set of known values to a string type.
scalar ErrorCode extends string;
enum KnownErrorCode {
NotFound,
Invalid,
NotFound,
Invalid,
}
```

Expand Down Expand Up @@ -670,8 +670,8 @@ Provide an alternative name for this type.

```typespec
model Certificate {
@projectedName("json", "exp")
expireAt: int32;
@projectedName("json", "exp")
expireAt: int32;
}
```

Expand Down Expand Up @@ -855,12 +855,12 @@ See also: [Automatic visibility](https://typespec.io/docs/libraries/http/operati

```typespec
model Dog {
// the service will generate an ID, so you don't need to send it.
@visibility("read") id: int32;
// the service will store this secret name, but won't ever return it
@visibility("create", "update") secretName: string;
// the regular name is always present
name: string;
// the service will generate an ID, so you don't need to send it.
@visibility("read") id: int32;
// the service will store this secret name, but won't ever return it
@visibility("create", "update") secretName: string;
// the regular name is always present
name: string;
}
```

Expand Down Expand Up @@ -977,9 +977,9 @@ not necessary to use this decorator.

```typespec
model Dog {
@visibility("read") id: int32;
@visibility("create", "update") secretName: string;
name: string;
@visibility("read") id: int32;
@visibility("create", "update") secretName: string;
name: string;
}
// The spread operator will copy all the properties of Dog into DogRead,
Expand All @@ -990,14 +990,14 @@ name: string;
// properties are kept.
@withVisibility("create", "update")
model DogCreateOrUpdate {
...Dog;
...Dog;
}
// In this case the id and name properties are kept and the secretName property
// is removed.
@withVisibility("read")
model DogRead {
...Dog;
...Dog;
}
```

48 changes: 24 additions & 24 deletions packages/compiler/generated-defs/TypeSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ export type ServiceDecorator = (
* ```typespec
* @error
* model PetStoreError {
* code: string;
* message: string;
* code: string;
* message: string;
* }
* ```
*/
Expand Down Expand Up @@ -415,8 +415,8 @@ export type TagDecorator = (
* ```typespec
* @friendlyName("{name}List", T)
* model List<Item> {
* value: Item[];
* nextLink: string;
* value: Item[];
* nextLink: string;
* }
* ```
*/
Expand All @@ -437,8 +437,8 @@ export type FriendlyNameDecorator = (
* scalar ErrorCode extends string;
*
* enum KnownErrorCode {
* NotFound,
* Invalid,
* NotFound,
* Invalid,
* }
* ```
*/
Expand All @@ -455,7 +455,7 @@ export type KnownValuesDecorator = (
* @example
* ```typespec
* model Pet {
* @key id: string;
* @key id: string;
* }
* ```
*/
Expand Down Expand Up @@ -494,8 +494,8 @@ export type OverloadDecorator = (
* @example
* ```typespec
* model Certificate {
* @projectedName("json", "exp")
* expireAt: int32;
* @projectedName("json", "exp")
* expireAt: int32;
* }
* ```
*/
Expand All @@ -514,16 +514,16 @@ export type ProjectedNameDecorator = (
* @example
* ```typespec
* model Certificate {
* @encodedName("application/json", "exp")
* @encodedName("application/xml", "expiry")
* expireAt: int32;
* @encodedName("application/json", "exp")
* @encodedName("application/xml", "expiry")
* expireAt: int32;
* }
* ```
* @example Invalid values
*
* ```typespec
* @encodedName("application/merge-patch+json", "exp")
* ^ error cannot use subtype
* ^ error cannot use subtype
* ```
*/
export type EncodedNameDecorator = (
Expand Down Expand Up @@ -581,12 +581,12 @@ export type DiscriminatorDecorator = (
* @example
* ```typespec
* model Dog {
* // the service will generate an ID, so you don't need to send it.
* @visibility("read") id: int32;
* // the service will store this secret name, but won't ever return it
* @visibility("create", "update") secretName: string;
* // the regular name is always present
* name: string;
* // the service will generate an ID, so you don't need to send it.
* @visibility("read") id: int32;
* // the service will store this secret name, but won't ever return it
* @visibility("create", "update") secretName: string;
* // the regular name is always present
* name: string;
* }
* ```
*/
Expand All @@ -611,9 +611,9 @@ export type VisibilityDecorator = (
* @example
* ```typespec
* model Dog {
* @visibility("read") id: int32;
* @visibility("create", "update") secretName: string;
* name: string;
* @visibility("read") id: int32;
* @visibility("create", "update") secretName: string;
* name: string;
* }
*
* // The spread operator will copy all the properties of Dog into DogRead,
Expand All @@ -624,14 +624,14 @@ export type VisibilityDecorator = (
* // properties are kept.
* @withVisibility("create", "update")
* model DogCreateOrUpdate {
* ...Dog;
* ...Dog;
* }
*
* // In this case the id and name properties are kept and the secretName property
* // is removed.
* @withVisibility("read")
* model DogRead {
* ...Dog;
* ...Dog;
* }
* ```
*/
Expand Down
23 changes: 22 additions & 1 deletion packages/compiler/src/core/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2815,11 +2815,32 @@ function createParser(code: string | SourceFile, options: ParseOptions = {}): Pa
nextToken();
start = tokenPos();
while (parseOptional(Token.Whitespace));
if (parseOptional(Token.Star)) {
if (!parseOptional(Token.Star)) {
break;
}
if (!inCodeFence) {
parseOptional(Token.Whitespace);
start = tokenPos();
break;
}
// If we are in a code fence we want to preserve the leading whitespace
// except for the first space after the star which is used as indentation.
const whitespaceStart = tokenPos();
parseOptional(Token.Whitespace);

// This `min` handles the case when there is no whitespace after the
// star e.g. a case like this:
//
// /**
// *```
// *foo-bar
// *```
// */
//
// Not having space after the star isn't idiomatic, but we support this.
// `whitespaceStart + 1` strips the first space before `foo-bar` if there
// is a space after the star (the idiomatic case).
start = Math.min(whitespaceStart + 1, tokenPos());
break;
case Token.EndOfFile:
break loop;
Expand Down
Loading

0 comments on commit d14b0d7

Please sign in to comment.