@typespec/http-server-csharp 0.58.0-alpha.10-dev.0 → 0.58.0-alpha.10-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { NoTarget, getFriendlyName, isNullType, isNumericType, isTemplateInstance, isUnknownType, isVoidType, } from "@typespec/compiler";
2
- import { StringBuilder } from "@typespec/compiler/emitter-framework";
3
- import { Visibility, createMetadataInfo, isBody, isBodyRoot, isMetadata, isStatusCode, } from "@typespec/http";
2
+ import { StringBuilder, code, } from "@typespec/compiler/emitter-framework";
3
+ import { Visibility, createMetadataInfo, getHeaderFieldName, isBody, isBodyRoot, isHeader, isMetadata, isPathParam, isQueryParam, isStatusCode, } from "@typespec/http";
4
4
  import { camelCase, pascalCase } from "change-case";
5
5
  import { getAttributes } from "./attributes.js";
6
6
  import { BooleanValue, CSharpType, NameCasingType, NullValue, NumericValue, StringValue, } from "./interfaces.js";
@@ -21,7 +21,7 @@ export function getCSharpTypeForScalar(program, scalar) {
21
21
  target: scalar,
22
22
  });
23
23
  const result = new CSharpType({
24
- name: "Object",
24
+ name: "object",
25
25
  namespace: "System",
26
26
  isBuiltIn: true,
27
27
  isValueType: false,
@@ -82,6 +82,7 @@ export function getCSharpType(program, type, namespace) {
82
82
  namespace: namespace || "Models",
83
83
  isBuiltIn: false,
84
84
  isValueType: false,
85
+ isClass: true,
85
86
  }),
86
87
  };
87
88
  case "Enum":
@@ -90,7 +91,7 @@ export function getCSharpType(program, type, namespace) {
90
91
  name: ensureCSharpIdentifier(program, type, type.name, NameCasingType.Class),
91
92
  namespace: `${namespace}.Models`,
92
93
  isBuiltIn: false,
93
- isValueType: false,
94
+ isValueType: true,
94
95
  }),
95
96
  };
96
97
  case "Model":
@@ -105,6 +106,8 @@ export function getCSharpType(program, type, namespace) {
105
106
  namespace: itemType.namespace,
106
107
  isBuiltIn: itemType.isBuiltIn,
107
108
  isValueType: false,
109
+ isClass: itemType.isClass,
110
+ isCollection: true,
108
111
  }),
109
112
  };
110
113
  }
@@ -118,6 +121,7 @@ export function getCSharpType(program, type, namespace) {
118
121
  namespace: `${namespace}.Models`,
119
122
  isBuiltIn: false,
120
123
  isValueType: false,
124
+ isClass: true,
121
125
  }),
122
126
  };
123
127
  default:
