diff --git a/packages/http-client-csharp/emitter/src/lib/client-model-builder.ts b/packages/http-client-csharp/emitter/src/lib/client-model-builder.ts index ad73391168..4ec1552574 100644 --- a/packages/http-client-csharp/emitter/src/lib/client-model-builder.ts +++ b/packages/http-client-csharp/emitter/src/lib/client-model-builder.ts @@ -8,6 +8,7 @@ import { SdkEndpointType, SdkHttpOperation, SdkServiceMethod, + SdkType, UsageFlags, getAllModels, } from "@azure-tools/typespec-client-generator-core"; @@ -19,6 +20,7 @@ import { InputOperationParameterKind } from "../type/input-operation-parameter-k import { InputParameter } from "../type/input-parameter.js"; import { InputEnumType, InputModelType, InputType } from "../type/input-type.js"; import { RequestLocation } from "../type/request-location.js"; +import { SdkTypeMap } from "../type/sdk-type-map.js"; import { fromSdkType } from "./converter.js"; import { Logger } from "./logger.js"; import { navigateModels } from "./model.js"; @@ -31,10 +33,13 @@ export function createModel(sdkContext: SdkContext): CodeMode const sdkPackage = sdkContext.sdkPackage; - const modelMap = new Map(); - const enumMap = new Map(); + const sdkTypeMap: SdkTypeMap = { + types: new Map(), + models: new Map(), + enums: new Map(), + }; - navigateModels(sdkContext, modelMap, enumMap); + navigateModels(sdkContext, sdkTypeMap); const sdkApiVersionEnums = sdkPackage.enums.filter((e) => e.usage === UsageFlags.ApiVersionEnum); @@ -50,14 +55,14 @@ export function createModel(sdkContext: SdkContext): CodeMode [] ); - const clientModel = { + const clientModel: CodeModel = { Name: sdkPackage.rootNamespace, ApiVersions: rootApiVersions, - Enums: Array.from(enumMap.values()), - Models: Array.from(modelMap.values()), + Enums: Array.from(sdkTypeMap.enums.values()), + Models: Array.from(sdkTypeMap.models.values()), Clients: inputClients, Auth: processServiceAuthentication(sdkPackage), - } as CodeModel; + }; return clientModel; function fromSdkClients( @@ -95,8 +100,7 @@ export function createModel(sdkContext: SdkContext): CodeMode clientParameters, rootApiVersions, sdkContext, - modelMap, - enumMap + sdkTypeMap ) ), Protocol: {}, @@ -155,7 +159,7 @@ export function createModel(sdkContext: SdkContext): CodeMode Name: "url", CrossLanguageDefinitionId: "TypeSpec.url", } - : fromSdkType(parameter.type, sdkContext, modelMap, enumMap); // TODO: consolidate with converter.fromSdkEndpointType + : fromSdkType(parameter.type, sdkContext, sdkTypeMap); // TODO: consolidate with converter.fromSdkEndpointType parameters.push({ Name: parameter.name, NameInRequest: parameter.serializedName, diff --git a/packages/http-client-csharp/emitter/src/lib/converter.ts b/packages/http-client-csharp/emitter/src/lib/converter.ts index a27971f9ac..140092a38a 100644 --- a/packages/http-client-csharp/emitter/src/lib/converter.ts +++ b/packages/http-client-csharp/emitter/src/lib/converter.ts @@ -31,56 +31,86 @@ import { InputEnumType, InputLiteralType, InputModelType, - InputNullableType, InputPrimitiveType, InputType, InputUnionType, } from "../type/input-type.js"; import { LiteralTypeContext } from "../type/literal-type-context.js"; +import { SdkTypeMap } from "../type/sdk-type-map.js"; export function fromSdkType( sdkType: SdkType, context: SdkContext, - models: Map, - enums: Map, + typeMap: SdkTypeMap, literalTypeContext?: LiteralTypeContext ): InputType { - if (sdkType.kind === "nullable") { - const inputType = fromSdkType(sdkType.type, context, models, enums); - return { - Kind: "nullable", - Type: inputType, - } as InputNullableType; + if (typeMap.types.has(sdkType)) { + return typeMap.types.get(sdkType)!; } - if (sdkType.kind === "model") return fromSdkModelType(sdkType, context, models, enums); - if (sdkType.kind === "endpoint") return fromSdkEndpointType(); - if (sdkType.kind === "enum") return fromSdkEnumType(sdkType, context, enums); - if (sdkType.kind === "enumvalue") - return fromSdkEnumValueTypeToConstantType(sdkType, context, enums, literalTypeContext); - if (sdkType.kind === "dict") return fromSdkDictionaryType(sdkType, context, models, enums); - if (sdkType.kind === "array") return fromSdkArrayType(sdkType, context, models, enums); - if (sdkType.kind === "constant") - return fromSdkConstantType(sdkType, context, models, enums, literalTypeContext); - if (sdkType.kind === "union") return fromUnionType(sdkType, context, models, enums); - if (sdkType.kind === "utcDateTime" || sdkType.kind === "offsetDateTime") - return fromSdkDateTimeType(sdkType); - if (sdkType.kind === "duration") return fromSdkDurationType(sdkType); - if (sdkType.kind === "tuple") return fromTupleType(sdkType); - // TODO -- endpoint and credential are handled separately in emitter, since we have specific locations for them in input model. - // We can handle unify the way we handle them in the future, probably by chaning the input model schema and do the conversion in generator. - if (sdkType.kind === "credential") throw new Error("Credential type is not supported yet."); - - return fromSdkBuiltInType(sdkType); + + let retVar: InputType; + switch (sdkType.kind) { + case "nullable": + const inputType = fromSdkType(sdkType.type, context, typeMap); + retVar = { + Kind: "nullable", + Type: inputType, + }; + break; + case "model": + retVar = fromSdkModelType(sdkType, context, typeMap); + break; + case "enum": + retVar = fromSdkEnumType(sdkType, context, typeMap); + break; + case "enumvalue": + retVar = fromSdkEnumValueTypeToConstantType(sdkType, context, typeMap, literalTypeContext); + break; + case "dict": + retVar = fromSdkDictionaryType(sdkType, context, typeMap); + break; + case "array": + retVar = fromSdkArrayType(sdkType, context, typeMap); + break; + case "constant": + retVar = fromSdkConstantType(sdkType, typeMap, literalTypeContext); + break; + case "union": + retVar = fromUnionType(sdkType, context, typeMap); + break; + case "utcDateTime": + case "offsetDateTime": + retVar = fromSdkDateTimeType(sdkType); + break; + case "duration": + retVar = fromSdkDurationType(sdkType); + break; + case "tuple": + retVar = fromTupleType(sdkType); + break; + // TODO -- endpoint and credential are handled separately in emitter, since we have specific locations for them in input model. + // We can handle unify the way we handle them in the future, probably by chaning the input model schema and do the conversion in generator. + case "endpoint": + retVar = fromSdkEndpointType(); + break; + case "credential": + throw new Error("Credential type is not supported yet."); + default: + retVar = fromSdkBuiltInType(sdkType); + break; + } + + typeMap.types.set(sdkType, retVar); + return retVar; } export function fromSdkModelType( modelType: SdkModelType, context: SdkContext, - models: Map, - enums: Map + typeMap: SdkTypeMap ): InputModelType { const modelTypeName = modelType.name; - let inputModelType = models.get(modelTypeName); + let inputModelType = typeMap.models.get(modelTypeName); if (!inputModelType) { inputModelType = { Kind: "model", @@ -97,10 +127,10 @@ export function fromSdkModelType( Decorators: modelType.decorators, } as InputModelType; - models.set(modelTypeName, inputModelType); + typeMap.models.set(modelTypeName, inputModelType); inputModelType.AdditionalProperties = modelType.additionalProperties - ? fromSdkType(modelType.additionalProperties, context, models, enums) + ? fromSdkType(modelType.additionalProperties, context, typeMap) : undefined; const propertiesDict = new Map(); @@ -124,7 +154,7 @@ export function fromSdkModelType( : undefined; inputModelType.BaseModel = modelType.baseModel - ? fromSdkModelType(modelType.baseModel, context, models, enums) + ? fromSdkModelType(modelType.baseModel, context, typeMap) : undefined; inputModelType.Properties = Array.from(propertiesDict.values()).flat(); @@ -133,7 +163,7 @@ export function fromSdkModelType( const discriminatedSubtypes: Record = {}; for (const key in modelType.discriminatedSubtypes) { const subtype = modelType.discriminatedSubtypes[key]; - discriminatedSubtypes[key] = fromSdkModelType(subtype, context, models, enums); + discriminatedSubtypes[key] = fromSdkModelType(subtype, context, typeMap); } inputModelType.DiscriminatedSubtypes = discriminatedSubtypes; } @@ -160,8 +190,7 @@ export function fromSdkModelType( Type: fromSdkType( property.type, context, - models, - enums, + typeMap, isDiscriminator ? undefined : literalTypeContext // this is a workaround because the type of discriminator property in derived models is always literal and we wrap literal into enums, which leads to a lot of extra enum types, adding this check to avoid them ), IsRequired: isRequired, @@ -194,13 +223,13 @@ export function fromSdkModelType( export function fromSdkEnumType( enumType: SdkEnumType, context: SdkContext, - enums: Map, + typeMap: SdkTypeMap, addToCollection: boolean = true ): InputEnumType { const enumName = enumType.name; - let inputEnumType = enums.get(enumName); - if (inputEnumType === undefined) { - const newInputEnumType: InputEnumType = { + let inputEnumType = typeMap.enums.get(enumName); + if (!inputEnumType) { + inputEnumType = { Kind: "enum", Name: enumName, CrossLanguageDefinitionId: enumType.crossLanguageDefinitionId, @@ -216,9 +245,9 @@ export function fromSdkEnumType( Usage: enumType.usage, Decorators: enumType.decorators, }; - if (addToCollection) enums.set(enumName, newInputEnumType); - inputEnumType = newInputEnumType; + if (addToCollection) typeMap.enums.set(enumName, inputEnumType); } + return inputEnumType; } @@ -247,7 +276,7 @@ function fromSdkDurationType(durationType: SdkDurationType): InputDurationType { } // TODO: tuple is not officially supported -function fromTupleType(tupleType: SdkTupleType): InputPrimitiveType { +function fromTupleType(tupleType: SdkTupleType): InputType { return { Kind: "any", Name: "tuple", @@ -270,12 +299,11 @@ function fromSdkBuiltInType(builtInType: SdkBuiltInType): InputPrimitiveType { function fromUnionType( union: SdkUnionType, context: SdkContext, - models: Map, - enums: Map + typeMap: SdkTypeMap ): InputUnionType { const variantTypes: InputType[] = []; for (const value of union.values) { - const variantType = fromSdkType(value, context, models, enums); + const variantType = fromSdkType(value, context, typeMap); variantTypes.push(variantType); } @@ -289,9 +317,7 @@ function fromUnionType( function fromSdkConstantType( constantType: SdkConstantType, - context: SdkContext, - models: Map, - enums: Map, + typeMap: SdkTypeMap, literalTypeContext?: LiteralTypeContext ): InputLiteralType { return { @@ -301,14 +327,13 @@ function fromSdkConstantType( ? fromSdkBuiltInType(constantType.valueType) : // TODO: this might change in the near future // we might keep constant as-is, instead of creating an enum for it. - convertConstantToEnum(constantType, enums, literalTypeContext), + convertConstantToEnum(constantType, literalTypeContext), Value: constantType.value, Decorators: constantType.decorators, }; function convertConstantToEnum( constantType: SdkConstantType, - enums: Map, literalTypeContext: LiteralTypeContext ) { // otherwise we need to wrap this into an extensible enum @@ -335,7 +360,8 @@ function fromSdkConstantType( Usage: literalTypeContext.Usage, Decorators: constantType.decorators, }; - enums.set(enumName, enumType); + + typeMap.enums.set(enumName, enumType); return enumType; } } @@ -343,15 +369,15 @@ function fromSdkConstantType( function fromSdkEnumValueTypeToConstantType( enumValueType: SdkEnumValueType, context: SdkContext, - enums: Map, + typeMap: SdkTypeMap, literalTypeContext?: LiteralTypeContext ): InputLiteralType { return { Kind: "constant", ValueType: enumValueType.valueType.kind === "boolean" || literalTypeContext === undefined - ? fromSdkBuiltInType(enumValueType.valueType as SdkBuiltInType) // TODO: TCGC fix - : fromSdkEnumType(enumValueType.enumType, context, enums), + ? fromSdkBuiltInType(enumValueType.valueType) + : fromSdkEnumType(enumValueType.enumType, context, typeMap), Value: enumValueType.value, Decorators: enumValueType.decorators, }; @@ -369,13 +395,12 @@ function fromSdkEnumValueType(enumValueType: SdkEnumValueType): InputEnumTypeVal function fromSdkDictionaryType( dictionaryType: SdkDictionaryType, context: SdkContext, - models: Map, - enums: Map + typeMap: SdkTypeMap ): InputDictionaryType { return { Kind: "dict", - KeyType: fromSdkType(dictionaryType.keyType, context, models, enums), - ValueType: fromSdkType(dictionaryType.valueType, context, models, enums), + KeyType: fromSdkType(dictionaryType.keyType, context, typeMap), + ValueType: fromSdkType(dictionaryType.valueType, context, typeMap), Decorators: dictionaryType.decorators, }; } @@ -383,13 +408,12 @@ function fromSdkDictionaryType( function fromSdkArrayType( arrayType: SdkArrayType, context: SdkContext, - models: Map, - enums: Map + typeMap: SdkTypeMap ): InputArrayType { return { Kind: "array", Name: arrayType.name, - ValueType: fromSdkType(arrayType.valueType, context, models, enums), + ValueType: fromSdkType(arrayType.valueType, context, typeMap), CrossLanguageDefinitionId: arrayType.crossLanguageDefinitionId, Decorators: arrayType.decorators, }; diff --git a/packages/http-client-csharp/emitter/src/lib/model.ts b/packages/http-client-csharp/emitter/src/lib/model.ts index 86737cbed2..0650a74089 100644 --- a/packages/http-client-csharp/emitter/src/lib/model.ts +++ b/packages/http-client-csharp/emitter/src/lib/model.ts @@ -14,8 +14,9 @@ import { isStatusCode, } from "@typespec/http"; import { NetEmitterOptions } from "../options.js"; -import { InputEnumType, InputModelType, InputType } from "../type/input-type.js"; +import { InputType } from "../type/input-type.js"; import { LiteralTypeContext } from "../type/literal-type-context.js"; +import { SdkTypeMap } from "../type/sdk-type-map.js"; import { fromSdkEnumType, fromSdkModelType, fromSdkType } from "./converter.js"; import { Logger } from "./logger.js"; @@ -72,30 +73,25 @@ export function getDefaultValue(type: Type): any { export function getInputType( context: SdkContext, type: Type, - models: Map, - enums: Map, + typeCache: SdkTypeMap, operation?: Operation, literalTypeContext?: LiteralTypeContext ): InputType { Logger.getInstance().debug(`getInputType for kind: ${type.kind}`); const sdkType = getClientType(context, type, operation); - return fromSdkType(sdkType, context, models, enums, literalTypeContext); + return fromSdkType(sdkType, context, typeCache, literalTypeContext); } -export function navigateModels( - context: SdkContext, - models: Map, - enums: Map -) { +export function navigateModels(context: SdkContext, typeCache: SdkTypeMap) { for (const type of getAllModels(context)) { if (type.name === "") { continue; } if (type.kind === "model") { - fromSdkModelType(type, context, models, enums); + fromSdkModelType(type, context, typeCache); } else { - fromSdkEnumType(type, context, enums); + fromSdkEnumType(type, context, typeCache); } } } diff --git a/packages/http-client-csharp/emitter/src/lib/operation-converter.ts b/packages/http-client-csharp/emitter/src/lib/operation-converter.ts index 25e00e3735..9a8cd87d52 100644 --- a/packages/http-client-csharp/emitter/src/lib/operation-converter.ts +++ b/packages/http-client-csharp/emitter/src/lib/operation-converter.ts @@ -8,6 +8,7 @@ import { SdkContext, SdkHeaderParameter, SdkHttpOperation, + SdkHttpParameter, SdkHttpResponse, SdkPathParameter, SdkQueryParameter, @@ -29,17 +30,13 @@ import { InputConstant } from "../type/input-constant.js"; import { InputOperationParameterKind } from "../type/input-operation-parameter-kind.js"; import { InputOperation } from "../type/input-operation.js"; import { InputParameter } from "../type/input-parameter.js"; -import { - InputEnumType, - InputModelType, - InputPrimitiveType, - InputType, -} from "../type/input-type.js"; +import { InputPrimitiveType, InputType } from "../type/input-type.js"; import { convertLroFinalStateVia } from "../type/operation-final-state-via.js"; import { OperationPaging } from "../type/operation-paging.js"; import { OperationResponse } from "../type/operation-response.js"; import { RequestLocation } from "../type/request-location.js"; import { parseHttpRequestMethod } from "../type/request-method.js"; +import { SdkTypeMap } from "../type/sdk-type-map.js"; import { fromSdkType } from "./converter.js"; import { getExternalDocs, getOperationId } from "./decorators.js"; import { Logger } from "./logger.js"; @@ -51,8 +48,7 @@ export function fromSdkServiceMethod( clientParameters: InputParameter[], rootApiVersions: string[], sdkContext: SdkContext, - modelMap: Map, - enumMap: Map + typeCache: SdkTypeMap ): InputOperation { let generateConvenience = shouldGenerateConvenient(sdkContext, method.operation.__raw.operation); if (method.operation.verb === "patch" && generateConvenience) { @@ -62,6 +58,12 @@ export function fromSdkServiceMethod( generateConvenience = false; } + const parameterMap = fromSdkOperationParameters( + method.operation, + rootApiVersions, + sdkContext, + typeCache + ); return { Name: method.name, ResourceName: @@ -74,20 +76,8 @@ export function fromSdkServiceMethod( Summary: getSummary(sdkContext.program, method.__raw!), Description: getDoc(sdkContext.program, method.__raw!), Accessibility: method.access, - Parameters: fromSdkOperationParameters( - method.operation, - clientParameters, - rootApiVersions, - sdkContext, - modelMap, - enumMap - ), - Responses: fromSdkHttpOperationResponses( - method.operation.responses, - sdkContext, - modelMap, - enumMap - ), + Parameters: [...clientParameters, ...parameterMap.values()], + Responses: fromSdkHttpOperationResponses(method.operation.responses, sdkContext, typeCache), HttpMethod: parseHttpRequestMethod(method.operation.verb), RequestBodyMediaType: getBodyMediaType(method.operation.bodyParam?.type), Uri: uri, @@ -95,7 +85,7 @@ export function fromSdkServiceMethod( ExternalDocsUrl: getExternalDocs(sdkContext, method.operation.__raw.operation)?.url, RequestMediaTypes: getRequestMediaTypes(method.operation), BufferResponse: true, - LongRunning: loadLongRunningOperation(method, sdkContext, modelMap, enumMap), + LongRunning: loadLongRunningOperation(method, sdkContext, typeCache), Paging: loadOperationPaging(method), GenerateProtocolMethod: shouldGenerateProtocol(sdkContext, method.operation.__raw.operation), GenerateConvenienceMethod: generateConvenience, @@ -144,28 +134,26 @@ function getValueType(value: any): SdkBuiltInKinds { function fromSdkOperationParameters( operation: SdkHttpOperation, - clientParameters: InputParameter[], rootApiVersions: string[], sdkContext: SdkContext, - modelMap: Map, - enumMap: Map -): InputParameter[] { - const params = clientParameters.concat( - operation.parameters.map((p) => - fromSdkHttpOperationParameter(p, rootApiVersions, sdkContext, modelMap, enumMap) - ) - ); - return operation.bodyParam - ? params.concat( - fromSdkHttpOperationParameter( - operation.bodyParam, - rootApiVersions, - sdkContext, - modelMap, - enumMap - ) - ) - : params; + typeCache: SdkTypeMap +): Map { + const parameters = new Map(); + for (const p of operation.parameters) { + const param = fromSdkHttpOperationParameter(p, rootApiVersions, sdkContext, typeCache); + parameters.set(p, param); + } + + if (operation.bodyParam) { + const bodyParam = fromSdkHttpOperationParameter( + operation.bodyParam, + rootApiVersions, + sdkContext, + typeCache + ); + parameters.set(operation.bodyParam, bodyParam); + } + return parameters; } // TODO: roll back to SdkMethodParameter when we figure out how to represent the parameter location @@ -174,12 +162,11 @@ function fromSdkHttpOperationParameter( p: SdkPathParameter | SdkQueryParameter | SdkHeaderParameter | SdkBodyParameter, rootApiVersions: string[], sdkContext: SdkContext, - modelMap: Map, - enumMap: Map + typeCache: SdkTypeMap ): InputParameter { const isContentType = p.kind === "header" && p.serializedName.toLocaleLowerCase() === "content-type"; - const parameterType = fromSdkType(p.type, sdkContext, modelMap, enumMap); + const parameterType = fromSdkType(p.type, sdkContext, typeCache); // remove this after: https://github.com/Azure/typespec-azure/issues/1084 if (p.type.kind === "bytes") { (parameterType as InputPrimitiveType).Encode = ( @@ -211,8 +198,7 @@ function fromSdkHttpOperationParameter( function loadLongRunningOperation( method: SdkServiceMethod, sdkContext: SdkContext, - modelMap: Map, - enumMap: Map + typeCache: SdkTypeMap ): import("../type/operation-long-running.js").OperationLongRunning | undefined { if (method.kind !== "lro") { return undefined; @@ -230,8 +216,7 @@ function loadLongRunningOperation( ? getInputType( sdkContext, method.__raw_lro_metadata.finalEnvelopeResult, - modelMap, - enumMap, + typeCache, method.operation.__raw.operation ) : undefined, @@ -244,16 +229,15 @@ function loadLongRunningOperation( function fromSdkHttpOperationResponses( operationResponses: Map, sdkContext: SdkContext, - modelMap: Map, - enumMap: Map + typeCache: SdkTypeMap ): OperationResponse[] { const responses: OperationResponse[] = []; operationResponses.forEach((r, range) => { responses.push({ StatusCodes: toStatusCodesArray(range), - BodyType: r.type ? fromSdkType(r.type, sdkContext, modelMap, enumMap) : undefined, + BodyType: r.type ? fromSdkType(r.type, sdkContext, typeCache) : undefined, BodyMediaType: BodyMediaType.Json, - Headers: fromSdkServiceResponseHeaders(r.headers, sdkContext, modelMap, enumMap), + Headers: fromSdkServiceResponseHeaders(r.headers, sdkContext, typeCache), IsErrorResponse: r.type !== undefined && isErrorModel(sdkContext.program, r.type.__raw!), ContentTypes: r.contentTypes, }); @@ -264,8 +248,7 @@ function fromSdkHttpOperationResponses( function fromSdkServiceResponseHeaders( headers: SdkServiceResponseHeader[], sdkContext: SdkContext, - modelMap: Map, - enumMap: Map + typeCache: SdkTypeMap ): HttpResponseHeader[] { return headers.map( (h) => @@ -273,7 +256,7 @@ function fromSdkServiceResponseHeaders( Name: h.__raw!.name, NameInResponse: h.serializedName, Description: h.description, - Type: fromSdkType(h.type, sdkContext, modelMap, enumMap), + Type: fromSdkType(h.type, sdkContext, typeCache), }) as HttpResponseHeader ); } diff --git a/packages/http-client-csharp/emitter/src/lib/typespec-server.ts b/packages/http-client-csharp/emitter/src/lib/typespec-server.ts index 4829a7ab54..0dd01127af 100644 --- a/packages/http-client-csharp/emitter/src/lib/typespec-server.ts +++ b/packages/http-client-csharp/emitter/src/lib/typespec-server.ts @@ -9,8 +9,9 @@ import { NetEmitterOptions } from "../options.js"; import { InputConstant } from "../type/input-constant.js"; import { InputOperationParameterKind } from "../type/input-operation-parameter-kind.js"; import { InputParameter } from "../type/input-parameter.js"; -import { InputEnumType, InputModelType, InputType } from "../type/input-type.js"; +import { InputType } from "../type/input-type.js"; import { RequestLocation } from "../type/request-location.js"; +import { SdkTypeMap } from "../type/sdk-type-map.js"; import { getDefaultValue, getInputType } from "./model.js"; export interface TypeSpecServer { @@ -22,8 +23,7 @@ export interface TypeSpecServer { export function resolveServers( context: SdkContext, servers: HttpServer[], - models: Map, - enums: Map + typeCache: SdkTypeMap ): TypeSpecServer[] { return servers.map((server) => { const parameters: InputParameter[] = []; @@ -39,7 +39,7 @@ export function resolveServers( Name: "url", CrossLanguageDefinitionId: "TypeSpec.url", } - : getInputType(context, prop, models, enums); + : getInputType(context, prop, typeCache); if (value) { defaultValue = { diff --git a/packages/http-client-csharp/emitter/src/type/sdk-type-map.ts b/packages/http-client-csharp/emitter/src/type/sdk-type-map.ts new file mode 100644 index 0000000000..ae39b539cb --- /dev/null +++ b/packages/http-client-csharp/emitter/src/type/sdk-type-map.ts @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +import { SdkType } from "@azure-tools/typespec-client-generator-core"; +import { InputEnumType, InputModelType, InputType } from "./input-type.js"; + +export interface SdkTypeMap { + types: Map; + models: Map; + enums: Map; +} diff --git a/packages/http-client-csharp/emitter/test/Unit/encode.test.ts b/packages/http-client-csharp/emitter/test/Unit/encode.test.ts index 21ed249fdc..a312eb6a10 100644 --- a/packages/http-client-csharp/emitter/test/Unit/encode.test.ts +++ b/packages/http-client-csharp/emitter/test/Unit/encode.test.ts @@ -1,14 +1,11 @@ import { TestHost } from "@typespec/compiler/testing"; -import { getAllHttpServices } from "@typespec/http"; import { ok, strictEqual } from "assert"; import { beforeEach, describe, it } from "vitest"; import { createModel } from "../../src/lib/client-model-builder.js"; -import { InputEnumType, InputModelType } from "../../src/type/input-type.js"; import { createEmitterContext, createEmitterTestHost, createNetSdkContext, - navigateModels, typeSpecCompile, } from "./utils/test-util.js"; @@ -102,16 +99,16 @@ describe("Test encode duration", () => { @encode(DurationKnownEncoding.ISO8601) value: duration; } + + op test() : ISO8601DurationProperty; `, runner ); const context = createEmitterContext(program); const sdkContext = await createNetSdkContext(context); - const [services] = getAllHttpServices(program); - const modelMap = new Map(); - const enumMap = new Map(); - navigateModels(sdkContext, services[0].namespace, modelMap, enumMap); - const durationModel = modelMap.get("ISO8601DurationProperty"); + const codeModel = createModel(sdkContext); + const models = codeModel.Models; + const durationModel = models.find((m) => m.Name === "ISO8601DurationProperty"); ok(durationModel); const type = durationModel.Properties[0].Type; strictEqual(type.Kind, "duration"); @@ -131,16 +128,16 @@ describe("Test encode duration", () => { @encode(DurationKnownEncoding.seconds, int32) value: duration; } + + op test() : Int32SecondsDurationProperty; `, runner ); const context = createEmitterContext(program); const sdkContext = await createNetSdkContext(context); - const [services] = getAllHttpServices(program); - const modelMap = new Map(); - const enumMap = new Map(); - navigateModels(sdkContext, services[0].namespace, modelMap, enumMap); - const durationModel = modelMap.get("Int32SecondsDurationProperty"); + const codeModel = createModel(sdkContext); + const models = codeModel.Models; + const durationModel = models.find((m) => m.Name === "Int32SecondsDurationProperty"); ok(durationModel); const type = durationModel.Properties[0].Type; strictEqual(type.Kind, "duration"); @@ -160,16 +157,16 @@ describe("Test encode duration", () => { @encode(DurationKnownEncoding.seconds, float32) value: duration; } + + op test() : FloatSecondsDurationProperty; `, runner ); const context = createEmitterContext(program); const sdkContext = await createNetSdkContext(context); - const [services] = getAllHttpServices(program); - const modelMap = new Map(); - const enumMap = new Map(); - navigateModels(sdkContext, services[0].namespace, modelMap, enumMap); - const durationModel = modelMap.get("FloatSecondsDurationProperty"); + const codeModel = createModel(sdkContext); + const models = codeModel.Models; + const durationModel = models.find((m) => m.Name === "FloatSecondsDurationProperty"); ok(durationModel); const type = durationModel.Properties[0].Type; strictEqual(type.Kind, "duration"); diff --git a/packages/http-client-csharp/emitter/test/Unit/string-format.test.ts b/packages/http-client-csharp/emitter/test/Unit/string-format.test.ts index a9a8faf1ee..f1a76e7e56 100644 --- a/packages/http-client-csharp/emitter/test/Unit/string-format.test.ts +++ b/packages/http-client-csharp/emitter/test/Unit/string-format.test.ts @@ -1,14 +1,11 @@ import { TestHost } from "@typespec/compiler/testing"; -import { getAllHttpServices } from "@typespec/http"; import { ok, strictEqual } from "assert"; import { beforeEach, describe, it } from "vitest"; import { createModel } from "../../src/lib/client-model-builder.js"; -import { InputEnumType, InputModelType } from "../../src/type/input-type.js"; import { createEmitterContext, createEmitterTestHost, createNetSdkContext, - navigateModels, typeSpecCompile, } from "./utils/test-util.js"; @@ -41,16 +38,16 @@ describe("Test string format", () => { @doc("The source url.") source: url; } + + op test(@body foo: Foo): void; `, runner ); const context = createEmitterContext(program); const sdkContext = await createNetSdkContext(context); - const [services] = getAllHttpServices(program); - const modelMap = new Map(); - const enumMap = new Map(); - navigateModels(sdkContext, services[0].namespace, modelMap, enumMap); - const foo = modelMap.get("Foo"); + const codeModel = createModel(sdkContext); + const models = codeModel.Models; + const foo = models.find((m) => m.Name === "Foo"); ok(foo); const type = foo?.Properties[0].Type; strictEqual(type.Kind, "url");