From 45f83aef11e61d86985ae3efcfa67ab198c0e411 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 29 Jan 2021 10:17:13 -0800 Subject: [PATCH 1/4] Handle circular dependency in additionalProperties --- .../modelerfour/src/modeler/modelerfour.ts | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/extensions/modelerfour/src/modeler/modelerfour.ts b/packages/extensions/modelerfour/src/modeler/modelerfour.ts index da9d95f65c..9b8321d1f5 100644 --- a/packages/extensions/modelerfour/src/modeler/modelerfour.ts +++ b/packages/extensions/modelerfour/src/modeler/modelerfour.ts @@ -712,6 +712,14 @@ export class ModelerFour { throw new Error("Method not implemented."); } processDictionarySchema(name: string, schema: OpenAPI.Schema): DictionarySchema { + const dictSchema = new DictionarySchema( + this.interpret.getName(name, schema), + this.interpret.getDescription("", schema), + null, + ); + // cache this now before we accidentally recurse on this type. + this.schemaCache.set(schema, dictSchema); + let elementSchema: Schema; let elementNullable: boolean | undefined; if (schema.additionalProperties === true) { @@ -727,16 +735,14 @@ export class ModelerFour { } } - return this.codeModel.schemas.add( - new DictionarySchema( - this.interpret.getName(name, schema), - this.interpret.getDescription(`Dictionary of <${elementSchema.language.default.name}>`, schema), - elementSchema, - { - nullableItems: elementNullable, - }, - ), + dictSchema.language.default.description = this.interpret.getDescription( + `Dictionary of <${elementSchema.language.default.name}>`, + schema, ); + dictSchema.elementType = elementSchema; + dictSchema.nullableItems = elementNullable; + + return this.codeModel.schemas.add(dictSchema); } isSchemaPolymorphic(schema: OpenAPI.Schema | undefined): boolean { @@ -779,6 +785,8 @@ export class ModelerFour { for (const { key: propertyName, value: propertyDeclaration } of items(schema.properties)) { const property = this.resolve(propertyDeclaration); this.use(>propertyDeclaration, (pSchemaName, pSchema) => { + console.error("process chema", pSchema); + const pType = this.processSchema(pSchemaName || `type·for·${propertyName}`, pSchema); const prop = objectSchema.addProperty( new Property( @@ -967,6 +975,7 @@ export class ModelerFour { trap = new Set(); processSchemaImpl(schema: OpenAPI.Schema, name: string): Schema { + console.error("Here", schema); if (this.trap.has(schema)) { throw new Error( `RECURSING! Saw schema ${schema.title || schema["x-ms-metadata"]?.name || name} more than once.`, From 75d2734d7d9382802827d80e56b8946f14f4bfc8 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 29 Jan 2021 10:25:06 -0800 Subject: [PATCH 2/4] Include change --- ...dditional-props-circular-dep_2021-01-29-18-24.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@autorest/modelerfour/fix-additional-props-circular-dep_2021-01-29-18-24.json diff --git a/common/changes/@autorest/modelerfour/fix-additional-props-circular-dep_2021-01-29-18-24.json b/common/changes/@autorest/modelerfour/fix-additional-props-circular-dep_2021-01-29-18-24.json new file mode 100644 index 0000000000..d374d7081e --- /dev/null +++ b/common/changes/@autorest/modelerfour/fix-additional-props-circular-dep_2021-01-29-18-24.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@autorest/modelerfour", + "comment": "Fix haivng circular dependencies in additionalProperties [PR #3819](https://github.com/Azure/autorest/pull/3819)", + "type": "patch" + } + ], + "packageName": "@autorest/modelerfour", + "email": "tiguerin@microsoft.com" +} \ No newline at end of file From 83a450a694d7403c1a3dbb3f609962d180fb5296 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 29 Jan 2021 13:40:38 -0800 Subject: [PATCH 3/4] Fix comments --- .../fix-additional-props-circular-dep_2021-01-29-18-24.json | 4 ++-- packages/extensions/modelerfour/src/modeler/modelerfour.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/common/changes/@autorest/modelerfour/fix-additional-props-circular-dep_2021-01-29-18-24.json b/common/changes/@autorest/modelerfour/fix-additional-props-circular-dep_2021-01-29-18-24.json index d374d7081e..86c3e5d119 100644 --- a/common/changes/@autorest/modelerfour/fix-additional-props-circular-dep_2021-01-29-18-24.json +++ b/common/changes/@autorest/modelerfour/fix-additional-props-circular-dep_2021-01-29-18-24.json @@ -2,10 +2,10 @@ "changes": [ { "packageName": "@autorest/modelerfour", - "comment": "Fix haivng circular dependencies in additionalProperties [PR #3819](https://github.com/Azure/autorest/pull/3819)", + "comment": "Fix the use of circular dependencies in additionalProperties [PR #3819](https://github.com/Azure/autorest/pull/3819)", "type": "patch" } ], "packageName": "@autorest/modelerfour", "email": "tiguerin@microsoft.com" -} \ No newline at end of file +} diff --git a/packages/extensions/modelerfour/src/modeler/modelerfour.ts b/packages/extensions/modelerfour/src/modeler/modelerfour.ts index 9b8321d1f5..90c943a86c 100644 --- a/packages/extensions/modelerfour/src/modeler/modelerfour.ts +++ b/packages/extensions/modelerfour/src/modeler/modelerfour.ts @@ -785,7 +785,6 @@ export class ModelerFour { for (const { key: propertyName, value: propertyDeclaration } of items(schema.properties)) { const property = this.resolve(propertyDeclaration); this.use(>propertyDeclaration, (pSchemaName, pSchema) => { - console.error("process chema", pSchema); const pType = this.processSchema(pSchemaName || `type·for·${propertyName}`, pSchema); const prop = objectSchema.addProperty( From ec1bcd761b76e577683e74811f7dcd702fad70b4 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 29 Jan 2021 13:49:50 -0800 Subject: [PATCH 4/4] Add tests --- .../modelerfour/src/modeler/modelerfour.ts | 1 - .../test/modeler/modelerfour.schemas.test.ts | 23 +++++++++++++++++++ .../test/modeler/modelerfour.test.ts | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 packages/extensions/modelerfour/test/modeler/modelerfour.schemas.test.ts diff --git a/packages/extensions/modelerfour/src/modeler/modelerfour.ts b/packages/extensions/modelerfour/src/modeler/modelerfour.ts index 90c943a86c..ebf9e38193 100644 --- a/packages/extensions/modelerfour/src/modeler/modelerfour.ts +++ b/packages/extensions/modelerfour/src/modeler/modelerfour.ts @@ -974,7 +974,6 @@ export class ModelerFour { trap = new Set(); processSchemaImpl(schema: OpenAPI.Schema, name: string): Schema { - console.error("Here", schema); if (this.trap.has(schema)) { throw new Error( `RECURSING! Saw schema ${schema.title || schema["x-ms-metadata"]?.name || name} more than once.`, diff --git a/packages/extensions/modelerfour/test/modeler/modelerfour.schemas.test.ts b/packages/extensions/modelerfour/test/modeler/modelerfour.schemas.test.ts new file mode 100644 index 0000000000..95d696f22c --- /dev/null +++ b/packages/extensions/modelerfour/test/modeler/modelerfour.schemas.test.ts @@ -0,0 +1,23 @@ +import { addOperation, addSchema, createTestSpec } from "../utils"; +import { runModeler } from "./modelerfour-utils"; + +describe("Modelerfour.Schemas", () => { + describe("additionalProperties", () => { + it("support reference to itself(circular dependency", async () => { + const spec = createTestSpec(); + + addSchema(spec, "SelfRefSchema", { + additionalProperties: { + $ref: "#/components/schemas/SelfRefSchema", + }, + }); + + const codeModel = await runModeler(spec); + + const schema = codeModel.schemas.dictionaries?.[0]; + expect(schema).not.toBeNull(); + expect(schema?.language.default.name).toEqual("SelfRefSchema"); + expect(schema?.elementType).toEqual(schema); + }); + }); +}); diff --git a/packages/extensions/modelerfour/test/modeler/modelerfour.test.ts b/packages/extensions/modelerfour/test/modeler/modelerfour.test.ts index 5ef1e0fdb0..4815a70f61 100644 --- a/packages/extensions/modelerfour/test/modeler/modelerfour.test.ts +++ b/packages/extensions/modelerfour/test/modeler/modelerfour.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information.