quicktype 18.0.6 → 19.0.5
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.
- package/README.md +1 -1
- package/dist/{cli/CompressedJSONFromStream.d.ts → CompressedJSONFromStream.d.ts} +1 -1
- package/dist/{cli/CompressedJSONFromStream.js → CompressedJSONFromStream.js} +2 -2
- package/dist/{cli/GraphQLIntrospection.d.ts → GraphQLIntrospection.d.ts} +0 -0
- package/dist/{cli/GraphQLIntrospection.js → GraphQLIntrospection.js} +1 -1
- package/dist/{cli/TypeSource.d.ts → TypeSource.d.ts} +2 -2
- package/dist/{cli/TypeSource.js → TypeSource.js} +0 -0
- package/dist/{cli/URLGrammar.d.ts → URLGrammar.d.ts} +0 -0
- package/dist/{cli/URLGrammar.js → URLGrammar.js} +1 -1
- package/dist/{cli/index.d.ts → index.d.ts} +2 -1
- package/dist/{cli/index.js → index.js} +4 -4
- package/package.json +61 -77
- package/dist/quicktype-core/Annotation.d.ts +0 -8
- package/dist/quicktype-core/Annotation.js +0 -16
- package/dist/quicktype-core/ConvenienceRenderer.d.ts +0 -138
- package/dist/quicktype-core/ConvenienceRenderer.js +0 -668
- package/dist/quicktype-core/DateTime.d.ts +0 -10
- package/dist/quicktype-core/DateTime.js +0 -57
- package/dist/quicktype-core/DeclarationIR.d.ts +0 -14
- package/dist/quicktype-core/DeclarationIR.js +0 -167
- package/dist/quicktype-core/EncodedMarkovChain.d.ts +0 -1
- package/dist/quicktype-core/EncodedMarkovChain.js +0 -4
- package/dist/quicktype-core/GatherNames.d.ts +0 -2
- package/dist/quicktype-core/GatherNames.js +0 -333
- package/dist/quicktype-core/Graph.d.ts +0 -12
- package/dist/quicktype-core/Graph.js +0 -220
- package/dist/quicktype-core/GraphRewriting.d.ts +0 -87
- package/dist/quicktype-core/GraphRewriting.js +0 -421
- package/dist/quicktype-core/MakeTransformations.d.ts +0 -4
- package/dist/quicktype-core/MakeTransformations.js +0 -193
- package/dist/quicktype-core/MarkovChain.d.ts +0 -15
- package/dist/quicktype-core/MarkovChain.js +0 -154
- package/dist/quicktype-core/Messages.d.ts +0 -294
- package/dist/quicktype-core/Messages.js +0 -105
- package/dist/quicktype-core/Naming.d.ts +0 -64
- package/dist/quicktype-core/Naming.js +0 -356
- package/dist/quicktype-core/Renderer.d.ts +0 -50
- package/dist/quicktype-core/Renderer.js +0 -274
- package/dist/quicktype-core/RendererOptions.d.ts +0 -71
- package/dist/quicktype-core/RendererOptions.js +0 -141
- package/dist/quicktype-core/Run.d.ts +0 -174
- package/dist/quicktype-core/Run.js +0 -393
- package/dist/quicktype-core/Source.d.ts +0 -65
- package/dist/quicktype-core/Source.js +0 -204
- package/dist/quicktype-core/TargetLanguage.d.ts +0 -34
- package/dist/quicktype-core/TargetLanguage.js +0 -66
- package/dist/quicktype-core/Transformers.d.ts +0 -209
- package/dist/quicktype-core/Transformers.js +0 -836
- package/dist/quicktype-core/Type.d.ts +0 -206
- package/dist/quicktype-core/Type.js +0 -716
- package/dist/quicktype-core/TypeBuilder.d.ts +0 -61
- package/dist/quicktype-core/TypeBuilder.js +0 -324
- package/dist/quicktype-core/TypeGraph.d.ts +0 -75
- package/dist/quicktype-core/TypeGraph.js +0 -420
- package/dist/quicktype-core/TypeUtils.d.ts +0 -33
- package/dist/quicktype-core/TypeUtils.js +0 -230
- package/dist/quicktype-core/UnifyClasses.d.ts +0 -16
- package/dist/quicktype-core/UnifyClasses.js +0 -159
- package/dist/quicktype-core/UnionBuilder.d.ts +0 -49
- package/dist/quicktype-core/UnionBuilder.js +0 -282
- package/dist/quicktype-core/attributes/AccessorNames.d.ts +0 -18
- package/dist/quicktype-core/attributes/AccessorNames.js +0 -182
- package/dist/quicktype-core/attributes/Constraints.d.ts +0 -38
- package/dist/quicktype-core/attributes/Constraints.js +0 -172
- package/dist/quicktype-core/attributes/Description.d.ts +0 -9
- package/dist/quicktype-core/attributes/Description.js +0 -97
- package/dist/quicktype-core/attributes/EnumValues.d.ts +0 -8
- package/dist/quicktype-core/attributes/EnumValues.js +0 -31
- package/dist/quicktype-core/attributes/StringTypes.d.ts +0 -28
- package/dist/quicktype-core/attributes/StringTypes.js +0 -189
- package/dist/quicktype-core/attributes/TypeAttributes.d.ts +0 -34
- package/dist/quicktype-core/attributes/TypeAttributes.js +0 -119
- package/dist/quicktype-core/attributes/TypeNames.d.ts +0 -46
- package/dist/quicktype-core/attributes/TypeNames.js +0 -274
- package/dist/quicktype-core/attributes/URIAttributes.d.ts +0 -8
- package/dist/quicktype-core/attributes/URIAttributes.js +0 -85
- package/dist/quicktype-core/index.d.ts +0 -48
- package/dist/quicktype-core/index.js +0 -180
- package/dist/quicktype-core/input/CompressedJSON.d.ts +0 -69
- package/dist/quicktype-core/input/CompressedJSON.js +0 -276
- package/dist/quicktype-core/input/FetchingJSONSchemaStore.d.ts +0 -6
- package/dist/quicktype-core/input/FetchingJSONSchemaStore.js +0 -18
- package/dist/quicktype-core/input/Inference.d.ts +0 -22
- package/dist/quicktype-core/input/Inference.js +0 -240
- package/dist/quicktype-core/input/Inputs.d.ts +0 -48
- package/dist/quicktype-core/input/Inputs.js +0 -145
- package/dist/quicktype-core/input/JSONSchemaInput.d.ts +0 -91
- package/dist/quicktype-core/input/JSONSchemaInput.js +0 -1041
- package/dist/quicktype-core/input/JSONSchemaStore.d.ts +0 -8
- package/dist/quicktype-core/input/JSONSchemaStore.js +0 -36
- package/dist/quicktype-core/input/PostmanCollection.d.ts +0 -5
- package/dist/quicktype-core/input/PostmanCollection.js +0 -60
- package/dist/quicktype-core/input/io/NodeIO.d.ts +0 -3
- package/dist/quicktype-core/input/io/NodeIO.js +0 -87
- package/dist/quicktype-core/input/io/get-stream/buffer-stream.d.ts +0 -2
- package/dist/quicktype-core/input/io/get-stream/buffer-stream.js +0 -45
- package/dist/quicktype-core/input/io/get-stream/index.d.ts +0 -9
- package/dist/quicktype-core/input/io/get-stream/index.js +0 -52
- package/dist/quicktype-core/language/All.d.ts +0 -3
- package/dist/quicktype-core/language/All.js +0 -57
- package/dist/quicktype-core/language/CPlusPlus.d.ts +0 -241
- package/dist/quicktype-core/language/CPlusPlus.js +0 -1847
- package/dist/quicktype-core/language/CSharp.d.ts +0 -201
- package/dist/quicktype-core/language/CSharp.js +0 -1850
- package/dist/quicktype-core/language/Crystal.d.ts +0 -37
- package/dist/quicktype-core/language/Crystal.js +0 -337
- package/dist/quicktype-core/language/Dart.d.ts +0 -66
- package/dist/quicktype-core/language/Dart.js +0 -576
- package/dist/quicktype-core/language/Elm.d.ts +0 -58
- package/dist/quicktype-core/language/Elm.js +0 -522
- package/dist/quicktype-core/language/Golang.d.ts +0 -51
- package/dist/quicktype-core/language/Golang.js +0 -460
- package/dist/quicktype-core/language/Haskell.d.ts +0 -56
- package/dist/quicktype-core/language/Haskell.js +0 -411
- package/dist/quicktype-core/language/JSONSchema.d.ts +0 -31
- package/dist/quicktype-core/language/JSONSchema.js +0 -169
- package/dist/quicktype-core/language/Java.d.ts +0 -125
- package/dist/quicktype-core/language/Java.js +0 -1081
- package/dist/quicktype-core/language/JavaScript.d.ts +0 -68
- package/dist/quicktype-core/language/JavaScript.js +0 -435
- package/dist/quicktype-core/language/JavaScriptPropTypes.d.ts +0 -40
- package/dist/quicktype-core/language/JavaScriptPropTypes.js +0 -213
- package/dist/quicktype-core/language/JavaScriptUnicodeMaps.d.ts +0 -2
- package/dist/quicktype-core/language/JavaScriptUnicodeMaps.js +0 -134
- package/dist/quicktype-core/language/Kotlin.d.ts +0 -109
- package/dist/quicktype-core/language/Kotlin.js +0 -832
- package/dist/quicktype-core/language/Objective-C.d.ts +0 -79
- package/dist/quicktype-core/language/Objective-C.js +0 -777
- package/dist/quicktype-core/language/Php.d.ts +0 -80
- package/dist/quicktype-core/language/Php.js +0 -702
- package/dist/quicktype-core/language/Pike.d.ts +0 -37
- package/dist/quicktype-core/language/Pike.js +0 -276
- package/dist/quicktype-core/language/Python.d.ts +0 -107
- package/dist/quicktype-core/language/Python.js +0 -969
- package/dist/quicktype-core/language/Rust.d.ts +0 -56
- package/dist/quicktype-core/language/Rust.js +0 -309
- package/dist/quicktype-core/language/Swift.d.ts +0 -96
- package/dist/quicktype-core/language/Swift.js +0 -1211
- package/dist/quicktype-core/language/TypeScriptFlow.d.ts +0 -77
- package/dist/quicktype-core/language/TypeScriptFlow.js +0 -286
- package/dist/quicktype-core/language/ruby/index.d.ts +0 -52
- package/dist/quicktype-core/language/ruby/index.js +0 -557
- package/dist/quicktype-core/language/ruby/keywords.d.ts +0 -3
- package/dist/quicktype-core/language/ruby/keywords.js +0 -358
- package/dist/quicktype-core/rewrites/CombineClasses.d.ts +0 -3
- package/dist/quicktype-core/rewrites/CombineClasses.js +0 -125
- package/dist/quicktype-core/rewrites/ExpandStrings.d.ts +0 -4
- package/dist/quicktype-core/rewrites/ExpandStrings.js +0 -143
- package/dist/quicktype-core/rewrites/FlattenStrings.d.ts +0 -3
- package/dist/quicktype-core/rewrites/FlattenStrings.js +0 -45
- package/dist/quicktype-core/rewrites/FlattenUnions.d.ts +0 -3
- package/dist/quicktype-core/rewrites/FlattenUnions.js +0 -47
- package/dist/quicktype-core/rewrites/InferMaps.d.ts +0 -3
- package/dist/quicktype-core/rewrites/InferMaps.js +0 -117
- package/dist/quicktype-core/rewrites/ReplaceObjectType.d.ts +0 -3
- package/dist/quicktype-core/rewrites/ReplaceObjectType.js +0 -60
- package/dist/quicktype-core/rewrites/ResolveIntersections.d.ts +0 -3
- package/dist/quicktype-core/rewrites/ResolveIntersections.js +0 -244
- package/dist/quicktype-core/support/Acronyms.d.ts +0 -10
- package/dist/quicktype-core/support/Acronyms.js +0 -1128
- package/dist/quicktype-core/support/Chance.d.ts +0 -38
- package/dist/quicktype-core/support/Chance.js +0 -2146
- package/dist/quicktype-core/support/Converters.d.ts +0 -6
- package/dist/quicktype-core/support/Converters.js +0 -16
- package/dist/quicktype-core/support/Strings.d.ts +0 -44
- package/dist/quicktype-core/support/Strings.js +0 -525
- package/dist/quicktype-core/support/Support.d.ts +0 -29
- package/dist/quicktype-core/support/Support.js +0 -162
- package/dist/quicktype-graphql-input/GraphQLSchema.d.ts +0 -645
- package/dist/quicktype-graphql-input/GraphQLSchema.js +0 -39
- package/dist/quicktype-graphql-input/index.d.ts +0 -17
- package/dist/quicktype-graphql-input/index.js +0 -407
- package/dist/quicktype-typescript-input/index.d.ts +0 -2
- package/dist/quicktype-typescript-input/index.js +0 -98
|
@@ -1,1850 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SystemTextJsonCSharpRenderer = exports.systemTextJsonCSharpOptions = exports.NewtonsoftCSharpRenderer = exports.newtonsoftCSharpOptions = exports.CSharpRenderer = exports.CSharpTargetLanguage = exports.cSharpOptions = exports.AccessModifier = exports.Framework = void 0;
|
|
4
|
-
const collection_utils_1 = require("collection-utils");
|
|
5
|
-
const Type_1 = require("../Type");
|
|
6
|
-
const TypeUtils_1 = require("../TypeUtils");
|
|
7
|
-
const Source_1 = require("../Source");
|
|
8
|
-
const Strings_1 = require("../support/Strings");
|
|
9
|
-
const Support_1 = require("../support/Support");
|
|
10
|
-
const Naming_1 = require("../Naming");
|
|
11
|
-
const ConvenienceRenderer_1 = require("../ConvenienceRenderer");
|
|
12
|
-
const TargetLanguage_1 = require("../TargetLanguage");
|
|
13
|
-
const RendererOptions_1 = require("../RendererOptions");
|
|
14
|
-
const Annotation_1 = require("../Annotation");
|
|
15
|
-
const Transformers_1 = require("../Transformers");
|
|
16
|
-
const Constraints_1 = require("../attributes/Constraints");
|
|
17
|
-
var Framework;
|
|
18
|
-
(function (Framework) {
|
|
19
|
-
Framework[Framework["Newtonsoft"] = 0] = "Newtonsoft";
|
|
20
|
-
Framework[Framework["SystemTextJson"] = 1] = "SystemTextJson";
|
|
21
|
-
})(Framework = exports.Framework || (exports.Framework = {}));
|
|
22
|
-
const unicode = require("unicode-properties");
|
|
23
|
-
var AccessModifier;
|
|
24
|
-
(function (AccessModifier) {
|
|
25
|
-
AccessModifier[AccessModifier["None"] = 0] = "None";
|
|
26
|
-
AccessModifier[AccessModifier["Public"] = 1] = "Public";
|
|
27
|
-
AccessModifier[AccessModifier["Internal"] = 2] = "Internal";
|
|
28
|
-
})(AccessModifier = exports.AccessModifier || (exports.AccessModifier = {}));
|
|
29
|
-
function noFollow(t) {
|
|
30
|
-
return t;
|
|
31
|
-
}
|
|
32
|
-
function needTransformerForType(t) {
|
|
33
|
-
if (t instanceof Type_1.UnionType) {
|
|
34
|
-
const maybeNullable = (0, TypeUtils_1.nullableFromUnion)(t);
|
|
35
|
-
if (maybeNullable === null)
|
|
36
|
-
return "automatic";
|
|
37
|
-
if (needTransformerForType(maybeNullable) === "manual")
|
|
38
|
-
return "nullable";
|
|
39
|
-
return "none";
|
|
40
|
-
}
|
|
41
|
-
if (t instanceof Type_1.ArrayType) {
|
|
42
|
-
const itemsNeed = needTransformerForType(t.items);
|
|
43
|
-
if (itemsNeed === "manual" || itemsNeed === "nullable")
|
|
44
|
-
return "automatic";
|
|
45
|
-
return "none";
|
|
46
|
-
}
|
|
47
|
-
if (t instanceof Type_1.EnumType)
|
|
48
|
-
return "automatic";
|
|
49
|
-
if (t.kind === "double")
|
|
50
|
-
return (0, Constraints_1.minMaxValueForType)(t) !== undefined ? "manual" : "none";
|
|
51
|
-
if (t.kind === "integer-string" || t.kind === "bool-string")
|
|
52
|
-
return "manual";
|
|
53
|
-
if (t.kind === "string") {
|
|
54
|
-
return (0, Constraints_1.minMaxLengthForType)(t) !== undefined ? "manual" : "none";
|
|
55
|
-
}
|
|
56
|
-
return "none";
|
|
57
|
-
}
|
|
58
|
-
function alwaysApplyTransformation(xf) {
|
|
59
|
-
const t = xf.targetType;
|
|
60
|
-
if (t instanceof Type_1.EnumType)
|
|
61
|
-
return true;
|
|
62
|
-
if (t instanceof Type_1.UnionType)
|
|
63
|
-
return (0, TypeUtils_1.nullableFromUnion)(t) === null;
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* The C# type for a given transformed string type.
|
|
68
|
-
*/
|
|
69
|
-
function csTypeForTransformedStringType(t) {
|
|
70
|
-
switch (t.kind) {
|
|
71
|
-
case "date-time":
|
|
72
|
-
return "DateTimeOffset";
|
|
73
|
-
case "uuid":
|
|
74
|
-
return "Guid";
|
|
75
|
-
case "uri":
|
|
76
|
-
return "Uri";
|
|
77
|
-
default:
|
|
78
|
-
return (0, Support_1.panic)(`Transformed string type ${t.kind} not supported`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
exports.cSharpOptions = {
|
|
82
|
-
framework: new RendererOptions_1.EnumOption("framework", "Serialization framework", [
|
|
83
|
-
["NewtonSoft", Framework.Newtonsoft],
|
|
84
|
-
["SystemTextJson", Framework.SystemTextJson]
|
|
85
|
-
], "NewtonSoft"),
|
|
86
|
-
useList: new RendererOptions_1.EnumOption("array-type", "Use T[] or List<T>", [
|
|
87
|
-
["array", false],
|
|
88
|
-
["list", true]
|
|
89
|
-
]),
|
|
90
|
-
dense: new RendererOptions_1.EnumOption("density", "Property density", [
|
|
91
|
-
["normal", false],
|
|
92
|
-
["dense", true]
|
|
93
|
-
], "normal", "secondary"),
|
|
94
|
-
// FIXME: Do this via a configurable named eventually.
|
|
95
|
-
namespace: new RendererOptions_1.StringOption("namespace", "Generated namespace", "NAME", "QuickType"),
|
|
96
|
-
version: new RendererOptions_1.EnumOption("csharp-version", "C# version", [
|
|
97
|
-
["5", 5],
|
|
98
|
-
["6", 6]
|
|
99
|
-
], "6", "secondary"),
|
|
100
|
-
virtual: new RendererOptions_1.BooleanOption("virtual", "Generate virtual properties", false),
|
|
101
|
-
typeForAny: new RendererOptions_1.EnumOption("any-type", 'Type to use for "any"', [
|
|
102
|
-
["object", "object"],
|
|
103
|
-
["dynamic", "dynamic"]
|
|
104
|
-
], "object", "secondary"),
|
|
105
|
-
useDecimal: new RendererOptions_1.EnumOption("number-type", "Type to use for numbers", [
|
|
106
|
-
["double", false],
|
|
107
|
-
["decimal", true]
|
|
108
|
-
], "double", "secondary"),
|
|
109
|
-
features: new RendererOptions_1.EnumOption("features", "Output features", [
|
|
110
|
-
["complete", { namespaces: true, helpers: true, attributes: true }],
|
|
111
|
-
["attributes-only", { namespaces: true, helpers: false, attributes: true }],
|
|
112
|
-
["just-types-and-namespace", { namespaces: true, helpers: false, attributes: false }],
|
|
113
|
-
["just-types", { namespaces: true, helpers: false, attributes: false }]
|
|
114
|
-
]),
|
|
115
|
-
baseclass: new RendererOptions_1.EnumOption("base-class", "Base class", [
|
|
116
|
-
["EntityData", "EntityData"],
|
|
117
|
-
["Object", undefined]
|
|
118
|
-
], "Object", "secondary"),
|
|
119
|
-
checkRequired: new RendererOptions_1.BooleanOption("check-required", "Fail if required properties are missing", false)
|
|
120
|
-
};
|
|
121
|
-
class CSharpTargetLanguage extends TargetLanguage_1.TargetLanguage {
|
|
122
|
-
constructor() {
|
|
123
|
-
super("C#", ["cs", "csharp"], "cs");
|
|
124
|
-
}
|
|
125
|
-
getOptions() {
|
|
126
|
-
return [
|
|
127
|
-
exports.cSharpOptions.framework,
|
|
128
|
-
exports.cSharpOptions.namespace,
|
|
129
|
-
exports.cSharpOptions.version,
|
|
130
|
-
exports.cSharpOptions.dense,
|
|
131
|
-
exports.cSharpOptions.useList,
|
|
132
|
-
exports.cSharpOptions.useDecimal,
|
|
133
|
-
exports.cSharpOptions.typeForAny,
|
|
134
|
-
exports.cSharpOptions.virtual,
|
|
135
|
-
exports.cSharpOptions.features,
|
|
136
|
-
exports.cSharpOptions.baseclass,
|
|
137
|
-
exports.cSharpOptions.checkRequired,
|
|
138
|
-
];
|
|
139
|
-
}
|
|
140
|
-
get stringTypeMapping() {
|
|
141
|
-
const mapping = new Map();
|
|
142
|
-
mapping.set("date", "date-time");
|
|
143
|
-
mapping.set("time", "date-time");
|
|
144
|
-
mapping.set("date-time", "date-time");
|
|
145
|
-
mapping.set("uuid", "uuid");
|
|
146
|
-
mapping.set("uri", "uri");
|
|
147
|
-
mapping.set("integer-string", "integer-string");
|
|
148
|
-
mapping.set("bool-string", "bool-string");
|
|
149
|
-
return mapping;
|
|
150
|
-
}
|
|
151
|
-
get supportsUnionsWithBothNumberTypes() {
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
get supportsOptionalClassProperties() {
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
needsTransformerForType(t) {
|
|
158
|
-
const need = needTransformerForType(t);
|
|
159
|
-
return need !== "none" && need !== "nullable";
|
|
160
|
-
}
|
|
161
|
-
makeRenderer(renderContext, untypedOptionValues) {
|
|
162
|
-
const options = (0, RendererOptions_1.getOptionValues)(exports.cSharpOptions, untypedOptionValues);
|
|
163
|
-
switch (options.framework) {
|
|
164
|
-
case Framework.Newtonsoft:
|
|
165
|
-
return new NewtonsoftCSharpRenderer(this, renderContext, (0, RendererOptions_1.getOptionValues)(exports.newtonsoftCSharpOptions, untypedOptionValues));
|
|
166
|
-
case Framework.SystemTextJson:
|
|
167
|
-
return new SystemTextJsonCSharpRenderer(this, renderContext, (0, RendererOptions_1.getOptionValues)(exports.systemTextJsonCSharpOptions, untypedOptionValues));
|
|
168
|
-
default:
|
|
169
|
-
return (0, Support_1.assertNever)(options.framework);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
exports.CSharpTargetLanguage = CSharpTargetLanguage;
|
|
174
|
-
const namingFunction = (0, Naming_1.funPrefixNamer)("namer", csNameStyle);
|
|
175
|
-
// FIXME: Make a Named?
|
|
176
|
-
const denseJsonPropertyName = "J";
|
|
177
|
-
const denseRequiredEnumName = "R";
|
|
178
|
-
const denseNullValueHandlingEnumName = "N";
|
|
179
|
-
function isStartCharacter(utf16Unit) {
|
|
180
|
-
if (unicode.isAlphabetic(utf16Unit)) {
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
return utf16Unit === 0x5f; // underscore
|
|
184
|
-
}
|
|
185
|
-
function isPartCharacter(utf16Unit) {
|
|
186
|
-
const category = unicode.getCategory(utf16Unit);
|
|
187
|
-
if (["Nd", "Pc", "Mn", "Mc"].indexOf(category) >= 0) {
|
|
188
|
-
return true;
|
|
189
|
-
}
|
|
190
|
-
return isStartCharacter(utf16Unit);
|
|
191
|
-
}
|
|
192
|
-
const legalizeName = (0, Strings_1.utf16LegalizeCharacters)(isPartCharacter);
|
|
193
|
-
function csNameStyle(original) {
|
|
194
|
-
const words = (0, Strings_1.splitIntoWords)(original);
|
|
195
|
-
return (0, Strings_1.combineWords)(words, legalizeName, Strings_1.firstUpperWordStyle, Strings_1.firstUpperWordStyle, Strings_1.firstUpperWordStyle, Strings_1.firstUpperWordStyle, "", isStartCharacter);
|
|
196
|
-
}
|
|
197
|
-
function isValueType(t) {
|
|
198
|
-
if (t instanceof Type_1.UnionType) {
|
|
199
|
-
return (0, TypeUtils_1.nullableFromUnion)(t) === null;
|
|
200
|
-
}
|
|
201
|
-
return ["integer", "double", "bool", "enum", "date-time", "uuid"].indexOf(t.kind) >= 0;
|
|
202
|
-
}
|
|
203
|
-
class CSharpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
204
|
-
_csOptions;
|
|
205
|
-
constructor(targetLanguage, renderContext, _csOptions) {
|
|
206
|
-
super(targetLanguage, renderContext);
|
|
207
|
-
this._csOptions = _csOptions;
|
|
208
|
-
}
|
|
209
|
-
forbiddenNamesForGlobalNamespace() {
|
|
210
|
-
return ["QuickType", "Type", "System", "Console", "Exception", "DateTimeOffset", "Guid", "Uri"];
|
|
211
|
-
}
|
|
212
|
-
forbiddenForObjectProperties(_, classNamed) {
|
|
213
|
-
return {
|
|
214
|
-
names: [
|
|
215
|
-
classNamed,
|
|
216
|
-
"ToString",
|
|
217
|
-
"GetHashCode",
|
|
218
|
-
"Finalize",
|
|
219
|
-
"Equals",
|
|
220
|
-
"GetType",
|
|
221
|
-
"MemberwiseClone",
|
|
222
|
-
"ReferenceEquals"
|
|
223
|
-
],
|
|
224
|
-
includeGlobalForbidden: false
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
forbiddenForUnionMembers(_, unionNamed) {
|
|
228
|
-
return { names: [unionNamed], includeGlobalForbidden: true };
|
|
229
|
-
}
|
|
230
|
-
makeNamedTypeNamer() {
|
|
231
|
-
return namingFunction;
|
|
232
|
-
}
|
|
233
|
-
namerForObjectProperty() {
|
|
234
|
-
return namingFunction;
|
|
235
|
-
}
|
|
236
|
-
makeUnionMemberNamer() {
|
|
237
|
-
return namingFunction;
|
|
238
|
-
}
|
|
239
|
-
makeEnumCaseNamer() {
|
|
240
|
-
return namingFunction;
|
|
241
|
-
}
|
|
242
|
-
unionNeedsName(u) {
|
|
243
|
-
return (0, TypeUtils_1.nullableFromUnion)(u) === null;
|
|
244
|
-
}
|
|
245
|
-
namedTypeToNameForTopLevel(type) {
|
|
246
|
-
// If the top-level type doesn't contain any classes or unions
|
|
247
|
-
// we have to define a class just for the `FromJson` method, in
|
|
248
|
-
// emitFromJsonForTopLevel.
|
|
249
|
-
return (0, TypeUtils_1.directlyReachableSingleNamedType)(type);
|
|
250
|
-
}
|
|
251
|
-
emitBlock(f, semicolon = false) {
|
|
252
|
-
this.emitLine("{");
|
|
253
|
-
this.indent(f);
|
|
254
|
-
this.emitLine("}", semicolon ? ";" : "");
|
|
255
|
-
}
|
|
256
|
-
get doubleType() {
|
|
257
|
-
return this._csOptions.useDecimal ? "decimal" : "double";
|
|
258
|
-
}
|
|
259
|
-
csType(t, follow = Transformers_1.followTargetType, withIssues = false) {
|
|
260
|
-
const actualType = follow(t);
|
|
261
|
-
return (0, TypeUtils_1.matchType)(actualType, _anyType => (0, Source_1.maybeAnnotated)(withIssues, Annotation_1.anyTypeIssueAnnotation, this._csOptions.typeForAny), _nullType => (0, Source_1.maybeAnnotated)(withIssues, Annotation_1.nullTypeIssueAnnotation, this._csOptions.typeForAny), _boolType => "bool", _integerType => "long", _doubleType => this.doubleType, _stringType => "string", arrayType => {
|
|
262
|
-
const itemsType = this.csType(arrayType.items, follow, withIssues);
|
|
263
|
-
if (this._csOptions.useList) {
|
|
264
|
-
return ["System.Collections.Generic.List<", itemsType, ">"];
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
return [itemsType, "[]"];
|
|
268
|
-
}
|
|
269
|
-
}, classType => this.nameForNamedType(classType), mapType => [
|
|
270
|
-
"System.Collections.Generic.Dictionary<string, ",
|
|
271
|
-
this.csType(mapType.values, follow, withIssues),
|
|
272
|
-
">"
|
|
273
|
-
], enumType => this.nameForNamedType(enumType), unionType => {
|
|
274
|
-
const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
|
|
275
|
-
if (nullable !== null)
|
|
276
|
-
return this.nullableCSType(nullable, noFollow);
|
|
277
|
-
return this.nameForNamedType(unionType);
|
|
278
|
-
}, transformedStringType => csTypeForTransformedStringType(transformedStringType));
|
|
279
|
-
}
|
|
280
|
-
nullableCSType(t, follow = Transformers_1.followTargetType, withIssues = false) {
|
|
281
|
-
t = (0, Transformers_1.followTargetType)(t);
|
|
282
|
-
const csType = this.csType(t, follow, withIssues);
|
|
283
|
-
if (isValueType(t)) {
|
|
284
|
-
return [csType, "?"];
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
return csType;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
baseclassForType(_t) {
|
|
291
|
-
return undefined;
|
|
292
|
-
}
|
|
293
|
-
emitType(description, accessModifier, declaration, name, baseclass, emitter) {
|
|
294
|
-
switch (accessModifier) {
|
|
295
|
-
case AccessModifier.Public:
|
|
296
|
-
declaration = ["public ", declaration];
|
|
297
|
-
break;
|
|
298
|
-
case AccessModifier.Internal:
|
|
299
|
-
declaration = ["internal ", declaration];
|
|
300
|
-
break;
|
|
301
|
-
default:
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
this.emitDescription(description);
|
|
305
|
-
if (baseclass === undefined) {
|
|
306
|
-
this.emitLine(declaration, " ", name);
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
this.emitLine(declaration, " ", name, " : ", baseclass);
|
|
310
|
-
}
|
|
311
|
-
this.emitBlock(emitter);
|
|
312
|
-
}
|
|
313
|
-
attributesForProperty(_property, _name, _c, _jsonName) {
|
|
314
|
-
return undefined;
|
|
315
|
-
}
|
|
316
|
-
propertyDefinition(property, name, _c, _jsonName) {
|
|
317
|
-
const t = property.type;
|
|
318
|
-
const csType = property.isOptional
|
|
319
|
-
? this.nullableCSType(t, Transformers_1.followTargetType, true)
|
|
320
|
-
: this.csType(t, Transformers_1.followTargetType, true);
|
|
321
|
-
const propertyArray = ["public "];
|
|
322
|
-
if (this._csOptions.virtual)
|
|
323
|
-
propertyArray.push("virtual ");
|
|
324
|
-
return [...propertyArray, csType, " ", name, " { get; set; }"];
|
|
325
|
-
}
|
|
326
|
-
emitDescriptionBlock(lines) {
|
|
327
|
-
const start = "/// <summary>";
|
|
328
|
-
if (this._csOptions.dense) {
|
|
329
|
-
this.emitLine(start, lines.join("; "), "</summary>");
|
|
330
|
-
}
|
|
331
|
-
else {
|
|
332
|
-
this.emitCommentLines(lines, "/// ", start, "/// </summary>");
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
blankLinesBetweenAttributes() {
|
|
336
|
-
return false;
|
|
337
|
-
}
|
|
338
|
-
emitClassDefinition(c, className) {
|
|
339
|
-
this.emitType(this.descriptionForType(c), AccessModifier.Public, "partial class", className, this.baseclassForType(c), () => {
|
|
340
|
-
if (c.getProperties().size === 0)
|
|
341
|
-
return;
|
|
342
|
-
const blankLines = this.blankLinesBetweenAttributes() ? "interposing" : "none";
|
|
343
|
-
let columns = [];
|
|
344
|
-
let isFirstProperty = true;
|
|
345
|
-
let previousDescription = undefined;
|
|
346
|
-
this.forEachClassProperty(c, blankLines, (name, jsonName, p) => {
|
|
347
|
-
const attributes = this.attributesForProperty(p, name, c, jsonName);
|
|
348
|
-
const description = this.descriptionForClassProperty(c, jsonName);
|
|
349
|
-
const property = this.propertyDefinition(p, name, c, jsonName);
|
|
350
|
-
if (attributes === undefined) {
|
|
351
|
-
if (
|
|
352
|
-
// Descriptions should be preceded by an empty line
|
|
353
|
-
(!isFirstProperty && description !== undefined) ||
|
|
354
|
-
// If the previous property has a description, leave an empty line
|
|
355
|
-
previousDescription !== undefined) {
|
|
356
|
-
this.ensureBlankLine();
|
|
357
|
-
}
|
|
358
|
-
this.emitDescription(description);
|
|
359
|
-
this.emitLine(property);
|
|
360
|
-
}
|
|
361
|
-
else if (this._csOptions.dense && attributes.length > 0) {
|
|
362
|
-
const comment = description === undefined ? "" : ` // ${description.join("; ")}`;
|
|
363
|
-
columns.push([attributes, " ", property, comment]);
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
this.emitDescription(description);
|
|
367
|
-
for (const attribute of attributes) {
|
|
368
|
-
this.emitLine(attribute);
|
|
369
|
-
}
|
|
370
|
-
this.emitLine(property);
|
|
371
|
-
}
|
|
372
|
-
isFirstProperty = false;
|
|
373
|
-
previousDescription = description;
|
|
374
|
-
});
|
|
375
|
-
if (columns.length > 0) {
|
|
376
|
-
this.emitTable(columns);
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
emitUnionDefinition(u, unionName) {
|
|
381
|
-
const nonNulls = (0, TypeUtils_1.removeNullFromUnion)(u, true)[1];
|
|
382
|
-
this.emitType(this.descriptionForType(u), AccessModifier.Public, "partial struct", unionName, this.baseclassForType(u), () => {
|
|
383
|
-
this.forEachUnionMember(u, nonNulls, "none", null, (fieldName, t) => {
|
|
384
|
-
const csType = this.nullableCSType(t);
|
|
385
|
-
this.emitLine("public ", csType, " ", fieldName, ";");
|
|
386
|
-
});
|
|
387
|
-
this.ensureBlankLine();
|
|
388
|
-
const nullTests = Array.from(nonNulls).map(t => [
|
|
389
|
-
this.nameForUnionMember(u, t),
|
|
390
|
-
" == null"
|
|
391
|
-
]);
|
|
392
|
-
this.ensureBlankLine();
|
|
393
|
-
this.forEachUnionMember(u, nonNulls, "none", null, (fieldName, t) => {
|
|
394
|
-
const csType = this.csType(t);
|
|
395
|
-
this.emitExpressionMember(["public static implicit operator ", unionName, "(", csType, " ", fieldName, ")"], ["new ", unionName, " { ", fieldName, " = ", fieldName, " }"]);
|
|
396
|
-
});
|
|
397
|
-
if (u.findMember("null") === undefined)
|
|
398
|
-
return;
|
|
399
|
-
this.emitExpressionMember("public bool IsNull", (0, collection_utils_1.arrayIntercalate)(" && ", nullTests), true);
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
emitEnumDefinition(e, enumName) {
|
|
403
|
-
const caseNames = [];
|
|
404
|
-
this.forEachEnumCase(e, "none", name => {
|
|
405
|
-
if (caseNames.length > 0)
|
|
406
|
-
caseNames.push(", ");
|
|
407
|
-
caseNames.push(name);
|
|
408
|
-
});
|
|
409
|
-
this.emitDescription(this.descriptionForType(e));
|
|
410
|
-
this.emitLine("public enum ", enumName, " { ", caseNames, " };");
|
|
411
|
-
}
|
|
412
|
-
emitExpressionMember(declare, define, isProperty = false) {
|
|
413
|
-
if (this._csOptions.version === 5) {
|
|
414
|
-
this.emitLine(declare);
|
|
415
|
-
this.emitBlock(() => {
|
|
416
|
-
const stmt = ["return ", define, ";"];
|
|
417
|
-
if (isProperty) {
|
|
418
|
-
this.emitLine("get");
|
|
419
|
-
this.emitBlock(() => this.emitLine(stmt));
|
|
420
|
-
}
|
|
421
|
-
else {
|
|
422
|
-
this.emitLine(stmt);
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
else {
|
|
427
|
-
this.emitLine(declare, " => ", define, ";");
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
emitTypeSwitch(types, condition, withBlock, withReturn, f) {
|
|
431
|
-
(0, Support_1.assert)(!withReturn || withBlock, "Can only have return with block");
|
|
432
|
-
for (const t of types) {
|
|
433
|
-
this.emitLine("if (", condition(t), ")");
|
|
434
|
-
if (withBlock) {
|
|
435
|
-
this.emitBlock(() => {
|
|
436
|
-
f(t);
|
|
437
|
-
if (withReturn) {
|
|
438
|
-
this.emitLine("return;");
|
|
439
|
-
}
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
else {
|
|
443
|
-
this.indent(() => f(t));
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
emitUsing(ns) {
|
|
448
|
-
this.emitLine("using ", ns, ";");
|
|
449
|
-
}
|
|
450
|
-
emitUsings() {
|
|
451
|
-
for (const ns of ["System", "System.Collections.Generic"]) {
|
|
452
|
-
this.emitUsing(ns);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
emitRequiredHelpers() {
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
emitTypesAndSupport() {
|
|
459
|
-
this.forEachObject("leading-and-interposing", (c, name) => this.emitClassDefinition(c, name));
|
|
460
|
-
this.forEachEnum("leading-and-interposing", (e, name) => this.emitEnumDefinition(e, name));
|
|
461
|
-
this.forEachUnion("leading-and-interposing", (u, name) => this.emitUnionDefinition(u, name));
|
|
462
|
-
this.emitRequiredHelpers();
|
|
463
|
-
}
|
|
464
|
-
emitDefaultLeadingComments() {
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
emitDefaultFollowingComments() {
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
needNamespace() {
|
|
471
|
-
return true;
|
|
472
|
-
}
|
|
473
|
-
emitSourceStructure() {
|
|
474
|
-
if (this.leadingComments !== undefined) {
|
|
475
|
-
this.emitCommentLines(this.leadingComments);
|
|
476
|
-
}
|
|
477
|
-
else {
|
|
478
|
-
this.emitDefaultLeadingComments();
|
|
479
|
-
}
|
|
480
|
-
this.ensureBlankLine();
|
|
481
|
-
if (this.needNamespace()) {
|
|
482
|
-
this.emitLine("namespace ", this._csOptions.namespace);
|
|
483
|
-
this.emitBlock(() => {
|
|
484
|
-
this.emitUsings();
|
|
485
|
-
this.emitTypesAndSupport();
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
489
|
-
this.emitUsings();
|
|
490
|
-
this.emitTypesAndSupport();
|
|
491
|
-
}
|
|
492
|
-
this.emitDefaultFollowingComments();
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
exports.CSharpRenderer = CSharpRenderer;
|
|
496
|
-
exports.newtonsoftCSharpOptions = Object.assign({}, exports.cSharpOptions, {});
|
|
497
|
-
class NewtonsoftCSharpRenderer extends CSharpRenderer {
|
|
498
|
-
_options;
|
|
499
|
-
_enumExtensionsNames = new Map();
|
|
500
|
-
_needHelpers;
|
|
501
|
-
_needAttributes;
|
|
502
|
-
_needNamespaces;
|
|
503
|
-
constructor(targetLanguage, renderContext, _options) {
|
|
504
|
-
super(targetLanguage, renderContext, _options);
|
|
505
|
-
this._options = _options;
|
|
506
|
-
this._needHelpers = _options.features.helpers;
|
|
507
|
-
this._needAttributes = _options.features.attributes;
|
|
508
|
-
this._needNamespaces = _options.features.namespaces;
|
|
509
|
-
}
|
|
510
|
-
forbiddenNamesForGlobalNamespace() {
|
|
511
|
-
const forbidden = [
|
|
512
|
-
"Converter",
|
|
513
|
-
"JsonConverter",
|
|
514
|
-
"JsonSerializer",
|
|
515
|
-
"JsonWriter",
|
|
516
|
-
"JsonToken",
|
|
517
|
-
"Serialize",
|
|
518
|
-
"Newtonsoft",
|
|
519
|
-
"MetadataPropertyHandling",
|
|
520
|
-
"DateParseHandling",
|
|
521
|
-
"FromJson",
|
|
522
|
-
"Required"
|
|
523
|
-
];
|
|
524
|
-
if (this._options.dense) {
|
|
525
|
-
forbidden.push("J", "R", "N");
|
|
526
|
-
}
|
|
527
|
-
if (this._options.baseclass !== undefined) {
|
|
528
|
-
forbidden.push(this._options.baseclass);
|
|
529
|
-
}
|
|
530
|
-
return super.forbiddenNamesForGlobalNamespace().concat(forbidden);
|
|
531
|
-
}
|
|
532
|
-
forbiddenForObjectProperties(c, className) {
|
|
533
|
-
const result = super.forbiddenForObjectProperties(c, className);
|
|
534
|
-
result.names = result.names.concat(["ToJson", "FromJson", "Required"]);
|
|
535
|
-
return result;
|
|
536
|
-
}
|
|
537
|
-
makeNameForTransformation(xf, typeName) {
|
|
538
|
-
if (typeName === undefined) {
|
|
539
|
-
let xfer = xf.transformer;
|
|
540
|
-
if (xfer instanceof Transformers_1.DecodingTransformer && xfer.consumer !== undefined) {
|
|
541
|
-
xfer = xfer.consumer;
|
|
542
|
-
}
|
|
543
|
-
return new Naming_1.SimpleName([`${xfer.kind}_converter`], namingFunction, ConvenienceRenderer_1.inferredNameOrder + 30);
|
|
544
|
-
}
|
|
545
|
-
return new Naming_1.DependencyName(namingFunction, typeName.order + 30, lookup => `${lookup(typeName)}_converter`);
|
|
546
|
-
}
|
|
547
|
-
makeNamedTypeDependencyNames(t, name) {
|
|
548
|
-
if (!(t instanceof Type_1.EnumType))
|
|
549
|
-
return [];
|
|
550
|
-
const extensionsName = new Naming_1.DependencyName(namingFunction, name.order + 30, lookup => `${lookup(name)}_extensions`);
|
|
551
|
-
this._enumExtensionsNames.set(name, extensionsName);
|
|
552
|
-
return [extensionsName];
|
|
553
|
-
}
|
|
554
|
-
emitUsings() {
|
|
555
|
-
// FIXME: We need System.Collections.Generic whenever we have maps or use List.
|
|
556
|
-
if (!this._needAttributes && !this._needHelpers)
|
|
557
|
-
return;
|
|
558
|
-
super.emitUsings();
|
|
559
|
-
this.ensureBlankLine();
|
|
560
|
-
for (const ns of ["System.Globalization", "Newtonsoft.Json", "Newtonsoft.Json.Converters"]) {
|
|
561
|
-
this.emitUsing(ns);
|
|
562
|
-
}
|
|
563
|
-
if (this._options.dense) {
|
|
564
|
-
this.emitUsing([denseJsonPropertyName, " = Newtonsoft.Json.JsonPropertyAttribute"]);
|
|
565
|
-
this.emitUsing([denseRequiredEnumName, " = Newtonsoft.Json.Required"]);
|
|
566
|
-
this.emitUsing([denseNullValueHandlingEnumName, " = Newtonsoft.Json.NullValueHandling"]);
|
|
567
|
-
}
|
|
568
|
-
if (this._options.baseclass === "EntityData") {
|
|
569
|
-
this.emitUsing("Microsoft.Azure.Mobile.Server");
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
baseclassForType(_t) {
|
|
573
|
-
return this._options.baseclass;
|
|
574
|
-
}
|
|
575
|
-
emitDefaultLeadingComments() {
|
|
576
|
-
if (!this._needHelpers)
|
|
577
|
-
return;
|
|
578
|
-
this.emitLine("// <auto-generated />");
|
|
579
|
-
this.emitLine("//");
|
|
580
|
-
this.emitLine("// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do", this.topLevels.size === 1 ? "" : " one of these", ":");
|
|
581
|
-
this.emitLine("//");
|
|
582
|
-
this.emitLine("// using ", this._options.namespace, ";");
|
|
583
|
-
this.emitLine("//");
|
|
584
|
-
this.forEachTopLevel("none", (t, topLevelName) => {
|
|
585
|
-
let rhs;
|
|
586
|
-
if (t instanceof Type_1.EnumType) {
|
|
587
|
-
rhs = ["JsonConvert.DeserializeObject<", topLevelName, ">(jsonString)"];
|
|
588
|
-
}
|
|
589
|
-
else {
|
|
590
|
-
rhs = [topLevelName, ".FromJson(jsonString)"];
|
|
591
|
-
}
|
|
592
|
-
this.emitLine("// var ", (0, Source_1.modifySource)(Strings_1.camelCase, topLevelName), " = ", rhs, ";");
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
converterForType(t) {
|
|
596
|
-
let xf = (0, Transformers_1.transformationForType)(t);
|
|
597
|
-
if (xf === undefined && t instanceof Type_1.UnionType) {
|
|
598
|
-
const maybeNullable = (0, TypeUtils_1.nullableFromUnion)(t);
|
|
599
|
-
if (maybeNullable !== null) {
|
|
600
|
-
t = maybeNullable;
|
|
601
|
-
xf = (0, Transformers_1.transformationForType)(t);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
if (xf === undefined)
|
|
605
|
-
return undefined;
|
|
606
|
-
if (alwaysApplyTransformation(xf))
|
|
607
|
-
return undefined;
|
|
608
|
-
return (0, Support_1.defined)(this.nameForTransformation(t));
|
|
609
|
-
}
|
|
610
|
-
attributesForProperty(property, _name, _c, jsonName) {
|
|
611
|
-
if (!this._needAttributes)
|
|
612
|
-
return undefined;
|
|
613
|
-
const attributes = [];
|
|
614
|
-
const jsonProperty = this._options.dense ? denseJsonPropertyName : "JsonProperty";
|
|
615
|
-
const escapedName = (0, Strings_1.utf16StringEscape)(jsonName);
|
|
616
|
-
const isNullable = (0, Transformers_1.followTargetType)(property.type).isNullable;
|
|
617
|
-
const isOptional = property.isOptional;
|
|
618
|
-
const requiredClass = this._options.dense ? "R" : "Required";
|
|
619
|
-
const nullValueHandlingClass = this._options.dense ? "N" : "NullValueHandling";
|
|
620
|
-
const nullValueHandling = isOptional && !isNullable ? [", NullValueHandling = ", nullValueHandlingClass, ".Ignore"] : [];
|
|
621
|
-
let required;
|
|
622
|
-
if (!this._options.checkRequired || (isOptional && isNullable)) {
|
|
623
|
-
required = [nullValueHandling];
|
|
624
|
-
}
|
|
625
|
-
else if (isOptional && !isNullable) {
|
|
626
|
-
required = [", Required = ", requiredClass, ".DisallowNull", nullValueHandling];
|
|
627
|
-
}
|
|
628
|
-
else if (!isOptional && isNullable) {
|
|
629
|
-
required = [", Required = ", requiredClass, ".AllowNull"];
|
|
630
|
-
}
|
|
631
|
-
else {
|
|
632
|
-
required = [", Required = ", requiredClass, ".Always", nullValueHandling];
|
|
633
|
-
}
|
|
634
|
-
attributes.push(["[", jsonProperty, '("', escapedName, '"', required, ")]"]);
|
|
635
|
-
const converter = this.converterForType(property.type);
|
|
636
|
-
if (converter !== undefined) {
|
|
637
|
-
attributes.push(["[JsonConverter(typeof(", converter, "))]"]);
|
|
638
|
-
}
|
|
639
|
-
return attributes;
|
|
640
|
-
}
|
|
641
|
-
blankLinesBetweenAttributes() {
|
|
642
|
-
return this._needAttributes && !this._options.dense;
|
|
643
|
-
}
|
|
644
|
-
// The "this" type can't be `dynamic`, so we have to force it to `object`.
|
|
645
|
-
topLevelResultType(t) {
|
|
646
|
-
return t.kind === "any" || t.kind === "none" ? "object" : this.csType(t);
|
|
647
|
-
}
|
|
648
|
-
emitFromJsonForTopLevel(t, name) {
|
|
649
|
-
if (t instanceof Type_1.EnumType)
|
|
650
|
-
return;
|
|
651
|
-
let partial;
|
|
652
|
-
let typeKind;
|
|
653
|
-
const definedType = this.namedTypeToNameForTopLevel(t);
|
|
654
|
-
if (definedType !== undefined) {
|
|
655
|
-
partial = "partial ";
|
|
656
|
-
typeKind = definedType instanceof Type_1.ClassType ? "class" : "struct";
|
|
657
|
-
}
|
|
658
|
-
else {
|
|
659
|
-
partial = "";
|
|
660
|
-
typeKind = "class";
|
|
661
|
-
}
|
|
662
|
-
const csType = this.topLevelResultType(t);
|
|
663
|
-
this.emitType(undefined, AccessModifier.Public, [partial, typeKind], name, this.baseclassForType(t), () => {
|
|
664
|
-
// FIXME: Make FromJson a Named
|
|
665
|
-
this.emitExpressionMember(["public static ", csType, " FromJson(string json)"], ["JsonConvert.DeserializeObject<", csType, ">(json, ", this._options.namespace, ".Converter.Settings)"]);
|
|
666
|
-
});
|
|
667
|
-
}
|
|
668
|
-
emitDecoderSwitch(emitBody) {
|
|
669
|
-
this.emitLine("switch (reader.TokenType)");
|
|
670
|
-
this.emitBlock(emitBody);
|
|
671
|
-
}
|
|
672
|
-
emitTokenCase(tokenType) {
|
|
673
|
-
this.emitLine("case JsonToken.", tokenType, ":");
|
|
674
|
-
}
|
|
675
|
-
emitThrow(message) {
|
|
676
|
-
this.emitLine("throw new Exception(", message, ");");
|
|
677
|
-
}
|
|
678
|
-
deserializeTypeCode(typeName) {
|
|
679
|
-
return ["serializer.Deserialize<", typeName, ">(reader)"];
|
|
680
|
-
}
|
|
681
|
-
serializeValueCode(value) {
|
|
682
|
-
return ["serializer.Serialize(writer, ", value, ")"];
|
|
683
|
-
}
|
|
684
|
-
emitSerializeClass() {
|
|
685
|
-
// FIXME: Make Serialize a Named
|
|
686
|
-
this.emitType(undefined, AccessModifier.Public, "static class", "Serialize", undefined, () => {
|
|
687
|
-
// Sometimes multiple top-levels will resolve to the same type, so we have to take care
|
|
688
|
-
// not to emit more than one extension method for the same type.
|
|
689
|
-
const seenTypes = new Set();
|
|
690
|
-
this.forEachTopLevel("none", t => {
|
|
691
|
-
// FIXME: Make ToJson a Named
|
|
692
|
-
if (!seenTypes.has(t)) {
|
|
693
|
-
seenTypes.add(t);
|
|
694
|
-
this.emitExpressionMember(["public static string ToJson(this ", this.topLevelResultType(t), " self)"], ["JsonConvert.SerializeObject(self, ", this._options.namespace, ".Converter.Settings)"]);
|
|
695
|
-
}
|
|
696
|
-
});
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
|
-
emitCanConvert(expr) {
|
|
700
|
-
this.emitExpressionMember("public override bool CanConvert(Type t)", expr);
|
|
701
|
-
}
|
|
702
|
-
emitReadJson(emitBody) {
|
|
703
|
-
this.emitLine("public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)");
|
|
704
|
-
this.emitBlock(emitBody);
|
|
705
|
-
}
|
|
706
|
-
emitWriteJson(variable, emitBody) {
|
|
707
|
-
this.emitLine("public override void WriteJson(JsonWriter writer, object ", variable, ", JsonSerializer serializer)");
|
|
708
|
-
this.emitBlock(emitBody);
|
|
709
|
-
}
|
|
710
|
-
converterObject(converterName) {
|
|
711
|
-
// FIXME: Get a singleton
|
|
712
|
-
return [converterName, ".Singleton"];
|
|
713
|
-
}
|
|
714
|
-
emitConverterClass() {
|
|
715
|
-
// FIXME: Make Converter a Named
|
|
716
|
-
const converterName = ["Converter"];
|
|
717
|
-
this.emitType(undefined, AccessModifier.Internal, "static class", converterName, undefined, () => {
|
|
718
|
-
this.emitLine("public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings");
|
|
719
|
-
this.emitBlock(() => {
|
|
720
|
-
this.emitLine("MetadataPropertyHandling = MetadataPropertyHandling.Ignore,");
|
|
721
|
-
this.emitLine("DateParseHandling = DateParseHandling.None,");
|
|
722
|
-
this.emitLine("Converters =");
|
|
723
|
-
this.emitLine("{");
|
|
724
|
-
this.indent(() => {
|
|
725
|
-
for (const [t, converter] of this.typesWithNamedTransformations) {
|
|
726
|
-
if (alwaysApplyTransformation((0, Support_1.defined)((0, Transformers_1.transformationForType)(t)))) {
|
|
727
|
-
this.emitLine(this.converterObject(converter), ",");
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
this.emitLine("new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }");
|
|
731
|
-
});
|
|
732
|
-
this.emitLine(`},`);
|
|
733
|
-
}, true);
|
|
734
|
-
});
|
|
735
|
-
}
|
|
736
|
-
emitDecoderTransformerCase(tokenCases, variableName, xfer, targetType, emitFinish) {
|
|
737
|
-
if (xfer === undefined)
|
|
738
|
-
return;
|
|
739
|
-
for (const tokenCase of tokenCases) {
|
|
740
|
-
this.emitTokenCase(tokenCase);
|
|
741
|
-
}
|
|
742
|
-
this.indent(() => {
|
|
743
|
-
const allHandled = this.emitDecodeTransformer(xfer, targetType, emitFinish, variableName);
|
|
744
|
-
if (!allHandled) {
|
|
745
|
-
this.emitLine("break;");
|
|
746
|
-
}
|
|
747
|
-
});
|
|
748
|
-
}
|
|
749
|
-
emitConsume(value, consumer, targetType, emitFinish) {
|
|
750
|
-
if (consumer === undefined) {
|
|
751
|
-
emitFinish(value);
|
|
752
|
-
return true;
|
|
753
|
-
}
|
|
754
|
-
else {
|
|
755
|
-
return this.emitTransformer(value, consumer, targetType, emitFinish);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
emitDecodeTransformer(xfer, targetType, emitFinish, variableName = "value") {
|
|
759
|
-
if (xfer instanceof Transformers_1.DecodingTransformer) {
|
|
760
|
-
const source = xfer.sourceType;
|
|
761
|
-
const converter = this.converterForType(targetType);
|
|
762
|
-
if (converter !== undefined) {
|
|
763
|
-
const typeSource = this.csType(targetType);
|
|
764
|
-
this.emitLine("var converter = ", this.converterObject(converter), ";");
|
|
765
|
-
this.emitLine("var ", variableName, " = (", typeSource, ")converter.ReadJson(reader, typeof(", typeSource, "), null, serializer);");
|
|
766
|
-
}
|
|
767
|
-
else if (source.kind !== "null") {
|
|
768
|
-
let output = targetType.kind === "double" ? targetType : source;
|
|
769
|
-
this.emitLine("var ", variableName, " = ", this.deserializeTypeCode(this.csType(output)), ";");
|
|
770
|
-
}
|
|
771
|
-
return this.emitConsume(variableName, xfer.consumer, targetType, emitFinish);
|
|
772
|
-
}
|
|
773
|
-
else if (xfer instanceof Transformers_1.ArrayDecodingTransformer) {
|
|
774
|
-
// FIXME: Consume StartArray
|
|
775
|
-
if (!(targetType instanceof Type_1.ArrayType)) {
|
|
776
|
-
return (0, Support_1.panic)("Array decoding must produce an array type");
|
|
777
|
-
}
|
|
778
|
-
// FIXME: handle EOF
|
|
779
|
-
this.emitLine("reader.Read();");
|
|
780
|
-
this.emitLine("var ", variableName, " = new List<", this.csType(targetType.items), ">();");
|
|
781
|
-
this.emitLine("while (reader.TokenType != JsonToken.EndArray)");
|
|
782
|
-
this.emitBlock(() => {
|
|
783
|
-
this.emitDecodeTransformer(xfer.itemTransformer, xfer.itemTargetType, v => this.emitLine(variableName, ".Add(", v, ");"), "arrayItem");
|
|
784
|
-
// FIXME: handle EOF
|
|
785
|
-
this.emitLine("reader.Read();");
|
|
786
|
-
});
|
|
787
|
-
let result = variableName;
|
|
788
|
-
if (!this._options.useList) {
|
|
789
|
-
result = [result, ".ToArray()"];
|
|
790
|
-
}
|
|
791
|
-
emitFinish(result);
|
|
792
|
-
return true;
|
|
793
|
-
}
|
|
794
|
-
else if (xfer instanceof Transformers_1.DecodingChoiceTransformer) {
|
|
795
|
-
this.emitDecoderSwitch(() => {
|
|
796
|
-
const nullTransformer = xfer.nullTransformer;
|
|
797
|
-
if (nullTransformer !== undefined) {
|
|
798
|
-
this.emitTokenCase("Null");
|
|
799
|
-
this.indent(() => {
|
|
800
|
-
const allHandled = this.emitDecodeTransformer(nullTransformer, targetType, emitFinish, "null");
|
|
801
|
-
if (!allHandled) {
|
|
802
|
-
this.emitLine("break");
|
|
803
|
-
}
|
|
804
|
-
});
|
|
805
|
-
}
|
|
806
|
-
this.emitDecoderTransformerCase(["Integer"], "integerValue", xfer.integerTransformer, targetType, emitFinish);
|
|
807
|
-
this.emitDecoderTransformerCase(xfer.integerTransformer === undefined ? ["Integer", "Float"] : ["Float"], "doubleValue", xfer.doubleTransformer, targetType, emitFinish);
|
|
808
|
-
this.emitDecoderTransformerCase(["Boolean"], "boolValue", xfer.boolTransformer, targetType, emitFinish);
|
|
809
|
-
this.emitDecoderTransformerCase(["String", "Date"], "stringValue", xfer.stringTransformer, targetType, emitFinish);
|
|
810
|
-
this.emitDecoderTransformerCase(["StartObject"], "objectValue", xfer.objectTransformer, targetType, emitFinish);
|
|
811
|
-
this.emitDecoderTransformerCase(["StartArray"], "arrayValue", xfer.arrayTransformer, targetType, emitFinish);
|
|
812
|
-
});
|
|
813
|
-
return false;
|
|
814
|
-
}
|
|
815
|
-
else {
|
|
816
|
-
return (0, Support_1.panic)("Unknown transformer");
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
stringCaseValue(t, stringCase) {
|
|
820
|
-
if (t.kind === "string") {
|
|
821
|
-
return ['"', (0, Strings_1.utf16StringEscape)(stringCase), '"'];
|
|
822
|
-
}
|
|
823
|
-
else if (t instanceof Type_1.EnumType) {
|
|
824
|
-
return [this.nameForNamedType(t), ".", this.nameForEnumCase(t, stringCase)];
|
|
825
|
-
}
|
|
826
|
-
return (0, Support_1.panic)(`Type ${t.kind} does not have string cases`);
|
|
827
|
-
}
|
|
828
|
-
emitTransformer(variable, xfer, targetType, emitFinish) {
|
|
829
|
-
function directTargetType(continuation) {
|
|
830
|
-
if (continuation === undefined) {
|
|
831
|
-
return targetType;
|
|
832
|
-
}
|
|
833
|
-
return (0, Transformers_1.followTargetType)(continuation.sourceType);
|
|
834
|
-
}
|
|
835
|
-
if (xfer instanceof Transformers_1.ChoiceTransformer) {
|
|
836
|
-
const caseXfers = xfer.transformers;
|
|
837
|
-
if (caseXfers.length > 1 && caseXfers.every(caseXfer => caseXfer instanceof Transformers_1.StringMatchTransformer)) {
|
|
838
|
-
this.emitLine("switch (", variable, ")");
|
|
839
|
-
this.emitBlock(() => {
|
|
840
|
-
for (const caseXfer of caseXfers) {
|
|
841
|
-
const matchXfer = caseXfer;
|
|
842
|
-
const value = this.stringCaseValue((0, Transformers_1.followTargetType)(matchXfer.sourceType), matchXfer.stringCase);
|
|
843
|
-
this.emitLine("case ", value, ":");
|
|
844
|
-
this.indent(() => {
|
|
845
|
-
const allDone = this.emitTransformer(variable, matchXfer.transformer, targetType, emitFinish);
|
|
846
|
-
if (!allDone) {
|
|
847
|
-
this.emitLine("break;");
|
|
848
|
-
}
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
});
|
|
852
|
-
// FIXME: Can we check for exhaustiveness? For enums it should be easy.
|
|
853
|
-
return false;
|
|
854
|
-
}
|
|
855
|
-
else {
|
|
856
|
-
for (const caseXfer of caseXfers) {
|
|
857
|
-
this.emitTransformer(variable, caseXfer, targetType, emitFinish);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
else if (xfer instanceof Transformers_1.UnionMemberMatchTransformer) {
|
|
862
|
-
const memberType = xfer.memberType;
|
|
863
|
-
const maybeNullable = (0, TypeUtils_1.nullableFromUnion)(xfer.sourceType);
|
|
864
|
-
let test;
|
|
865
|
-
let member;
|
|
866
|
-
if (maybeNullable !== null) {
|
|
867
|
-
if (memberType.kind === "null") {
|
|
868
|
-
test = [variable, " == null"];
|
|
869
|
-
member = "null";
|
|
870
|
-
}
|
|
871
|
-
else {
|
|
872
|
-
test = [variable, " != null"];
|
|
873
|
-
member = variable;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
else if (memberType.kind === "null") {
|
|
877
|
-
test = [variable, ".IsNull"];
|
|
878
|
-
member = "null";
|
|
879
|
-
}
|
|
880
|
-
else {
|
|
881
|
-
const memberName = this.nameForUnionMember(xfer.sourceType, memberType);
|
|
882
|
-
member = [variable, ".", memberName];
|
|
883
|
-
test = [member, " != null"];
|
|
884
|
-
}
|
|
885
|
-
if (memberType.kind !== "null" && isValueType(memberType)) {
|
|
886
|
-
member = [member, ".Value"];
|
|
887
|
-
}
|
|
888
|
-
this.emitLine("if (", test, ")");
|
|
889
|
-
this.emitBlock(() => this.emitTransformer(member, xfer.transformer, targetType, emitFinish));
|
|
890
|
-
}
|
|
891
|
-
else if (xfer instanceof Transformers_1.StringMatchTransformer) {
|
|
892
|
-
const value = this.stringCaseValue((0, Transformers_1.followTargetType)(xfer.sourceType), xfer.stringCase);
|
|
893
|
-
this.emitLine("if (", variable, " == ", value, ")");
|
|
894
|
-
this.emitBlock(() => this.emitTransformer(variable, xfer.transformer, targetType, emitFinish));
|
|
895
|
-
}
|
|
896
|
-
else if (xfer instanceof Transformers_1.EncodingTransformer) {
|
|
897
|
-
const converter = this.converterForType(xfer.sourceType);
|
|
898
|
-
if (converter !== undefined) {
|
|
899
|
-
this.emitLine("var converter = ", this.converterObject(converter), ";");
|
|
900
|
-
this.emitLine("converter.WriteJson(writer, ", variable, ", serializer);");
|
|
901
|
-
}
|
|
902
|
-
else {
|
|
903
|
-
this.emitLine(this.serializeValueCode(variable), ";");
|
|
904
|
-
}
|
|
905
|
-
emitFinish([]);
|
|
906
|
-
return true;
|
|
907
|
-
}
|
|
908
|
-
else if (xfer instanceof Transformers_1.ArrayEncodingTransformer) {
|
|
909
|
-
this.emitLine("writer.WriteStartArray();");
|
|
910
|
-
const itemVariable = "arrayItem";
|
|
911
|
-
this.emitLine("foreach (var ", itemVariable, " in ", variable, ")");
|
|
912
|
-
this.emitBlock(() => {
|
|
913
|
-
this.emitTransformer(itemVariable, xfer.itemTransformer, xfer.itemTargetType, () => {
|
|
914
|
-
return;
|
|
915
|
-
});
|
|
916
|
-
});
|
|
917
|
-
this.emitLine("writer.WriteEndArray();");
|
|
918
|
-
emitFinish([]);
|
|
919
|
-
return true;
|
|
920
|
-
}
|
|
921
|
-
else if (xfer instanceof Transformers_1.ParseStringTransformer) {
|
|
922
|
-
const immediateTargetType = xfer.consumer === undefined ? targetType : xfer.consumer.sourceType;
|
|
923
|
-
switch (immediateTargetType.kind) {
|
|
924
|
-
case "date-time":
|
|
925
|
-
this.emitLine("DateTimeOffset dt;");
|
|
926
|
-
this.emitLine("if (DateTimeOffset.TryParse(", variable, ", out dt))");
|
|
927
|
-
this.emitBlock(() => this.emitConsume("dt", xfer.consumer, targetType, emitFinish));
|
|
928
|
-
break;
|
|
929
|
-
case "uuid":
|
|
930
|
-
this.emitLine("Guid guid;");
|
|
931
|
-
this.emitLine("if (Guid.TryParse(", variable, ", out guid))");
|
|
932
|
-
this.emitBlock(() => this.emitConsume("guid", xfer.consumer, targetType, emitFinish));
|
|
933
|
-
break;
|
|
934
|
-
case "uri":
|
|
935
|
-
this.emitLine("try");
|
|
936
|
-
this.emitBlock(() => {
|
|
937
|
-
this.emitLine("var uri = new Uri(", variable, ");");
|
|
938
|
-
this.emitConsume("uri", xfer.consumer, targetType, emitFinish);
|
|
939
|
-
});
|
|
940
|
-
this.emitLine("catch (UriFormatException) {}");
|
|
941
|
-
break;
|
|
942
|
-
case "integer":
|
|
943
|
-
this.emitLine("long l;");
|
|
944
|
-
this.emitLine("if (Int64.TryParse(", variable, ", out l))");
|
|
945
|
-
this.emitBlock(() => this.emitConsume("l", xfer.consumer, targetType, emitFinish));
|
|
946
|
-
break;
|
|
947
|
-
case "bool":
|
|
948
|
-
this.emitLine("bool b;");
|
|
949
|
-
this.emitLine("if (Boolean.TryParse(", variable, ", out b))");
|
|
950
|
-
this.emitBlock(() => this.emitConsume("b", xfer.consumer, targetType, emitFinish));
|
|
951
|
-
break;
|
|
952
|
-
default:
|
|
953
|
-
return (0, Support_1.panic)(`Parsing string to ${immediateTargetType.kind} not supported`);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
else if (xfer instanceof Transformers_1.StringifyTransformer) {
|
|
957
|
-
switch (xfer.sourceType.kind) {
|
|
958
|
-
case "date-time":
|
|
959
|
-
return this.emitConsume([variable, '.ToString("o", System.Globalization.CultureInfo.InvariantCulture)'], xfer.consumer, targetType, emitFinish);
|
|
960
|
-
case "uuid":
|
|
961
|
-
return this.emitConsume([variable, '.ToString("D", System.Globalization.CultureInfo.InvariantCulture)'], xfer.consumer, targetType, emitFinish);
|
|
962
|
-
case "integer":
|
|
963
|
-
case "uri":
|
|
964
|
-
return this.emitConsume([variable, ".ToString()"], xfer.consumer, targetType, emitFinish);
|
|
965
|
-
case "bool":
|
|
966
|
-
this.emitLine("var boolString = ", variable, ' ? "true" : "false";');
|
|
967
|
-
return this.emitConsume("boolString", xfer.consumer, targetType, emitFinish);
|
|
968
|
-
default:
|
|
969
|
-
return (0, Support_1.panic)(`Stringifying ${xfer.sourceType.kind} not supported`);
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
else if (xfer instanceof Transformers_1.StringProducerTransformer) {
|
|
973
|
-
const value = this.stringCaseValue(directTargetType(xfer.consumer), xfer.result);
|
|
974
|
-
return this.emitConsume(value, xfer.consumer, targetType, emitFinish);
|
|
975
|
-
}
|
|
976
|
-
else if (xfer instanceof Transformers_1.MinMaxLengthCheckTransformer) {
|
|
977
|
-
const min = xfer.minLength;
|
|
978
|
-
const max = xfer.maxLength;
|
|
979
|
-
const conditions = [];
|
|
980
|
-
if (min !== undefined) {
|
|
981
|
-
conditions.push([variable, ".Length >= ", min.toString()]);
|
|
982
|
-
}
|
|
983
|
-
if (max !== undefined) {
|
|
984
|
-
conditions.push([variable, ".Length <= ", max.toString()]);
|
|
985
|
-
}
|
|
986
|
-
this.emitLine("if (", (0, collection_utils_1.arrayIntercalate)([" && "], conditions), ")");
|
|
987
|
-
this.emitBlock(() => this.emitConsume(variable, xfer.consumer, targetType, emitFinish));
|
|
988
|
-
return false;
|
|
989
|
-
}
|
|
990
|
-
else if (xfer instanceof Transformers_1.MinMaxValueTransformer) {
|
|
991
|
-
const min = xfer.minimum;
|
|
992
|
-
const max = xfer.maximum;
|
|
993
|
-
const conditions = [];
|
|
994
|
-
if (min !== undefined) {
|
|
995
|
-
conditions.push([variable, " >= ", min.toString()]);
|
|
996
|
-
}
|
|
997
|
-
if (max !== undefined) {
|
|
998
|
-
conditions.push([variable, " <= ", max.toString()]);
|
|
999
|
-
}
|
|
1000
|
-
this.emitLine("if (", (0, collection_utils_1.arrayIntercalate)([" && "], conditions), ")");
|
|
1001
|
-
this.emitBlock(() => this.emitConsume(variable, xfer.consumer, targetType, emitFinish));
|
|
1002
|
-
return false;
|
|
1003
|
-
}
|
|
1004
|
-
else if (xfer instanceof Transformers_1.UnionInstantiationTransformer) {
|
|
1005
|
-
if (!(targetType instanceof Type_1.UnionType)) {
|
|
1006
|
-
return (0, Support_1.panic)("Union instantiation transformer must produce a union type");
|
|
1007
|
-
}
|
|
1008
|
-
const maybeNullable = (0, TypeUtils_1.nullableFromUnion)(targetType);
|
|
1009
|
-
if (maybeNullable !== null) {
|
|
1010
|
-
emitFinish(variable);
|
|
1011
|
-
}
|
|
1012
|
-
else {
|
|
1013
|
-
const unionName = this.nameForNamedType(targetType);
|
|
1014
|
-
let initializer;
|
|
1015
|
-
if (xfer.sourceType.kind === "null") {
|
|
1016
|
-
initializer = " ";
|
|
1017
|
-
}
|
|
1018
|
-
else {
|
|
1019
|
-
const memberName = this.nameForUnionMember(targetType, xfer.sourceType);
|
|
1020
|
-
initializer = [" ", memberName, " = ", variable, " "];
|
|
1021
|
-
}
|
|
1022
|
-
emitFinish(["new ", unionName, " {", initializer, "}"]);
|
|
1023
|
-
}
|
|
1024
|
-
return true;
|
|
1025
|
-
}
|
|
1026
|
-
else {
|
|
1027
|
-
return (0, Support_1.panic)("Unknown transformer");
|
|
1028
|
-
}
|
|
1029
|
-
return false;
|
|
1030
|
-
}
|
|
1031
|
-
emitTransformation(converterName, t) {
|
|
1032
|
-
const xf = (0, Support_1.defined)((0, Transformers_1.transformationForType)(t));
|
|
1033
|
-
const reverse = xf.reverse;
|
|
1034
|
-
const targetType = xf.targetType;
|
|
1035
|
-
const xfer = xf.transformer;
|
|
1036
|
-
this.emitType(undefined, AccessModifier.Internal, "class", converterName, "JsonConverter", () => {
|
|
1037
|
-
const csType = this.csType(targetType);
|
|
1038
|
-
let canConvertExpr = ["t == typeof(", csType, ")"];
|
|
1039
|
-
const haveNullable = isValueType(targetType);
|
|
1040
|
-
if (haveNullable) {
|
|
1041
|
-
canConvertExpr = [canConvertExpr, " || t == typeof(", csType, "?)"];
|
|
1042
|
-
}
|
|
1043
|
-
this.emitCanConvert(canConvertExpr);
|
|
1044
|
-
this.ensureBlankLine();
|
|
1045
|
-
this.emitReadJson(() => {
|
|
1046
|
-
// FIXME: It's unsatisfying that we need this. The reason is that we not
|
|
1047
|
-
// only match T, but also T?. If we didn't, then the T in T? would not be
|
|
1048
|
-
// deserialized with our converter but with the default one. Can we check
|
|
1049
|
-
// whether the type is a nullable?
|
|
1050
|
-
// FIXME: This could duplicate one of the cases handled below in
|
|
1051
|
-
// `emitDecodeTransformer`.
|
|
1052
|
-
if (haveNullable && !(targetType instanceof Type_1.UnionType)) {
|
|
1053
|
-
this.emitLine("if (reader.TokenType == JsonToken.Null) return null;");
|
|
1054
|
-
}
|
|
1055
|
-
const allHandled = this.emitDecodeTransformer(xfer, targetType, v => this.emitLine("return ", v, ";"));
|
|
1056
|
-
if (!allHandled) {
|
|
1057
|
-
this.emitThrow(['"Cannot unmarshal type ', csType, '"']);
|
|
1058
|
-
}
|
|
1059
|
-
});
|
|
1060
|
-
this.ensureBlankLine();
|
|
1061
|
-
this.emitWriteJson("untypedValue", () => {
|
|
1062
|
-
// FIXME: See above.
|
|
1063
|
-
if (haveNullable && !(targetType instanceof Type_1.UnionType)) {
|
|
1064
|
-
this.emitLine("if (untypedValue == null)");
|
|
1065
|
-
this.emitBlock(() => {
|
|
1066
|
-
this.emitLine("serializer.Serialize(writer, null);");
|
|
1067
|
-
this.emitLine("return;");
|
|
1068
|
-
});
|
|
1069
|
-
}
|
|
1070
|
-
this.emitLine("var value = (", csType, ")untypedValue;");
|
|
1071
|
-
const allHandled = this.emitTransformer("value", reverse.transformer, reverse.targetType, () => this.emitLine("return;"));
|
|
1072
|
-
if (!allHandled) {
|
|
1073
|
-
this.emitThrow(['"Cannot marshal type ', csType, '"']);
|
|
1074
|
-
}
|
|
1075
|
-
});
|
|
1076
|
-
this.ensureBlankLine();
|
|
1077
|
-
this.emitLine("public static readonly ", converterName, " Singleton = new ", converterName, "();");
|
|
1078
|
-
});
|
|
1079
|
-
}
|
|
1080
|
-
emitRequiredHelpers() {
|
|
1081
|
-
if (this._needHelpers) {
|
|
1082
|
-
this.forEachTopLevel("leading-and-interposing", (t, n) => this.emitFromJsonForTopLevel(t, n));
|
|
1083
|
-
this.ensureBlankLine();
|
|
1084
|
-
this.emitSerializeClass();
|
|
1085
|
-
}
|
|
1086
|
-
if (this._needHelpers || (this._needAttributes && (this.haveNamedUnions || this.haveEnums))) {
|
|
1087
|
-
this.ensureBlankLine();
|
|
1088
|
-
this.emitConverterClass();
|
|
1089
|
-
this.forEachTransformation("leading-and-interposing", (n, t) => this.emitTransformation(n, t));
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
needNamespace() {
|
|
1093
|
-
return this._needNamespaces;
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
exports.NewtonsoftCSharpRenderer = NewtonsoftCSharpRenderer;
|
|
1097
|
-
exports.systemTextJsonCSharpOptions = Object.assign({}, exports.cSharpOptions, {});
|
|
1098
|
-
class SystemTextJsonCSharpRenderer extends CSharpRenderer {
|
|
1099
|
-
_options;
|
|
1100
|
-
_enumExtensionsNames = new Map();
|
|
1101
|
-
_needHelpers;
|
|
1102
|
-
_needAttributes;
|
|
1103
|
-
_needNamespaces;
|
|
1104
|
-
constructor(targetLanguage, renderContext, _options) {
|
|
1105
|
-
super(targetLanguage, renderContext, _options);
|
|
1106
|
-
this._options = _options;
|
|
1107
|
-
this._needHelpers = _options.features.helpers;
|
|
1108
|
-
this._needAttributes = _options.features.attributes;
|
|
1109
|
-
this._needNamespaces = _options.features.namespaces;
|
|
1110
|
-
}
|
|
1111
|
-
forbiddenNamesForGlobalNamespace() {
|
|
1112
|
-
const forbidden = [
|
|
1113
|
-
"Converter",
|
|
1114
|
-
"JsonConverter",
|
|
1115
|
-
"JsonSerializer",
|
|
1116
|
-
"JsonWriter",
|
|
1117
|
-
"JsonToken",
|
|
1118
|
-
"Serialize",
|
|
1119
|
-
"JsonSerializerOptions",
|
|
1120
|
-
// "Newtonsoft",
|
|
1121
|
-
// "MetadataPropertyHandling",
|
|
1122
|
-
// "DateParseHandling",
|
|
1123
|
-
"FromJson",
|
|
1124
|
-
"Required"
|
|
1125
|
-
];
|
|
1126
|
-
if (this._options.dense) {
|
|
1127
|
-
forbidden.push("J", "R", "N");
|
|
1128
|
-
}
|
|
1129
|
-
if (this._options.baseclass !== undefined) {
|
|
1130
|
-
forbidden.push(this._options.baseclass);
|
|
1131
|
-
}
|
|
1132
|
-
return super.forbiddenNamesForGlobalNamespace().concat(forbidden);
|
|
1133
|
-
}
|
|
1134
|
-
forbiddenForObjectProperties(c, className) {
|
|
1135
|
-
const result = super.forbiddenForObjectProperties(c, className);
|
|
1136
|
-
result.names = result.names.concat(["ToJson", "FromJson", "Required"]);
|
|
1137
|
-
return result;
|
|
1138
|
-
}
|
|
1139
|
-
makeNameForTransformation(xf, typeName) {
|
|
1140
|
-
if (typeName === undefined) {
|
|
1141
|
-
let xfer = xf.transformer;
|
|
1142
|
-
if (xfer instanceof Transformers_1.DecodingTransformer && xfer.consumer !== undefined) {
|
|
1143
|
-
xfer = xfer.consumer;
|
|
1144
|
-
}
|
|
1145
|
-
return new Naming_1.SimpleName([`${xfer.kind}_converter`], namingFunction, ConvenienceRenderer_1.inferredNameOrder + 30);
|
|
1146
|
-
}
|
|
1147
|
-
return new Naming_1.DependencyName(namingFunction, typeName.order + 30, lookup => `${lookup(typeName)}_converter`);
|
|
1148
|
-
}
|
|
1149
|
-
makeNamedTypeDependencyNames(t, name) {
|
|
1150
|
-
if (!(t instanceof Type_1.EnumType))
|
|
1151
|
-
return [];
|
|
1152
|
-
const extensionsName = new Naming_1.DependencyName(namingFunction, name.order + 30, lookup => `${lookup(name)}_extensions`);
|
|
1153
|
-
this._enumExtensionsNames.set(name, extensionsName);
|
|
1154
|
-
return [extensionsName];
|
|
1155
|
-
}
|
|
1156
|
-
emitUsings() {
|
|
1157
|
-
// FIXME: We need System.Collections.Generic whenever we have maps or use List.
|
|
1158
|
-
if (!this._needAttributes && !this._needHelpers)
|
|
1159
|
-
return;
|
|
1160
|
-
super.emitUsings();
|
|
1161
|
-
this.ensureBlankLine();
|
|
1162
|
-
for (const ns of ["System.Text.Json", "System.Text.Json.Serialization", "System.Globalization"]) {
|
|
1163
|
-
this.emitUsing(ns);
|
|
1164
|
-
}
|
|
1165
|
-
if (this._options.dense) {
|
|
1166
|
-
this.emitUsing([denseJsonPropertyName, " = System.Text.Json.Serialization.JsonPropertyNameAttribute"]);
|
|
1167
|
-
// this.emitUsing([denseRequiredEnumName, " = Newtonsoft.Json.Required"]);
|
|
1168
|
-
this.emitUsing([denseNullValueHandlingEnumName, " = System.Text.Json.Serialization.JsonIgnoreCondition"]);
|
|
1169
|
-
}
|
|
1170
|
-
if (this._options.baseclass === "EntityData") {
|
|
1171
|
-
this.emitUsing("Microsoft.Azure.Mobile.Server");
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
baseclassForType(_t) {
|
|
1175
|
-
return this._options.baseclass;
|
|
1176
|
-
}
|
|
1177
|
-
emitDefaultFollowingComments() {
|
|
1178
|
-
if (!this._needHelpers)
|
|
1179
|
-
return;
|
|
1180
|
-
this.emitLine("#pragma warning restore CS8618");
|
|
1181
|
-
this.emitLine("#pragma warning restore CS8601");
|
|
1182
|
-
this.emitLine("#pragma warning restore CS8603");
|
|
1183
|
-
}
|
|
1184
|
-
emitDefaultLeadingComments() {
|
|
1185
|
-
if (!this._needHelpers)
|
|
1186
|
-
return;
|
|
1187
|
-
this.emitLine("// <auto-generated />");
|
|
1188
|
-
this.emitLine("//");
|
|
1189
|
-
this.emitLine("// To parse this JSON data, add NuGet 'System.Text.Json' then do", this.topLevels.size === 1 ? "" : " one of these", ":");
|
|
1190
|
-
this.emitLine("//");
|
|
1191
|
-
this.emitLine("// using ", this._options.namespace, ";");
|
|
1192
|
-
this.emitLine("//");
|
|
1193
|
-
this.forEachTopLevel("none", (t, topLevelName) => {
|
|
1194
|
-
let rhs;
|
|
1195
|
-
if (t instanceof Type_1.EnumType) {
|
|
1196
|
-
rhs = ["JsonSerializer.Deserialize<", topLevelName, ">(jsonString)"];
|
|
1197
|
-
}
|
|
1198
|
-
else {
|
|
1199
|
-
rhs = [topLevelName, ".FromJson(jsonString)"];
|
|
1200
|
-
}
|
|
1201
|
-
this.emitLine("// var ", (0, Source_1.modifySource)(Strings_1.camelCase, topLevelName), " = ", rhs, ";");
|
|
1202
|
-
});
|
|
1203
|
-
// fix: should this be an option? Or respond to an existing option?
|
|
1204
|
-
this.emitLine("#nullable enable");
|
|
1205
|
-
this.emitLine("#pragma warning disable CS8618");
|
|
1206
|
-
this.emitLine("#pragma warning disable CS8601");
|
|
1207
|
-
this.emitLine("#pragma warning disable CS8603");
|
|
1208
|
-
}
|
|
1209
|
-
converterForType(t) {
|
|
1210
|
-
let xf = (0, Transformers_1.transformationForType)(t);
|
|
1211
|
-
if (xf === undefined && t instanceof Type_1.UnionType) {
|
|
1212
|
-
const maybeNullable = (0, TypeUtils_1.nullableFromUnion)(t);
|
|
1213
|
-
if (maybeNullable !== null) {
|
|
1214
|
-
t = maybeNullable;
|
|
1215
|
-
xf = (0, Transformers_1.transformationForType)(t);
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
if (xf === undefined)
|
|
1219
|
-
return undefined;
|
|
1220
|
-
if (alwaysApplyTransformation(xf))
|
|
1221
|
-
return undefined;
|
|
1222
|
-
return (0, Support_1.defined)(this.nameForTransformation(t));
|
|
1223
|
-
}
|
|
1224
|
-
attributesForProperty(property, _name, _c, jsonName) {
|
|
1225
|
-
if (!this._needAttributes)
|
|
1226
|
-
return undefined;
|
|
1227
|
-
const attributes = [];
|
|
1228
|
-
const jsonPropertyName = this._options.dense ? denseJsonPropertyName : "JsonPropertyName";
|
|
1229
|
-
const escapedName = (0, Strings_1.utf16StringEscape)(jsonName);
|
|
1230
|
-
const isNullable = (0, Transformers_1.followTargetType)(property.type).isNullable;
|
|
1231
|
-
const isOptional = property.isOptional;
|
|
1232
|
-
if (isOptional && !isNullable) {
|
|
1233
|
-
attributes.push(["[", "JsonIgnore", "(Condition = JsonIgnoreCondition.WhenWritingNull)]"]);
|
|
1234
|
-
}
|
|
1235
|
-
// const requiredClass = this._options.dense ? "R" : "Required";
|
|
1236
|
-
// const nullValueHandlingClass = this._options.dense ? "N" : "NullValueHandling";
|
|
1237
|
-
// const nullValueHandling = isOptional && !isNullable ? [", NullValueHandling = ", nullValueHandlingClass, ".Ignore"] : [];
|
|
1238
|
-
// let required: Sourcelike;
|
|
1239
|
-
// if (!this._options.checkRequired || (isOptional && isNullable)) {
|
|
1240
|
-
// required = [nullValueHandling];
|
|
1241
|
-
// } else if (isOptional && !isNullable) {
|
|
1242
|
-
// required = [", Required = ", requiredClass, ".DisallowNull", nullValueHandling];
|
|
1243
|
-
// } else if (!isOptional && isNullable) {
|
|
1244
|
-
// required = [", Required = ", requiredClass, ".AllowNull"];
|
|
1245
|
-
// } else {
|
|
1246
|
-
// required = [", Required = ", requiredClass, ".Always", nullValueHandling];
|
|
1247
|
-
// }
|
|
1248
|
-
attributes.push(["[", jsonPropertyName, '("', escapedName, '")]']);
|
|
1249
|
-
const converter = this.converterForType(property.type);
|
|
1250
|
-
if (converter !== undefined) {
|
|
1251
|
-
attributes.push(["[JsonConverter(typeof(", converter, "))]"]);
|
|
1252
|
-
}
|
|
1253
|
-
return attributes;
|
|
1254
|
-
}
|
|
1255
|
-
blankLinesBetweenAttributes() {
|
|
1256
|
-
return this._needAttributes && !this._options.dense;
|
|
1257
|
-
}
|
|
1258
|
-
// The "this" type can't be `dynamic`, so we have to force it to `object`.
|
|
1259
|
-
topLevelResultType(t) {
|
|
1260
|
-
return t.kind === "any" || t.kind === "none" ? "object" : this.csType(t);
|
|
1261
|
-
}
|
|
1262
|
-
emitFromJsonForTopLevel(t, name) {
|
|
1263
|
-
if (t instanceof Type_1.EnumType)
|
|
1264
|
-
return;
|
|
1265
|
-
let partial;
|
|
1266
|
-
let typeKind;
|
|
1267
|
-
const definedType = this.namedTypeToNameForTopLevel(t);
|
|
1268
|
-
if (definedType !== undefined) {
|
|
1269
|
-
partial = "partial ";
|
|
1270
|
-
typeKind = definedType instanceof Type_1.ClassType ? "class" : "struct";
|
|
1271
|
-
}
|
|
1272
|
-
else {
|
|
1273
|
-
partial = "";
|
|
1274
|
-
typeKind = "class";
|
|
1275
|
-
}
|
|
1276
|
-
const csType = this.topLevelResultType(t);
|
|
1277
|
-
this.emitType(undefined, AccessModifier.Public, [partial, typeKind], name, this.baseclassForType(t), () => {
|
|
1278
|
-
// FIXME: Make FromJson a Named
|
|
1279
|
-
this.emitExpressionMember(["public static ", csType, " FromJson(string json)"], ["JsonSerializer.Deserialize<", csType, ">(json, ", this._options.namespace, ".Converter.Settings)"]);
|
|
1280
|
-
});
|
|
1281
|
-
}
|
|
1282
|
-
emitDecoderSwitch(emitBody) {
|
|
1283
|
-
this.emitLine("switch (reader.TokenType)");
|
|
1284
|
-
this.emitBlock(emitBody);
|
|
1285
|
-
}
|
|
1286
|
-
emitTokenCase(tokenType) {
|
|
1287
|
-
this.emitLine("case JsonTokenType.", tokenType, ":");
|
|
1288
|
-
}
|
|
1289
|
-
emitThrow(message) {
|
|
1290
|
-
this.emitLine("throw new Exception(", message, ");");
|
|
1291
|
-
}
|
|
1292
|
-
deserializeTypeCode(typeName) {
|
|
1293
|
-
switch (typeName) {
|
|
1294
|
-
case "bool":
|
|
1295
|
-
return ["reader.GetBoolean()"];
|
|
1296
|
-
case "long":
|
|
1297
|
-
return ["reader.GetInt64()"];
|
|
1298
|
-
case "decimal":
|
|
1299
|
-
return ["reader.GetDecimal()"];
|
|
1300
|
-
case "double":
|
|
1301
|
-
return ["reader.GetDouble()"];
|
|
1302
|
-
case "string":
|
|
1303
|
-
return ["reader.GetString()"];
|
|
1304
|
-
default:
|
|
1305
|
-
return ["JsonSerializer.Deserialize<", typeName, ">(ref reader, options)"];
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
serializeValueCode(value) {
|
|
1309
|
-
if (value !== "null")
|
|
1310
|
-
return ["JsonSerializer.Serialize(writer, ", value, ", options)"];
|
|
1311
|
-
else
|
|
1312
|
-
return ["writer.WriteNullValue()"];
|
|
1313
|
-
}
|
|
1314
|
-
emitSerializeClass() {
|
|
1315
|
-
// FIXME: Make Serialize a Named
|
|
1316
|
-
this.emitType(undefined, AccessModifier.Public, "static class", "Serialize", undefined, () => {
|
|
1317
|
-
// Sometimes multiple top-levels will resolve to the same type, so we have to take care
|
|
1318
|
-
// not to emit more than one extension method for the same type.
|
|
1319
|
-
const seenTypes = new Set();
|
|
1320
|
-
this.forEachTopLevel("none", t => {
|
|
1321
|
-
// FIXME: Make ToJson a Named
|
|
1322
|
-
if (!seenTypes.has(t)) {
|
|
1323
|
-
seenTypes.add(t);
|
|
1324
|
-
this.emitExpressionMember(["public static string ToJson(this ", this.topLevelResultType(t), " self)"], ["JsonSerializer.Serialize(self, ", this._options.namespace, ".Converter.Settings)"]);
|
|
1325
|
-
}
|
|
1326
|
-
});
|
|
1327
|
-
});
|
|
1328
|
-
}
|
|
1329
|
-
emitCanConvert(expr) {
|
|
1330
|
-
this.emitExpressionMember("public override bool CanConvert(Type t)", expr);
|
|
1331
|
-
}
|
|
1332
|
-
emitReadJson(emitBody, csType) {
|
|
1333
|
-
this.emitLine("public override ", csType, " Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)");
|
|
1334
|
-
this.emitBlock(emitBody);
|
|
1335
|
-
}
|
|
1336
|
-
emitWriteJson(variable, emitBody, csType) {
|
|
1337
|
-
this.emitLine("public override void Write(Utf8JsonWriter writer, ", csType, " ", variable, ", JsonSerializerOptions options)");
|
|
1338
|
-
this.emitBlock(emitBody);
|
|
1339
|
-
}
|
|
1340
|
-
converterObject(converterName) {
|
|
1341
|
-
// FIXME: Get a singleton
|
|
1342
|
-
return [converterName, ".Singleton"];
|
|
1343
|
-
}
|
|
1344
|
-
emitConverterClass() {
|
|
1345
|
-
// FIXME: Make Converter a Named
|
|
1346
|
-
const converterName = ["Converter"];
|
|
1347
|
-
this.emitType(undefined, AccessModifier.Internal, "static class", converterName, undefined, () => {
|
|
1348
|
-
// Do not use .Web as defaults. That turns on caseInsensitive property names and will fail the keywords test.
|
|
1349
|
-
this.emitLine("public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)");
|
|
1350
|
-
this.emitBlock(() => {
|
|
1351
|
-
// this.emitLine("MetadataPropertyHandling = MetadataPropertyHandling.Ignore,");
|
|
1352
|
-
// this.emitLine("DateParseHandling = DateParseHandling.None,");
|
|
1353
|
-
this.emitLine("Converters =");
|
|
1354
|
-
this.emitLine("{");
|
|
1355
|
-
this.indent(() => {
|
|
1356
|
-
for (const [t, converter] of this.typesWithNamedTransformations) {
|
|
1357
|
-
if (alwaysApplyTransformation((0, Support_1.defined)((0, Transformers_1.transformationForType)(t)))) {
|
|
1358
|
-
this.emitLine(this.converterObject(converter), ",");
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
this.emitLine("new DateOnlyConverter(),");
|
|
1362
|
-
this.emitLine("new TimeOnlyConverter(),");
|
|
1363
|
-
this.emitLine("IsoDateTimeOffsetConverter.Singleton");
|
|
1364
|
-
// this.emitLine("new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }");
|
|
1365
|
-
});
|
|
1366
|
-
this.emitLine(`},`);
|
|
1367
|
-
}, true);
|
|
1368
|
-
});
|
|
1369
|
-
}
|
|
1370
|
-
emitDecoderTransformerCase(tokenCases, variableName, xfer, targetType, emitFinish) {
|
|
1371
|
-
if (xfer === undefined)
|
|
1372
|
-
return;
|
|
1373
|
-
for (const tokenCase of tokenCases) {
|
|
1374
|
-
this.emitTokenCase(tokenCase);
|
|
1375
|
-
}
|
|
1376
|
-
this.indent(() => {
|
|
1377
|
-
const allHandled = this.emitDecodeTransformer(xfer, targetType, emitFinish, variableName);
|
|
1378
|
-
if (!allHandled) {
|
|
1379
|
-
this.emitLine("break;");
|
|
1380
|
-
}
|
|
1381
|
-
});
|
|
1382
|
-
}
|
|
1383
|
-
emitConsume(value, consumer, targetType, emitFinish) {
|
|
1384
|
-
if (consumer === undefined) {
|
|
1385
|
-
emitFinish(value);
|
|
1386
|
-
return true;
|
|
1387
|
-
}
|
|
1388
|
-
else {
|
|
1389
|
-
return this.emitTransformer(value, consumer, targetType, emitFinish);
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
emitDecodeTransformer(xfer, targetType, emitFinish, variableName = "value") {
|
|
1393
|
-
if (xfer instanceof Transformers_1.DecodingTransformer) {
|
|
1394
|
-
const source = xfer.sourceType;
|
|
1395
|
-
const converter = this.converterForType(targetType);
|
|
1396
|
-
if (converter !== undefined) {
|
|
1397
|
-
const typeSource = this.csType(targetType);
|
|
1398
|
-
this.emitLine("var converter = ", this.converterObject(converter), ";");
|
|
1399
|
-
this.emitLine("var ", variableName, " = (", typeSource, ")converter.ReadJson(reader, typeof(", typeSource, "), null, serializer);");
|
|
1400
|
-
}
|
|
1401
|
-
else if (source.kind !== "null") {
|
|
1402
|
-
let output = targetType.kind === "double" ? targetType : source;
|
|
1403
|
-
this.emitLine("var ", variableName, " = ", this.deserializeTypeCode(this.csType(output)), ";");
|
|
1404
|
-
}
|
|
1405
|
-
return this.emitConsume(variableName, xfer.consumer, targetType, emitFinish);
|
|
1406
|
-
}
|
|
1407
|
-
else if (xfer instanceof Transformers_1.ArrayDecodingTransformer) {
|
|
1408
|
-
// FIXME: Consume StartArray
|
|
1409
|
-
if (!(targetType instanceof Type_1.ArrayType)) {
|
|
1410
|
-
return (0, Support_1.panic)("Array decoding must produce an array type");
|
|
1411
|
-
}
|
|
1412
|
-
// FIXME: handle EOF
|
|
1413
|
-
this.emitLine("reader.Read();");
|
|
1414
|
-
this.emitLine("var ", variableName, " = new List<", this.csType(targetType.items), ">();");
|
|
1415
|
-
this.emitLine("while (reader.TokenType != JsonToken.EndArray)");
|
|
1416
|
-
this.emitBlock(() => {
|
|
1417
|
-
this.emitDecodeTransformer(xfer.itemTransformer, xfer.itemTargetType, v => this.emitLine(variableName, ".Add(", v, ");"), "arrayItem");
|
|
1418
|
-
// FIXME: handle EOF
|
|
1419
|
-
this.emitLine("reader.Read();");
|
|
1420
|
-
});
|
|
1421
|
-
let result = variableName;
|
|
1422
|
-
if (!this._options.useList) {
|
|
1423
|
-
result = [result, ".ToArray()"];
|
|
1424
|
-
}
|
|
1425
|
-
emitFinish(result);
|
|
1426
|
-
return true;
|
|
1427
|
-
}
|
|
1428
|
-
else if (xfer instanceof Transformers_1.DecodingChoiceTransformer) {
|
|
1429
|
-
this.emitDecoderSwitch(() => {
|
|
1430
|
-
const nullTransformer = xfer.nullTransformer;
|
|
1431
|
-
if (nullTransformer !== undefined) {
|
|
1432
|
-
this.emitTokenCase("Null");
|
|
1433
|
-
this.indent(() => {
|
|
1434
|
-
const allHandled = this.emitDecodeTransformer(nullTransformer, targetType, emitFinish, "null");
|
|
1435
|
-
if (!allHandled) {
|
|
1436
|
-
this.emitLine("break");
|
|
1437
|
-
}
|
|
1438
|
-
});
|
|
1439
|
-
}
|
|
1440
|
-
this.emitDecoderTransformerCase(["Number"], "integerValue", xfer.integerTransformer, targetType, emitFinish);
|
|
1441
|
-
this.emitDecoderTransformerCase(["Number"],
|
|
1442
|
-
// xfer.integerTransformer === undefined ? ["Integer", "Float"] : ["Float"],
|
|
1443
|
-
"doubleValue", xfer.doubleTransformer, targetType, emitFinish);
|
|
1444
|
-
this.emitDecoderTransformerCase(["True", "False"], "boolValue", xfer.boolTransformer, targetType, emitFinish);
|
|
1445
|
-
this.emitDecoderTransformerCase(
|
|
1446
|
-
// ["String", "Date"],
|
|
1447
|
-
["String"], "stringValue", xfer.stringTransformer, targetType, emitFinish);
|
|
1448
|
-
this.emitDecoderTransformerCase(["StartObject"], "objectValue", xfer.objectTransformer, targetType, emitFinish);
|
|
1449
|
-
this.emitDecoderTransformerCase(["StartArray"], "arrayValue", xfer.arrayTransformer, targetType, emitFinish);
|
|
1450
|
-
});
|
|
1451
|
-
return false;
|
|
1452
|
-
}
|
|
1453
|
-
else {
|
|
1454
|
-
return (0, Support_1.panic)("Unknown transformer");
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
stringCaseValue(t, stringCase) {
|
|
1458
|
-
if (t.kind === "string") {
|
|
1459
|
-
return ['"', (0, Strings_1.utf16StringEscape)(stringCase), '"'];
|
|
1460
|
-
}
|
|
1461
|
-
else if (t instanceof Type_1.EnumType) {
|
|
1462
|
-
return [this.nameForNamedType(t), ".", this.nameForEnumCase(t, stringCase)];
|
|
1463
|
-
}
|
|
1464
|
-
return (0, Support_1.panic)(`Type ${t.kind} does not have string cases`);
|
|
1465
|
-
}
|
|
1466
|
-
emitTransformer(variable, xfer, targetType, emitFinish) {
|
|
1467
|
-
function directTargetType(continuation) {
|
|
1468
|
-
if (continuation === undefined) {
|
|
1469
|
-
return targetType;
|
|
1470
|
-
}
|
|
1471
|
-
return (0, Transformers_1.followTargetType)(continuation.sourceType);
|
|
1472
|
-
}
|
|
1473
|
-
if (xfer instanceof Transformers_1.ChoiceTransformer) {
|
|
1474
|
-
const caseXfers = xfer.transformers;
|
|
1475
|
-
if (caseXfers.length > 1 && caseXfers.every(caseXfer => caseXfer instanceof Transformers_1.StringMatchTransformer)) {
|
|
1476
|
-
this.emitLine("switch (", variable, ")");
|
|
1477
|
-
this.emitBlock(() => {
|
|
1478
|
-
for (const caseXfer of caseXfers) {
|
|
1479
|
-
const matchXfer = caseXfer;
|
|
1480
|
-
const value = this.stringCaseValue((0, Transformers_1.followTargetType)(matchXfer.sourceType), matchXfer.stringCase);
|
|
1481
|
-
this.emitLine("case ", value, ":");
|
|
1482
|
-
this.indent(() => {
|
|
1483
|
-
const allDone = this.emitTransformer(variable, matchXfer.transformer, targetType, emitFinish);
|
|
1484
|
-
if (!allDone) {
|
|
1485
|
-
this.emitLine("break;");
|
|
1486
|
-
}
|
|
1487
|
-
});
|
|
1488
|
-
}
|
|
1489
|
-
});
|
|
1490
|
-
// FIXME: Can we check for exhaustiveness? For enums it should be easy.
|
|
1491
|
-
return false;
|
|
1492
|
-
}
|
|
1493
|
-
else {
|
|
1494
|
-
for (const caseXfer of caseXfers) {
|
|
1495
|
-
this.emitTransformer(variable, caseXfer, targetType, emitFinish);
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
else if (xfer instanceof Transformers_1.UnionMemberMatchTransformer) {
|
|
1500
|
-
const memberType = xfer.memberType;
|
|
1501
|
-
const maybeNullable = (0, TypeUtils_1.nullableFromUnion)(xfer.sourceType);
|
|
1502
|
-
let test;
|
|
1503
|
-
let member;
|
|
1504
|
-
if (maybeNullable !== null) {
|
|
1505
|
-
if (memberType.kind === "null") {
|
|
1506
|
-
test = [variable, " == null"];
|
|
1507
|
-
member = "null";
|
|
1508
|
-
}
|
|
1509
|
-
else {
|
|
1510
|
-
test = [variable, " != null"];
|
|
1511
|
-
member = variable;
|
|
1512
|
-
}
|
|
1513
|
-
}
|
|
1514
|
-
else if (memberType.kind === "null") {
|
|
1515
|
-
test = [variable, ".IsNull"];
|
|
1516
|
-
member = "null";
|
|
1517
|
-
}
|
|
1518
|
-
else {
|
|
1519
|
-
const memberName = this.nameForUnionMember(xfer.sourceType, memberType);
|
|
1520
|
-
member = [variable, ".", memberName];
|
|
1521
|
-
test = [member, " != null"];
|
|
1522
|
-
}
|
|
1523
|
-
if (memberType.kind !== "null" && isValueType(memberType)) {
|
|
1524
|
-
member = [member, ".Value"];
|
|
1525
|
-
}
|
|
1526
|
-
this.emitLine("if (", test, ")");
|
|
1527
|
-
this.emitBlock(() => this.emitTransformer(member, xfer.transformer, targetType, emitFinish));
|
|
1528
|
-
}
|
|
1529
|
-
else if (xfer instanceof Transformers_1.StringMatchTransformer) {
|
|
1530
|
-
const value = this.stringCaseValue((0, Transformers_1.followTargetType)(xfer.sourceType), xfer.stringCase);
|
|
1531
|
-
this.emitLine("if (", variable, " == ", value, ")");
|
|
1532
|
-
this.emitBlock(() => this.emitTransformer(variable, xfer.transformer, targetType, emitFinish));
|
|
1533
|
-
}
|
|
1534
|
-
else if (xfer instanceof Transformers_1.EncodingTransformer) {
|
|
1535
|
-
const converter = this.converterForType(xfer.sourceType);
|
|
1536
|
-
if (converter !== undefined) {
|
|
1537
|
-
this.emitLine("var converter = ", this.converterObject(converter), ";");
|
|
1538
|
-
this.emitLine("converter.WriteJson(writer, ", variable, ", serializer);");
|
|
1539
|
-
}
|
|
1540
|
-
else {
|
|
1541
|
-
this.emitLine(this.serializeValueCode(variable), ";");
|
|
1542
|
-
}
|
|
1543
|
-
emitFinish([]);
|
|
1544
|
-
return true;
|
|
1545
|
-
}
|
|
1546
|
-
else if (xfer instanceof Transformers_1.ArrayEncodingTransformer) {
|
|
1547
|
-
this.emitLine("writer.WriteStartArray();");
|
|
1548
|
-
const itemVariable = "arrayItem";
|
|
1549
|
-
this.emitLine("foreach (var ", itemVariable, " in ", variable, ")");
|
|
1550
|
-
this.emitBlock(() => {
|
|
1551
|
-
this.emitTransformer(itemVariable, xfer.itemTransformer, xfer.itemTargetType, () => {
|
|
1552
|
-
return;
|
|
1553
|
-
});
|
|
1554
|
-
});
|
|
1555
|
-
this.emitLine("writer.WriteEndArray();");
|
|
1556
|
-
emitFinish([]);
|
|
1557
|
-
return true;
|
|
1558
|
-
}
|
|
1559
|
-
else if (xfer instanceof Transformers_1.ParseStringTransformer) {
|
|
1560
|
-
const immediateTargetType = xfer.consumer === undefined ? targetType : xfer.consumer.sourceType;
|
|
1561
|
-
switch (immediateTargetType.kind) {
|
|
1562
|
-
case "date-time":
|
|
1563
|
-
this.emitLine("DateTimeOffset dt;");
|
|
1564
|
-
this.emitLine("if (DateTimeOffset.TryParse(", variable, ", out dt))");
|
|
1565
|
-
this.emitBlock(() => this.emitConsume("dt", xfer.consumer, targetType, emitFinish));
|
|
1566
|
-
break;
|
|
1567
|
-
case "uuid":
|
|
1568
|
-
this.emitLine("Guid guid;");
|
|
1569
|
-
this.emitLine("if (Guid.TryParse(", variable, ", out guid))");
|
|
1570
|
-
this.emitBlock(() => this.emitConsume("guid", xfer.consumer, targetType, emitFinish));
|
|
1571
|
-
break;
|
|
1572
|
-
case "uri":
|
|
1573
|
-
this.emitLine("try");
|
|
1574
|
-
this.emitBlock(() => {
|
|
1575
|
-
// this.emitLine("var uri = new Uri(", variable, ");");
|
|
1576
|
-
// The default value about:blank should never happen, but this way we avoid a null reference warning.
|
|
1577
|
-
this.emitLine('var uri = new Uri("about:blank");');
|
|
1578
|
-
this.emitLine("if (!string.IsNullOrEmpty(stringValue))");
|
|
1579
|
-
this.emitBlock(() => {
|
|
1580
|
-
this.emitLine("uri = new Uri(", variable, ");");
|
|
1581
|
-
});
|
|
1582
|
-
this.emitConsume("uri", xfer.consumer, targetType, emitFinish);
|
|
1583
|
-
});
|
|
1584
|
-
this.emitLine("catch (UriFormatException) {}");
|
|
1585
|
-
break;
|
|
1586
|
-
case "integer":
|
|
1587
|
-
this.emitLine("long l;");
|
|
1588
|
-
this.emitLine("if (Int64.TryParse(", variable, ", out l))");
|
|
1589
|
-
this.emitBlock(() => this.emitConsume("l", xfer.consumer, targetType, emitFinish));
|
|
1590
|
-
break;
|
|
1591
|
-
case "bool":
|
|
1592
|
-
this.emitLine("bool b;");
|
|
1593
|
-
this.emitLine("if (Boolean.TryParse(", variable, ", out b))");
|
|
1594
|
-
this.emitBlock(() => this.emitConsume("b", xfer.consumer, targetType, emitFinish));
|
|
1595
|
-
break;
|
|
1596
|
-
default:
|
|
1597
|
-
return (0, Support_1.panic)(`Parsing string to ${immediateTargetType.kind} not supported`);
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
else if (xfer instanceof Transformers_1.StringifyTransformer) {
|
|
1601
|
-
switch (xfer.sourceType.kind) {
|
|
1602
|
-
case "date-time":
|
|
1603
|
-
return this.emitConsume([variable, '.ToString("o", System.Globalization.CultureInfo.InvariantCulture)'], xfer.consumer, targetType, emitFinish);
|
|
1604
|
-
case "uuid":
|
|
1605
|
-
return this.emitConsume([variable, '.ToString("D", System.Globalization.CultureInfo.InvariantCulture)'], xfer.consumer, targetType, emitFinish);
|
|
1606
|
-
case "integer":
|
|
1607
|
-
case "uri":
|
|
1608
|
-
return this.emitConsume([variable, ".ToString()"], xfer.consumer, targetType, emitFinish);
|
|
1609
|
-
case "bool":
|
|
1610
|
-
this.emitLine("var boolString = ", variable, ' ? "true" : "false";');
|
|
1611
|
-
return this.emitConsume("boolString", xfer.consumer, targetType, emitFinish);
|
|
1612
|
-
default:
|
|
1613
|
-
return (0, Support_1.panic)(`Stringifying ${xfer.sourceType.kind} not supported`);
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
else if (xfer instanceof Transformers_1.StringProducerTransformer) {
|
|
1617
|
-
const value = this.stringCaseValue(directTargetType(xfer.consumer), xfer.result);
|
|
1618
|
-
return this.emitConsume(value, xfer.consumer, targetType, emitFinish);
|
|
1619
|
-
}
|
|
1620
|
-
else if (xfer instanceof Transformers_1.MinMaxLengthCheckTransformer) {
|
|
1621
|
-
const min = xfer.minLength;
|
|
1622
|
-
const max = xfer.maxLength;
|
|
1623
|
-
const conditions = [];
|
|
1624
|
-
if (min !== undefined) {
|
|
1625
|
-
conditions.push([variable, ".Length >= ", min.toString()]);
|
|
1626
|
-
}
|
|
1627
|
-
if (max !== undefined) {
|
|
1628
|
-
conditions.push([variable, ".Length <= ", max.toString()]);
|
|
1629
|
-
}
|
|
1630
|
-
this.emitLine("if (", (0, collection_utils_1.arrayIntercalate)([" && "], conditions), ")");
|
|
1631
|
-
this.emitBlock(() => this.emitConsume(variable, xfer.consumer, targetType, emitFinish));
|
|
1632
|
-
return false;
|
|
1633
|
-
}
|
|
1634
|
-
else if (xfer instanceof Transformers_1.MinMaxValueTransformer) {
|
|
1635
|
-
const min = xfer.minimum;
|
|
1636
|
-
const max = xfer.maximum;
|
|
1637
|
-
const conditions = [];
|
|
1638
|
-
if (min !== undefined) {
|
|
1639
|
-
conditions.push([variable, " >= ", min.toString()]);
|
|
1640
|
-
}
|
|
1641
|
-
if (max !== undefined) {
|
|
1642
|
-
conditions.push([variable, " <= ", max.toString()]);
|
|
1643
|
-
}
|
|
1644
|
-
this.emitLine("if (", (0, collection_utils_1.arrayIntercalate)([" && "], conditions), ")");
|
|
1645
|
-
this.emitBlock(() => this.emitConsume(variable, xfer.consumer, targetType, emitFinish));
|
|
1646
|
-
return false;
|
|
1647
|
-
}
|
|
1648
|
-
else if (xfer instanceof Transformers_1.UnionInstantiationTransformer) {
|
|
1649
|
-
if (!(targetType instanceof Type_1.UnionType)) {
|
|
1650
|
-
return (0, Support_1.panic)("Union instantiation transformer must produce a union type");
|
|
1651
|
-
}
|
|
1652
|
-
const maybeNullable = (0, TypeUtils_1.nullableFromUnion)(targetType);
|
|
1653
|
-
if (maybeNullable !== null) {
|
|
1654
|
-
emitFinish(variable);
|
|
1655
|
-
}
|
|
1656
|
-
else {
|
|
1657
|
-
const unionName = this.nameForNamedType(targetType);
|
|
1658
|
-
let initializer;
|
|
1659
|
-
if (xfer.sourceType.kind === "null") {
|
|
1660
|
-
initializer = " ";
|
|
1661
|
-
}
|
|
1662
|
-
else {
|
|
1663
|
-
const memberName = this.nameForUnionMember(targetType, xfer.sourceType);
|
|
1664
|
-
initializer = [" ", memberName, " = ", variable, " "];
|
|
1665
|
-
}
|
|
1666
|
-
emitFinish(["new ", unionName, " {", initializer, "}"]);
|
|
1667
|
-
}
|
|
1668
|
-
return true;
|
|
1669
|
-
}
|
|
1670
|
-
else {
|
|
1671
|
-
return (0, Support_1.panic)("Unknown transformer");
|
|
1672
|
-
}
|
|
1673
|
-
return false;
|
|
1674
|
-
}
|
|
1675
|
-
emitTransformation(converterName, t) {
|
|
1676
|
-
const xf = (0, Support_1.defined)((0, Transformers_1.transformationForType)(t));
|
|
1677
|
-
const reverse = xf.reverse;
|
|
1678
|
-
const targetType = xf.targetType;
|
|
1679
|
-
const xfer = xf.transformer;
|
|
1680
|
-
const csType = this.csType(targetType);
|
|
1681
|
-
// const haveNullable = isValueType(targetType);
|
|
1682
|
-
// if (haveNullable) {
|
|
1683
|
-
// converterName = ['Nullable', converterName];
|
|
1684
|
-
// csType = [csType, "?"];
|
|
1685
|
-
// }
|
|
1686
|
-
this.emitType(undefined, AccessModifier.Internal, "class", converterName, ["JsonConverter<", csType, ">"], () => {
|
|
1687
|
-
let canConvertExpr = ["t == typeof(", csType, ")"];
|
|
1688
|
-
this.emitCanConvert(canConvertExpr);
|
|
1689
|
-
this.ensureBlankLine();
|
|
1690
|
-
this.emitReadJson(() => {
|
|
1691
|
-
// FIXME: It's unsatisfying that we need this. The reason is that we not
|
|
1692
|
-
// only match T, but also T?. If we didn't, then the T in T? would not be
|
|
1693
|
-
// deserialized with our converter but with the default one. Can we check
|
|
1694
|
-
// whether the type is a nullable?
|
|
1695
|
-
// FIXME: This could duplicate one of the cases handled below in
|
|
1696
|
-
// `emitDecodeTransformer`.
|
|
1697
|
-
// if (haveNullable && !(targetType instanceof UnionType)) {
|
|
1698
|
-
// this.emitLine("if (reader.TokenType == JsonTokenType.Null) return null;");
|
|
1699
|
-
// }
|
|
1700
|
-
const allHandled = this.emitDecodeTransformer(xfer, targetType, v => this.emitLine("return ", v, ";"));
|
|
1701
|
-
if (!allHandled) {
|
|
1702
|
-
this.emitThrow(['"Cannot unmarshal type ', csType, '"']);
|
|
1703
|
-
}
|
|
1704
|
-
}, csType);
|
|
1705
|
-
this.ensureBlankLine();
|
|
1706
|
-
this.emitWriteJson("value", () => {
|
|
1707
|
-
// FIXME: See above.
|
|
1708
|
-
// if (haveNullable && !(targetType instanceof UnionType)) {
|
|
1709
|
-
// this.emitLine("if (value == null)");
|
|
1710
|
-
// this.emitBlock(() => {
|
|
1711
|
-
// this.emitLine("writer.WriteNullValue();");
|
|
1712
|
-
// this.emitLine("return;");
|
|
1713
|
-
// });
|
|
1714
|
-
// }
|
|
1715
|
-
const allHandled = this.emitTransformer("value", reverse.transformer, reverse.targetType, () => this.emitLine("return;"));
|
|
1716
|
-
if (!allHandled) {
|
|
1717
|
-
this.emitThrow(['"Cannot marshal type ', csType, '"']);
|
|
1718
|
-
}
|
|
1719
|
-
}, csType);
|
|
1720
|
-
this.ensureBlankLine();
|
|
1721
|
-
this.emitLine("public static readonly ", converterName, " Singleton = new ", converterName, "();");
|
|
1722
|
-
});
|
|
1723
|
-
}
|
|
1724
|
-
emitRequiredHelpers() {
|
|
1725
|
-
if (this._needHelpers) {
|
|
1726
|
-
this.forEachTopLevel("leading-and-interposing", (t, n) => this.emitFromJsonForTopLevel(t, n));
|
|
1727
|
-
this.ensureBlankLine();
|
|
1728
|
-
this.emitSerializeClass();
|
|
1729
|
-
}
|
|
1730
|
-
if (this._needHelpers || (this._needAttributes && (this.haveNamedUnions || this.haveEnums))) {
|
|
1731
|
-
this.ensureBlankLine();
|
|
1732
|
-
this.emitConverterClass();
|
|
1733
|
-
this.forEachTransformation("leading-and-interposing", (n, t) => this.emitTransformation(n, t));
|
|
1734
|
-
this.emitMultiline(`
|
|
1735
|
-
public class DateOnlyConverter : JsonConverter<DateOnly>
|
|
1736
|
-
{
|
|
1737
|
-
private readonly string serializationFormat;
|
|
1738
|
-
public DateOnlyConverter() : this(null) { }
|
|
1739
|
-
|
|
1740
|
-
public DateOnlyConverter(string? serializationFormat)
|
|
1741
|
-
{
|
|
1742
|
-
this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
|
-
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
1746
|
-
{
|
|
1747
|
-
var value = reader.GetString();
|
|
1748
|
-
return DateOnly.Parse(value!);
|
|
1749
|
-
}
|
|
1750
|
-
|
|
1751
|
-
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
|
|
1752
|
-
=> writer.WriteStringValue(value.ToString(serializationFormat));
|
|
1753
|
-
}
|
|
1754
|
-
|
|
1755
|
-
public class TimeOnlyConverter : JsonConverter<TimeOnly>
|
|
1756
|
-
{
|
|
1757
|
-
private readonly string serializationFormat;
|
|
1758
|
-
|
|
1759
|
-
public TimeOnlyConverter() : this(null) { }
|
|
1760
|
-
|
|
1761
|
-
public TimeOnlyConverter(string? serializationFormat)
|
|
1762
|
-
{
|
|
1763
|
-
this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
|
|
1764
|
-
}
|
|
1765
|
-
|
|
1766
|
-
public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
1767
|
-
{
|
|
1768
|
-
var value = reader.GetString();
|
|
1769
|
-
return TimeOnly.Parse(value!);
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
|
-
public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
|
|
1773
|
-
=> writer.WriteStringValue(value.ToString(serializationFormat));
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
|
-
internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
|
|
1777
|
-
{
|
|
1778
|
-
public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);
|
|
1779
|
-
|
|
1780
|
-
private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
|
|
1781
|
-
|
|
1782
|
-
private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
|
|
1783
|
-
private string? _dateTimeFormat;
|
|
1784
|
-
private CultureInfo? _culture;
|
|
1785
|
-
|
|
1786
|
-
public DateTimeStyles DateTimeStyles
|
|
1787
|
-
{
|
|
1788
|
-
get => _dateTimeStyles;
|
|
1789
|
-
set => _dateTimeStyles = value;
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
|
-
public string? DateTimeFormat
|
|
1793
|
-
{
|
|
1794
|
-
get => _dateTimeFormat ?? string.Empty;
|
|
1795
|
-
set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
|
|
1796
|
-
}
|
|
1797
|
-
|
|
1798
|
-
public CultureInfo Culture
|
|
1799
|
-
{
|
|
1800
|
-
get => _culture ?? CultureInfo.CurrentCulture;
|
|
1801
|
-
set => _culture = value;
|
|
1802
|
-
}
|
|
1803
|
-
|
|
1804
|
-
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
|
|
1805
|
-
{
|
|
1806
|
-
string text;
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
|
|
1810
|
-
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
|
|
1811
|
-
{
|
|
1812
|
-
value = value.ToUniversalTime();
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
|
-
text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
|
|
1816
|
-
|
|
1817
|
-
writer.WriteStringValue(text);
|
|
1818
|
-
}
|
|
1819
|
-
|
|
1820
|
-
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
1821
|
-
{
|
|
1822
|
-
string? dateText = reader.GetString();
|
|
1823
|
-
|
|
1824
|
-
if (string.IsNullOrEmpty(dateText) == false)
|
|
1825
|
-
{
|
|
1826
|
-
if (!string.IsNullOrEmpty(_dateTimeFormat))
|
|
1827
|
-
{
|
|
1828
|
-
return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
|
|
1829
|
-
}
|
|
1830
|
-
else
|
|
1831
|
-
{
|
|
1832
|
-
return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1835
|
-
else
|
|
1836
|
-
{
|
|
1837
|
-
return default(DateTimeOffset);
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
|
|
1843
|
-
}`);
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
needNamespace() {
|
|
1847
|
-
return this._needNamespaces;
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
exports.SystemTextJsonCSharpRenderer = SystemTextJsonCSharpRenderer;
|