@@ -474,6 +478,23 @@ export function ensureCSharpIdentifier(program, target, name, context = NameCasi
474
478
  export function getModelAttributes(program, entity, cSharpName) {
475
479
  return getAttributes(program, entity, cSharpName);
476
480
  }
481
+ export function getModelDeclarationName(program, model, defaultSuffix) {
482
+ if (model.name !== null && model.name.length > 0) {
483
+ return ensureCSharpIdentifier(program, model, model.name, NameCasingType.Class);
484
+ }
485
+ if (model.sourceModel && model.sourceModel.name && model.sourceModel.name.length > 0) {
486
+ return ensureCSharpIdentifier(program, model, `${model.sourceModel.name}${defaultSuffix}`, NameCasingType.Class);
487
+ }
488
+ if (model.sourceModels.length > 0) {
489
+ const sourceNames = model.sourceModels
490
+ .filter((m) => m.model.name !== undefined && m.model.name.length > 0)
491
+ .flatMap((m) => ensureCSharpIdentifier(program, model, m.model.name, NameCasingType.Class));
492
+ if (sourceNames.length > 0) {
493
+ return `${sourceNames.join()}${defaultSuffix}`;
494
+ }
495
+ }
496
+ return `Model${defaultSuffix}`;
497
+ }
477
498
  export function getModelInstantiationName(program, model, name) {
478
499
  const friendlyName = getFriendlyName(program, model);
479
500
  if (friendlyName && friendlyName.length > 0)
@@ -563,6 +584,8 @@ export class HttpMetadata {
563
584
  });
564
585
  switch (responseType.kind) {
565
586
  case "Model":
587
+ if (responseType.indexer && responseType.indexer.key.name !== "string")
588
+ return responseType;
566
589
  const bodyProp = new ModelInfo().filterAllProperties(program, responseType, (p) => isBody(program, p) || isBodyRoot(program, p));
567
590
  if (bodyProp !== undefined)
568
591
  return metaInfo.getEffectivePayloadType(bodyProp.type, Visibility.Read);
@@ -642,4 +665,522 @@ export function getCSharpStatusCode(entry) {
642
665
  return undefined;
643
666
  }
644
667
  }
668
+ export function isEmptyResponseModel(program, model) {
669
+ if (model.kind !== "Model")
670
+ return false;
671
+ if (model.properties.size === 0)
672
+ return true;
673
+ return model.properties.size === 1 && isStatusCode(program, [...model.properties.values()][0]);
674
+ }
675
+ export function isContentTypeHeader(program, parameter) {
676
+ return (isHeader(program, parameter) &&
677
+ (parameter.name === "contentType" || getHeaderFieldName(program, parameter) === "Content-type"));
678
+ }
679
+ export function isValidParameter(program, parameter) {
680
+ return (!isContentTypeHeader(program, parameter) &&
681
+ (parameter.type.kind !== "Intrinsic" || parameter.type.name !== "never") &&
682
+ parameter.model?.name === "");
683
+ }
684
+ /** Determine whether the given parameter is http metadata */
685
+ export function isHttpMetadata(program, property) {
686
+ return (isPathParam(program, property) || isHeader(program, property) || isQueryParam(program, property));
687
+ }
688
+ export function getBusinessLogicCallParameters(parameters) {
689
+ const builder = new StringBuilder();
690
+ const blParameters = parameters.filter((p) => p.operationKind === "BusinessLogic" || p.operationKind === "All");
691
+ let i = 0;
692
+ for (const param of blParameters) {
693
+ builder.push(code `${getBusinessLogicCallParameter(param)}${++i < blParameters.length ? ", " : ""}`);
694
+ }
695
+ return builder.reduce();
696
+ }
697
+ export function getBusinessLogicDeclParameters(parameters) {
698
+ const builder = new StringBuilder();
699
+ const blParameters = parameters.filter((p) => p.operationKind === "BusinessLogic" || p.operationKind === "All");
700
+ let i = 0;
701
+ for (const param of blParameters) {
702
+ builder.push(code `${getBusinessLogicSignatureParameter(param)}${++i < blParameters.length ? ", " : ""}`);
703
+ }
704
+ return builder.reduce();
705
+ }
706
+ export function getHttpDeclParameters(parameters) {
707
+ const builder = new StringBuilder();
708
+ const blParameters = parameters.filter((p) => p.operationKind === "Http" || p.operationKind === "All");
709
+ let i = 0;
710
+ for (const param of blParameters) {
711
+ builder.push(code `${getHttpSignatureParameter(param)}${++i < blParameters.length ? ", " : ""}`);
712
+ }
713
+ return builder.reduce();
714
+ }
715
+ export function getBusinessLogicCallParameter(param) {
716
+ const builder = new StringBuilder();
717
+ builder.push(code `${param.callName}`);
718
+ return builder.reduce();
719
+ }
720
+ export function getBusinessLogicSignatureParameter(param) {
721
+ const builder = new StringBuilder();
722
+ builder.push(code `${param.typeName}${param.optional || param.nullable ? "? " : " "}${param.name}`);
723
+ return builder.reduce();
724
+ }
725
+ export function getHttpSignatureParameter(param) {
726
+ const builder = new StringBuilder();
727
+ builder.push(code `${getHttpParameterDecorator(param)}${getBusinessLogicSignatureParameter(param)}${param.defaultValue === undefined ? "" : code ` = ${typeof param.defaultValue === "boolean" ? code `${param.defaultValue.toString()}` : code `${param.defaultValue}`}`}`);
728
+ return builder.reduce();
729
+ }
730
+ export function getHttpParameterDecorator(parameter) {
731
+ switch (parameter.httpParameterKind) {
732
+ case "query":
733
+ return code `[FromQuery${parameter.httpParameterName ? code `(Name="${parameter.httpParameterName}")` : ""}] `;
734
+ case "header":
735
+ return code `[FromHeader${parameter.httpParameterName ? code `(Name="${parameter.httpParameterName}")` : ""}] `;
736
+ default:
737
+ return "";
738
+ }
739
+ }
740
+ export function getParameterKind(parameter) {
741
+ switch (parameter.type) {
742
+ case "path":
743
+ return "path";
744
+ case "cookie":
745
+ case "header":
746
+ return "header";
747
+ case "query":
748
+ return "query";
749
+ }
750
+ }
751
+ export function canHaveDefault(program, type) {
752
+ switch (type.kind) {
753
+ case "Boolean":
754
+ case "EnumMember":
755
+ case "Enum":
756
+ case "Number":
757
+ case "String":
758
+ case "Scalar":
759
+ case "StringTemplate":
760
+ return true;
761
+ case "ModelProperty":
762
+ return canHaveDefault(program, type.type);
763
+ default:
764
+ return false;
765
+ }
766
+ }
767
+ export class CSharpOperationHelpers {
768
+ constructor(inEmitter) {
769
+ this.emitter = inEmitter;
770
+ this.#anonymousModels = new Map();
771
+ this.#opCache = new Map();
772
+ }
773
+ emitter;
774
+ #anonymousModels;
775
+ #opCache;
776
+ getParameters(program, operation) {
777
+ function safeConcat(...names) {
778
+ return names
779
+ .filter((n) => n !== undefined && n !== null && n.length > 0)
780
+ .flatMap((s) => getCSharpIdentifier(s, NameCasingType.Class))
781
+ .join();
782
+ }
783
+ const cached = this.#opCache.get(operation.operation);
784
+ if (cached)
785
+ return cached;
786
+ const bodyParam = operation.parameters.body;
787
+ const isExplicitBodyParam = bodyParam?.property !== undefined;
788
+ const result = [];
789
+ if (operation.verb === "get" && operation.parameters.body !== undefined) {
790
+ reportDiagnostic(program, {
791
+ code: "get-request-body",
792
+ target: operation.operation,
793
+ format: {},
794
+ });
795
+ this.#opCache.set(operation.operation, result);
796
+ return result;
797
+ }
798
+ const validParams = operation.parameters.parameters.filter((p) => isValidParameter(program, p.param));
799
+ const requiredParams = validParams.filter((p) => p.type === "path" || (!p.param.optional && p.param.defaultValue === undefined));
800
+ const optionalParams = validParams.filter((p) => p.type !== "path" && (p.param.optional || p.param.defaultValue !== undefined));
801
+ for (const parameter of requiredParams) {
802
+ let { typeReference: paramType, defaultValue: paramValue } = this.getTypeInfo(program, parameter.param.type);
803
+ // cSharp does not allow array defaults in operation parameters
804
+ if (!canHaveDefault(program, parameter.param)) {
805
+ paramValue = undefined;
806
+ }
807
+ const paramName = ensureCSharpIdentifier(program, parameter.param, parameter.param.name, NameCasingType.Parameter);
808
+ result.push({
809
+ isExplicitBody: false,
810
+ name: paramName,
811
+ callName: paramName,
812
+ optional: false,
813
+ typeName: paramType,
814
+ defaultValue: paramValue,
815
+ httpParameterKind: getParameterKind(parameter),
816
+ httpParameterName: parameter.name,
817
+ nullable: false,
818
+ operationKind: "All",
819
+ });
820
+ }
821
+ const overrideParameters = getExplicitBodyParameters(program, operation);
822
+ if (overrideParameters !== undefined) {
823
+ for (const overrideParam of overrideParameters) {
824
+ result.push(overrideParam);
825
+ }
826
+ }
827
+ else if (bodyParam !== undefined && isExplicitBodyParam) {
828
+ let { typeReference: bodyType, defaultValue: bodyValue, nullableType: isNullable, } = this.getTypeInfo(program, bodyParam.type);
829
+ if (!canHaveDefault(program, bodyParam.type)) {
830
+ bodyValue = undefined;
831
+ }
832
+ result.push({
833
+ isExplicitBody: true,
834
+ httpParameterKind: "body",
835
+ name: "body",
836
+ callName: "body",
837
+ typeName: bodyType,
838
+ nullable: isNullable,
839
+ defaultValue: bodyValue,
840
+ optional: bodyParam.property?.optional ?? false,
841
+ operationKind: "All",
842
+ });
843
+ }
844
+ else if (bodyParam !== undefined) {
845
+ switch (bodyParam.type.kind) {
846
+ case "Model":
847
+ let tsBody = bodyParam.type;
848
+ if (!bodyParam.type.name) {
849
+ tsBody = program.checker.cloneType(bodyParam.type, {
850
+ name: safeConcat(operation.operation.interface?.name, operation.operation.name, "Request"),
851
+ });
852
+ }
853
+ const { typeReference: bodyType } = this.getTypeInfo(program, tsBody);
854
+ const bodyName = ensureCSharpIdentifier(program, bodyParam.type, "body", NameCasingType.Parameter);
855
+ result.push({
856
+ isExplicitBody: false,
857
+ httpParameterKind: "body",
858
+ name: bodyName,
859
+ callName: bodyName,
860
+ typeName: bodyType,
861
+ nullable: false,
862
+ defaultValue: undefined,
863
+ optional: false,
864
+ operationKind: "Http",
865
+ });
866
+ for (const [propName, propDef] of bodyParam.type.properties) {
867
+ let { typeReference: csType, defaultValue: csValue, nullableType: isNullable, } = this.getTypeInfo(program, propDef.type);
868
+ // cSharp does not allow array defaults in operation parameters
869
+ if (!canHaveDefault(program, propDef)) {
870
+ csValue = undefined;
871
+ }
872
+ const paramName = ensureCSharpIdentifier(program, propDef, propName, NameCasingType.Parameter);
873
+ const refName = ensureCSharpIdentifier(program, propDef, propName, NameCasingType.Property);
874
+ result.push({
875
+ isExplicitBody: false,
876
+ httpParameterKind: "body",
877
+ name: paramName,
878
+ callName: `body.${refName}`,
879
+ typeName: csType,
880
+ nullable: isNullable,
881
+ defaultValue: csValue,
882
+ optional: propDef.optional,
883
+ operationKind: "BusinessLogic",
884
+ });
885
+ }
886
+ break;
887
+ case "ModelProperty":
888
+ {
889
+ let { typeReference: csType, defaultValue: csValue, nullableType: isNullable, } = this.getTypeInfo(program, bodyParam.type.type);
890
+ if (!canHaveDefault(program, bodyParam.type)) {
891
+ csValue = undefined;
892
+ }
893
+ const optName = ensureCSharpIdentifier(program, bodyParam.type.type, bodyParam.type.name, NameCasingType.Parameter);
894
+ result.push({
895
+ isExplicitBody: true,
896
+ httpParameterKind: "body",
897
+ name: optName,
898
+ callName: optName,
899
+ typeName: csType,
900
+ nullable: isNullable,
901
+ defaultValue: csValue,
902
+ optional: bodyParam.type.optional,
903
+ operationKind: "All",
904
+ });
905
+ }
906
+ break;
907
+ default: {
908
+ let { typeReference: csType, defaultValue: csValue, nullableType: isNullable, } = this.getTypeInfo(program, bodyParam.type);
909
+ if (!canHaveDefault(program, bodyParam.type)) {
910
+ csValue = undefined;
911
+ }
912
+ result.push({
913
+ isExplicitBody: true,
914
+ httpParameterKind: "body",
915
+ name: "body",
916
+ callName: "body",
917
+ typeName: csType,
918
+ nullable: isNullable,
919
+ defaultValue: csValue,
920
+ optional: false,
921
+ operationKind: "All",
922
+ });
923
+ }
924
+ }
925
+ }
926
+ for (const parameter of optionalParams) {
927
+ const { typeReference: paramType, defaultValue: paramValue, nullableType: isNullable, } = this.getTypeInfo(program, parameter.param.type);
928
+ const optName = ensureCSharpIdentifier(program, parameter.param, parameter.param.name, NameCasingType.Parameter);
929
+ result.push({
930
+ isExplicitBody: false,
931
+ name: optName,
932
+ callName: optName,
933
+ optional: true,
934
+ typeName: paramType,
935
+ defaultValue: paramValue,
936
+ httpParameterKind: getParameterKind(parameter),
937
+ httpParameterName: parameter.name,
938
+ nullable: isNullable,
939
+ operationKind: "All",
940
+ });
941
+ }
942
+ this.#opCache.set(operation.operation, result);
943
+ return result;
944
+ }
945
+ getTypeInfo(program, tsType) {
946
+ const myEmitter = this.emitter;
947
+ function extractStringValue(type, span) {
948
+ switch (type.kind) {
949
+ case "String":
950
+ return type.value;
951
+ case "Boolean":
952
+ return `${type.value}`;
953
+ case "Number":
954
+ return type.valueAsString;
955
+ case "StringTemplateSpan":
956
+ if (type.isInterpolated) {
957
+ return extractStringValue(type.type, span);
958
+ }
959
+ else {
960
+ return type.type.value;
961
+ }
962
+ case "ModelProperty":
963
+ return extractStringValue(type.type, span);
964
+ case "EnumMember":
965
+ if (type.value === undefined)
966
+ return type.name;
967
+ if (typeof type.value === "string")
968
+ return type.value;
969
+ if (typeof type.value === "number")
970
+ return `${type.value}`;
971
+ }
972
+ reportDiagnostic(myEmitter.getProgram(), {
973
+ code: "invalid-interpolation",
974
+ target: span,
975
+ format: {},
976
+ });
977
+ return "";
978
+ }
979
+ switch (tsType.kind) {
980
+ case "String":
981
+ return {
982
+ typeReference: code `string`,
983
+ defaultValue: `"${tsType.value}"`,
984
+ nullableType: false,
985
+ };
986
+ case "StringTemplate":
987
+ const template = tsType;
988
+ if (template.stringValue !== undefined)
989
+ return {
990
+ typeReference: code `string`,
991
+ defaultValue: `"${template.stringValue}"`,
992
+ nullableType: false,
993
+ };
994
+ const spanResults = [];
995
+ for (const span of template.spans) {
996
+ spanResults.push(extractStringValue(span, span));
997
+ }
998
+ return {
999
+ typeReference: code `string`,
1000
+ defaultValue: `"${spanResults.join("")}"`,
1001
+ nullableType: false,
1002
+ };
1003
+ case "Boolean":
1004
+ return {
1005
+ typeReference: code `bool`,
1006
+ defaultValue: `${tsType.value === true ? true : false}`,
1007
+ nullableType: false,
1008
+ };
1009
+ case "Number":
1010
+ const [type, value] = findNumericType(tsType);
1011
+ return { typeReference: code `${type}`, defaultValue: `${value}`, nullableType: false };
1012
+ case "Tuple":
1013
+ const defaults = [];
1014
+ const [csharpType, isObject] = coalesceTsTypes(program, tsType.values);
1015
+ if (isObject)
1016
+ return { typeReference: "object[]", defaultValue: undefined, nullableType: false };
1017
+ for (const value of tsType.values) {
1018
+ const { defaultValue: itemDefault } = this.getTypeInfo(program, value);
1019
+ defaults.push(itemDefault);
1020
+ }
1021
+ return {
1022
+ typeReference: code `${csharpType.getTypeReference()}[]`,
1023
+ defaultValue: `[${defaults.join(", ")}]`,
1024
+ nullableType: csharpType.isNullable,
1025
+ };
1026
+ case "Object":
1027
+ return { typeReference: code `object`, defaultValue: undefined, nullableType: false };
1028
+ case "Model":
1029
+ let modelResult;
1030
+ const cachedResult = this.#anonymousModels.get(tsType);
1031
+ if (cachedResult) {
1032
+ return cachedResult;
1033
+ }
1034
+ if (isRecord(tsType)) {
1035
+ modelResult = { typeReference: code `JsonObject`, nullableType: false };
1036
+ }
1037
+ else {
1038
+ modelResult = {
1039
+ typeReference: code `${this.emitter.emitTypeReference(tsType)}`,
1040
+ nullableType: false,
1041
+ };
1042
+ }
1043
+ this.#anonymousModels.set(tsType, modelResult);
1044
+ return modelResult;
1045
+ case "ModelProperty":
1046
+ return this.getTypeInfo(program, tsType.type);
1047
+ case "Enum":
1048
+ return {
1049
+ typeReference: code `${this.emitter.emitTypeReference(tsType)}`,
1050
+ nullableType: false,
1051
+ };
1052
+ case "EnumMember":
1053
+ if (typeof tsType.value === "number") {
1054
+ const stringValue = tsType.value.toString();
1055
+ if (stringValue.includes(".") || stringValue.includes("e"))
1056
+ return { typeReference: "double", defaultValue: stringValue, nullableType: false };
1057
+ return { typeReference: "int", defaultValue: stringValue, nullableType: false };
1058
+ }
1059
+ if (typeof tsType.value === "string") {
1060
+ return { typeReference: "string", defaultValue: tsType.value, nullableType: false };
1061
+ }
1062
+ return { typeReference: code `object`, nullableType: false };
1063
+ case "Union":
1064
+ return this.getUnionInfo(program, tsType);
1065
+ case "UnionVariant":
1066
+ return this.getTypeInfo(program, tsType.type);
1067
+ default:
1068
+ return {
1069
+ typeReference: code `${this.emitter.emitTypeReference(tsType)}`,
1070
+ nullableType: false,
1071
+ };
1072
+ }
1073
+ }
1074
+ getUnionInfo(program, union) {
1075
+ const propResult = getNonNullableTsType(union);
1076
+ if (propResult === undefined) {
1077
+ return {
1078
+ typeReference: code `${this.emitter.emitTypeReference(union)}`,
1079
+ nullableType: [...union.variants.values()].some((v) => isNullType(v.type)),
1080
+ };
1081
+ }
1082
+ const candidate = this.getTypeInfo(program, propResult.type);
1083
+ candidate.nullableType = propResult.nullable;
1084
+ return candidate;
1085
+ }
1086
+ }
1087
+ export function getExplicitBodyParameters(program, httpOperation) {
1088
+ if (httpOperation.parameters.body && httpOperation.parameters.body.bodyKind === "multipart") {
1089
+ return [
1090
+ {
1091
+ name: "reader",
1092
+ callName: "reader",
1093
+ nullable: false,
1094
+ optional: false,
1095
+ typeName: "MultipartReader",
1096
+ isExplicitBody: false,
1097
+ httpParameterKind: "body",
1098
+ operationKind: "BusinessLogic",
1099
+ },
1100
+ ];
1101
+ }
1102
+ return undefined;
1103
+ }
1104
+ export function findNumericType(type) {
1105
+ const stringValue = type.valueAsString;
1106
+ if (stringValue.includes(".") || stringValue.includes("e"))
1107
+ return ["double", stringValue];
1108
+ return ["int", stringValue];
1109
+ }
1110
+ export function coalesceUnionTypes(program, union) {
1111
+ const [result, _] = coalesceTsTypes(program, [...union.variants.values()].flatMap((v) => v.type));
1112
+ return result;
1113
+ }
1114
+ export function getNonNullableTsType(union) {
1115
+ const types = [...union.variants.values()];
1116
+ const nulls = types.flatMap((v) => v.type).filter((t) => isNullType(t));
1117
+ const nonNulls = types.flatMap((v) => v.type).filter((t) => !isNullType(t));
1118
+ if (nonNulls.length === 1)
1119
+ return { type: nonNulls[0], nullable: nulls.length > 0 };
1120
+ return undefined;
1121
+ }
1122
+ export function coalesceTsTypes(program, types) {
1123
+ const defaultValue = [
1124
+ new CSharpType({
1125
+ name: "object",
1126
+ namespace: "System",
1127
+ isBuiltIn: true,
1128
+ isValueType: false,
1129
+ }),
1130
+ true,
1131
+ ];
1132
+ let current = undefined;
1133
+ let nullable = false;
1134
+ for (const type of types) {
1135
+ let candidate = undefined;
1136
+ switch (type.kind) {
1137
+ case "Boolean":
1138
+ candidate = new CSharpType({ name: "bool", namespace: "System", isValueType: true });
1139
+ break;
1140
+ case "StringTemplate":
1141
+ case "String":
1142
+ candidate = new CSharpType({ name: "string", namespace: "System", isValueType: false });
1143
+ break;
1144
+ case "Number":
1145
+ const stringValue = type.valueAsString;
1146
+ if (stringValue.includes(".") || stringValue.includes("e")) {
1147
+ candidate = new CSharpType({
1148
+ name: "double",
1149
+ namespace: "System",
1150
+ isValueType: true,
1151
+ });
1152
+ }
1153
+ else {
1154
+ candidate = new CSharpType({ name: "int", namespace: "System", isValueType: true });
1155
+ }
1156
+ break;
1157
+ case "Union":
1158
+ candidate = coalesceUnionTypes(program, type);
1159
+ break;
1160
+ case "Scalar":
1161
+ candidate = getCSharpTypeForScalar(program, type);
1162
+ break;
1163
+ case "Intrinsic":
1164
+ if (isNullType(type)) {
1165
+ nullable = true;
1166
+ candidate = current;
1167
+ }
1168
+ else {
1169
+ return defaultValue;
1170
+ }
1171
+ break;
1172
+ default:
1173
+ return defaultValue;
1174
+ }
1175
+ current = current ?? candidate;
1176
+ if (current === undefined || (candidate !== undefined && !candidate.equals(current)))
1177
+ return defaultValue;
1178
+ }
1179
+ if (current !== undefined && nullable === true)
1180
+ current.isNullable = true;
1181
+ return current === undefined ? defaultValue : [current, false];
1182
+ }
1183
+ export function isRecord(type) {
1184
+ return type.kind === "Model" && type.name === "Record" && type.indexer !== undefined;
1185
+ }
645
1186
  //# sourceMappingURL=utils.js.map