Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions tools/apiview/emitters/typespec-apiview/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release History

## Version 0.4.9 (06-26-2024)
Fix issue where "unknown" was rendered as "any".
Support value syntax for objects and arrays.

## Version 0.4.8 (04-18-2024)
Display suppressions in APIView.
Resolve visual anomalies.
Expand Down
2,834 changes: 1,283 additions & 1,551 deletions tools/apiview/emitters/typespec-apiview/package-lock.json

Large diffs are not rendered by default.

37 changes: 18 additions & 19 deletions tools/apiview/emitters/typespec-apiview/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure-tools/typespec-apiview",
"version": "0.4.8",
"version": "0.4.9",
"author": "Microsoft Corporation",
"description": "Library for emitting APIView token files from TypeSpec",
"homepage": "https://github.com/Azure/azure-sdk-tools",
Expand Down Expand Up @@ -54,27 +54,26 @@
"!dist/test/**"
],
"peerDependencies": {
"@typespec/compiler": ">=0.52 <1.0",
"@typespec/versioning": ">=0.52 <1.0"
"@typespec/compiler": ">=0.57 <1.0",
"@typespec/versioning": ">=0.57 <1.0"
},
"devDependencies": {
"@azure-tools/typespec-azure-core": ">=0.29 <1.0",
"@typespec/http": ">=0.52 <1.0",
"@typespec/rest": ">=0.52 <1.0",
"@typespec/eslint-plugin": ">=0.40 <1.0",
"@typespec/library-linter": ">=0.40 <1.0",
"@typespec/prettier-plugin-typespec": ">=0.40 <1.0",
"@typespec/eslint-config-typespec": ">=0.6 <1.0",
"@azure-tools/typespec-azure-core": ">=0.43 <1.0",
"@typespec/http": ">=0.57 <1.0",
"@typespec/rest": ">=0.57 <1.0",
"@typespec/eslint-plugin": ">=0.57 <1.0",
"@typespec/library-linter": ">=0.57 <1.0",
"@typespec/prettier-plugin-typespec": ">=0.57 <1.0",
"@types/mocha": "~9.1.0",
"@types/node": "~16.0.3",
"c8": "~7.11.0",
"cspell": "^6.8.1",
"eslint": "^8.23.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-unicorn": "^43.0.2",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"typescript": "^5.0.0",
"@types/node": "~18.11.19",
"c8": "^9.1.0",
"cspell": "^8.8.1",
"eslint": "^8.57.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-unicorn": "^53.0.0",
"prettier": "~3.2.5",
"rimraf": "~5.0.7",
"typescript": "~5.4.5",
"mocha": "~9.2.0",
"mocha-junit-reporter": "~2.0.2",
"mocha-multi-reporters": "~1.5.1",
Expand Down
44 changes: 41 additions & 3 deletions tools/apiview/emitters/typespec-apiview/src/apiview.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AliasStatementNode,
ArrayExpressionNode,
ArrayLiteralNode,
AugmentDecoratorStatementNode,
BaseNode,
BooleanLiteralNode,
Expand All @@ -23,6 +24,9 @@ import {
Namespace,
navigateProgram,
NumericLiteralNode,
ObjectLiteralNode,
ObjectLiteralPropertyNode,
ObjectLiteralSpreadPropertyNode,
OperationSignatureDeclarationNode,
OperationSignatureReferenceNode,
OperationStatementNode,
Expand Down Expand Up @@ -379,6 +383,7 @@ export class ApiView {

tokenize(node: BaseNode) {
let obj;
let last = 0; // track the final index of an array
let isExpanded = false;
switch (node.kind) {
case SyntaxKind.AliasStatement:
Expand All @@ -396,6 +401,18 @@ export class ApiView {
this.tokenize(obj.elementType);
this.punctuation("[]");
break;
case SyntaxKind.ArrayLiteral:
obj = node as ArrayLiteralNode;
this.punctuation("#[");
last = obj.values.length - 1;
obj.values.forEach((val, i) => {
this.tokenize(val);
if (i !== last) {
this.punctuation(",", false, true);
}
});
this.punctuation("]");
break;
case SyntaxKind.AugmentDecoratorStatement:
obj = node as AugmentDecoratorStatementNode;
const decoratorName = this.getNameForNode(obj.target);
Expand Down Expand Up @@ -435,7 +452,7 @@ export class ApiView {
this.tokenizeIdentifier(obj.target, "keyword");
this.lineMarker();
if (obj.arguments.length) {
const last = obj.arguments.length - 1;
last = obj.arguments.length - 1;
this.punctuation("(", false, false);
for (let x = 0; x < obj.arguments.length; x++) {
const arg = obj.arguments[x];
Expand Down Expand Up @@ -544,6 +561,28 @@ export class ApiView {
obj = node as NumericLiteralNode;
this.literal(obj.value.toString());
break;
case SyntaxKind.ObjectLiteral:
obj = node as ObjectLiteralNode;
this.punctuation("#{", true, false);
last = obj.properties.length - 1;
obj.properties.forEach((prop, i) => {
this.tokenize(prop);
if (i !== last) {
this.punctuation(",", false, true);
}
});
this.punctuation("}", false, false);
break;
case SyntaxKind.ObjectLiteralProperty:
obj = node as ObjectLiteralPropertyNode;
this.tokenizeIdentifier(obj.id, "member");
this.punctuation(":", false, true);
this.tokenize(obj.value);
break;
case SyntaxKind.ObjectLiteralSpreadProperty:
obj = node as ObjectLiteralSpreadPropertyNode;
// TODO: Whenever there is an example?
throw new Error(`Case "ObjectLiteralSpreadProperty" not implemented`);
case SyntaxKind.OperationStatement:
this.tokenizeOperationStatement(node as OperationStatementNode);
break;
Expand Down Expand Up @@ -641,7 +680,7 @@ export class ApiView {
this.tokenizeUnionVariant(node as UnionVariantNode);
break;
case SyntaxKind.UnknownKeyword:
this.keyword("any", true, true);
this.keyword("unknown", true, true);
break;
case SyntaxKind.UsingStatement:
throw new Error(`Case "UsingStatement" not implemented`);
Expand Down Expand Up @@ -741,7 +780,6 @@ export class ApiView {
case SyntaxKind.MemberExpression:
return this.getFullyQualifiedIdentifier(obj.target as MemberExpressionNode);
}
break;
default:
throw new Error(`Unsupported expression kind: ${SyntaxKind[node.kind]}`);
//unsupported ArrayExpressionNode | MemberExpressionNode | ModelExpressionNode | TupleExpressionNode | UnionExpressionNode | IntersectionExpressionNode | TypeReferenceNode | ValueOfExpressionNode | AnyKeywordNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
Directive,
DirectiveExpressionNode,
StringLiteralNode,
ObjectLiteralNode,
} from "@typespec/compiler";

export class NamespaceModel {
Expand All @@ -49,6 +50,7 @@ export class NamespaceModel {
| ScalarStatementNode
| UnionStatementNode
| UnionExpressionNode
| ObjectLiteralNode
>();
models = new Map<
string,
Expand All @@ -60,6 +62,7 @@ export class NamespaceModel {
| ScalarStatementNode
| UnionStatementNode
| UnionExpressionNode
| ObjectLiteralNode
>();
aliases = new Map<string, AliasStatementNode>();
augmentDecorators = new Array<AugmentDecoratorStatementNode>();
Expand Down Expand Up @@ -188,7 +191,6 @@ export function generateId(obj: BaseNode | NamespaceModel | undefined): string |
case SyntaxKind.MemberExpression:
return generateId(node.target);
}
break;
case SyntaxKind.EnumMember:
node = obj as EnumMemberNode;
name = node.id.sv;
Expand Down
4 changes: 3 additions & 1 deletion tools/apiview/emitters/typespec-apiview/src/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
IntersectionExpressionNode,
ModelExpressionNode,
ModelStatementNode,
ObjectLiteralNode,
OperationStatementNode,
ProjectionModelExpressionNode,
ScalarStatementNode,
Expand Down Expand Up @@ -34,7 +35,8 @@ export class ApiViewNavigation {
| ProjectionModelExpressionNode
| ScalarStatementNode
| UnionStatementNode
| UnionExpressionNode,
| UnionExpressionNode
| ObjectLiteralNode,
stack: NamespaceStack
) {
let obj;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe("apiview-options: tests", () => {
`
const apiview = await apiViewFor(input, {});
const actual = apiViewText(apiview);
compare(expect, actual, 9);
compare(expect, actual, 10);
});

it("outputs the global namespace when --include-global-namespace is set", async () => {
Expand All @@ -48,6 +48,7 @@ describe("apiview-options: tests", () => {
model SomeGlobal {}
}

#suppress "deprecated"
@TypeSpec.service(
{
title: "Test";
Expand All @@ -63,7 +64,7 @@ describe("apiview-options: tests", () => {
});
// TODO: Update once bug is fixed: https://github.com/microsoft/typespec/issues/3165
const actual = apiViewText(apiview);
compare(expect, actual, 1);
compare(expect, actual, 3);
});

it("emits error if multi-service package tries to specify version", async () => {
Expand Down Expand Up @@ -116,6 +117,6 @@ describe("apiview-options: tests", () => {
`;
const apiview = await apiViewFor(input, {"version": "1", "service": "OtherTest"});
const actual = apiViewText(apiview);
compare(expect, actual, 9);
compare(expect, actual, 10);
});
});
Loading