quicktype 18.0.6 → 19.0.4
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} +1 -1
- package/dist/{cli/index.js → index.js} +4 -5
- 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,777 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ObjectiveCRenderer = exports.ObjectiveCTargetLanguage = exports.objcOptions = void 0;
|
|
4
|
-
const collection_utils_1 = require("collection-utils");
|
|
5
|
-
const TargetLanguage_1 = require("../TargetLanguage");
|
|
6
|
-
const Type_1 = require("../Type");
|
|
7
|
-
const TypeUtils_1 = require("../TypeUtils");
|
|
8
|
-
const Naming_1 = require("../Naming");
|
|
9
|
-
const Source_1 = require("../Source");
|
|
10
|
-
const Strings_1 = require("../support/Strings");
|
|
11
|
-
const ConvenienceRenderer_1 = require("../ConvenienceRenderer");
|
|
12
|
-
const RendererOptions_1 = require("../RendererOptions");
|
|
13
|
-
const Support_1 = require("../support/Support");
|
|
14
|
-
const unicode = require("unicode-properties");
|
|
15
|
-
const DEBUG = false;
|
|
16
|
-
const DEFAULT_CLASS_PREFIX = "QT";
|
|
17
|
-
exports.objcOptions = {
|
|
18
|
-
features: new RendererOptions_1.EnumOption("features", "Interface and implementation", [
|
|
19
|
-
["all", { interface: true, implementation: true }],
|
|
20
|
-
["interface", { interface: true, implementation: false }],
|
|
21
|
-
["implementation", { interface: false, implementation: true }]
|
|
22
|
-
]),
|
|
23
|
-
justTypes: new RendererOptions_1.BooleanOption("just-types", "Plain types only", false),
|
|
24
|
-
marshallingFunctions: new RendererOptions_1.BooleanOption("functions", "C-style functions", false),
|
|
25
|
-
classPrefix: new RendererOptions_1.StringOption("class-prefix", "Class prefix", "PREFIX", DEFAULT_CLASS_PREFIX),
|
|
26
|
-
extraComments: new RendererOptions_1.BooleanOption("extra-comments", "Extra comments", false)
|
|
27
|
-
};
|
|
28
|
-
class ObjectiveCTargetLanguage extends TargetLanguage_1.TargetLanguage {
|
|
29
|
-
constructor() {
|
|
30
|
-
super("Objective-C", ["objc", "objective-c", "objectivec"], "m");
|
|
31
|
-
}
|
|
32
|
-
getOptions() {
|
|
33
|
-
return [
|
|
34
|
-
exports.objcOptions.justTypes,
|
|
35
|
-
exports.objcOptions.classPrefix,
|
|
36
|
-
exports.objcOptions.features,
|
|
37
|
-
exports.objcOptions.extraComments,
|
|
38
|
-
exports.objcOptions.marshallingFunctions
|
|
39
|
-
];
|
|
40
|
-
}
|
|
41
|
-
makeRenderer(renderContext, untypedOptionValues) {
|
|
42
|
-
return new ObjectiveCRenderer(this, renderContext, (0, RendererOptions_1.getOptionValues)(exports.objcOptions, untypedOptionValues));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
exports.ObjectiveCTargetLanguage = ObjectiveCTargetLanguage;
|
|
46
|
-
function typeNameStyle(prefix, original) {
|
|
47
|
-
const words = (0, Strings_1.splitIntoWords)(original);
|
|
48
|
-
const result = (0, Strings_1.combineWords)(words, legalizeName, Strings_1.firstUpperWordStyle, Strings_1.firstUpperWordStyle, Strings_1.allUpperWordStyle, Strings_1.allUpperWordStyle, "", isStartCharacter);
|
|
49
|
-
return (0, Strings_1.addPrefixIfNecessary)(prefix, result);
|
|
50
|
-
}
|
|
51
|
-
function propertyNameStyle(original, isBool = false) {
|
|
52
|
-
// Objective-C developers are uncomfortable with property "id"
|
|
53
|
-
// so we use an alternate name in this special case.
|
|
54
|
-
if (original === "id") {
|
|
55
|
-
original = "identifier";
|
|
56
|
-
}
|
|
57
|
-
let words = (0, Strings_1.splitIntoWords)(original);
|
|
58
|
-
if (isBool) {
|
|
59
|
-
if (words.length === 0) {
|
|
60
|
-
words = [{ word: "flag", isAcronym: false }];
|
|
61
|
-
}
|
|
62
|
-
else if (!words[0].isAcronym && booleanPrefixes.indexOf(words[0].word) < 0) {
|
|
63
|
-
words = [{ word: "is", isAcronym: false }, ...words];
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
// Properties cannot even begin with any of the forbidden names
|
|
67
|
-
// For example, properies named new* are treated differently by ARC
|
|
68
|
-
if (words.length > 0 && forbiddenPropertyNames.indexOf(words[0].word) >= 0) {
|
|
69
|
-
words = [{ word: "the", isAcronym: false }, ...words];
|
|
70
|
-
}
|
|
71
|
-
return (0, Strings_1.combineWords)(words, legalizeName, Strings_1.allLowerWordStyle, Strings_1.firstUpperWordStyle, Strings_1.allLowerWordStyle, Strings_1.allUpperWordStyle, "", isStartCharacter);
|
|
72
|
-
}
|
|
73
|
-
const keywords = [
|
|
74
|
-
/*
|
|
75
|
-
"_Bool",
|
|
76
|
-
"_Complex",
|
|
77
|
-
"_Imaginary",
|
|
78
|
-
*/
|
|
79
|
-
"asm",
|
|
80
|
-
"atomic",
|
|
81
|
-
"auto",
|
|
82
|
-
"bool",
|
|
83
|
-
"break",
|
|
84
|
-
"case",
|
|
85
|
-
"char",
|
|
86
|
-
"const",
|
|
87
|
-
"continue",
|
|
88
|
-
"default",
|
|
89
|
-
"do",
|
|
90
|
-
"double",
|
|
91
|
-
"else",
|
|
92
|
-
"enum",
|
|
93
|
-
"extern",
|
|
94
|
-
"false",
|
|
95
|
-
"float",
|
|
96
|
-
"for",
|
|
97
|
-
"goto",
|
|
98
|
-
"if",
|
|
99
|
-
"inline",
|
|
100
|
-
"int",
|
|
101
|
-
"long",
|
|
102
|
-
"nil",
|
|
103
|
-
"nonatomic",
|
|
104
|
-
"register",
|
|
105
|
-
"restrict",
|
|
106
|
-
"retain",
|
|
107
|
-
"return",
|
|
108
|
-
"short",
|
|
109
|
-
"signed",
|
|
110
|
-
"sizeof",
|
|
111
|
-
"static",
|
|
112
|
-
"struct",
|
|
113
|
-
"switch",
|
|
114
|
-
"typedef",
|
|
115
|
-
"typeof",
|
|
116
|
-
"true",
|
|
117
|
-
"union",
|
|
118
|
-
"unsigned",
|
|
119
|
-
"void",
|
|
120
|
-
"volatile",
|
|
121
|
-
"while"
|
|
122
|
-
];
|
|
123
|
-
const forbiddenPropertyNames = [
|
|
124
|
-
"id",
|
|
125
|
-
"hash",
|
|
126
|
-
"description",
|
|
127
|
-
"init",
|
|
128
|
-
"copy",
|
|
129
|
-
"mutableCopy",
|
|
130
|
-
"superclass",
|
|
131
|
-
"debugDescription",
|
|
132
|
-
"new"
|
|
133
|
-
];
|
|
134
|
-
const booleanPrefixes = [
|
|
135
|
-
"is",
|
|
136
|
-
"are",
|
|
137
|
-
"were",
|
|
138
|
-
"was",
|
|
139
|
-
"will",
|
|
140
|
-
"all",
|
|
141
|
-
"some",
|
|
142
|
-
"many",
|
|
143
|
-
"has",
|
|
144
|
-
"have",
|
|
145
|
-
"had",
|
|
146
|
-
"does",
|
|
147
|
-
"do",
|
|
148
|
-
"requires",
|
|
149
|
-
"require",
|
|
150
|
-
"needs",
|
|
151
|
-
"need"
|
|
152
|
-
];
|
|
153
|
-
function isStartCharacter(utf16Unit) {
|
|
154
|
-
return unicode.isAlphabetic(utf16Unit) || utf16Unit === 0x5f; // underscore
|
|
155
|
-
}
|
|
156
|
-
function isPartCharacter(utf16Unit) {
|
|
157
|
-
const category = unicode.getCategory(utf16Unit);
|
|
158
|
-
return ["Nd", "Pc", "Mn", "Mc"].indexOf(category) >= 0 || isStartCharacter(utf16Unit);
|
|
159
|
-
}
|
|
160
|
-
const legalizeName = (0, Strings_1.utf16LegalizeCharacters)(isPartCharacter);
|
|
161
|
-
const staticEnumValuesIdentifier = "values";
|
|
162
|
-
const forbiddenForEnumCases = ["new", staticEnumValuesIdentifier];
|
|
163
|
-
function splitExtension(filename) {
|
|
164
|
-
const i = filename.lastIndexOf(".");
|
|
165
|
-
const extension = i !== -1 ? filename.split(".").pop() : "m";
|
|
166
|
-
filename = i !== -1 ? filename.slice(0, i) : filename;
|
|
167
|
-
return [filename, extension === undefined ? "m" : extension];
|
|
168
|
-
}
|
|
169
|
-
class ObjectiveCRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
170
|
-
_options;
|
|
171
|
-
_currentFilename;
|
|
172
|
-
_classPrefix;
|
|
173
|
-
constructor(targetLanguage, renderContext, _options) {
|
|
174
|
-
super(targetLanguage, renderContext);
|
|
175
|
-
this._options = _options;
|
|
176
|
-
// Infer the class prefix from a top-level name if it's not given
|
|
177
|
-
if (_options.classPrefix === DEFAULT_CLASS_PREFIX) {
|
|
178
|
-
const aTopLevel = (0, Support_1.defined)((0, collection_utils_1.iterableFirst)(this.topLevels.keys()));
|
|
179
|
-
this._classPrefix = this.inferClassPrefix(aTopLevel);
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
this._classPrefix = _options.classPrefix;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
inferClassPrefix(name) {
|
|
186
|
-
const l = name.length;
|
|
187
|
-
let firstNonUpper = 0;
|
|
188
|
-
while (firstNonUpper < l && (0, Strings_1.fastIsUpperCase)(name.charCodeAt(firstNonUpper))) {
|
|
189
|
-
firstNonUpper += 1;
|
|
190
|
-
}
|
|
191
|
-
if (firstNonUpper < 2)
|
|
192
|
-
return DEFAULT_CLASS_PREFIX;
|
|
193
|
-
return name.slice(0, firstNonUpper - 1);
|
|
194
|
-
}
|
|
195
|
-
forbiddenNamesForGlobalNamespace() {
|
|
196
|
-
return keywords;
|
|
197
|
-
}
|
|
198
|
-
forbiddenForObjectProperties(_c, _className) {
|
|
199
|
-
return { names: forbiddenPropertyNames, includeGlobalForbidden: true };
|
|
200
|
-
}
|
|
201
|
-
forbiddenForEnumCases(_e, _enumName) {
|
|
202
|
-
return { names: forbiddenForEnumCases, includeGlobalForbidden: true };
|
|
203
|
-
}
|
|
204
|
-
makeNamedTypeNamer() {
|
|
205
|
-
return (0, Naming_1.funPrefixNamer)("types", rawName => typeNameStyle(this._classPrefix, rawName));
|
|
206
|
-
}
|
|
207
|
-
namerForObjectProperty(_, p) {
|
|
208
|
-
// TODO why is underscore being removed?
|
|
209
|
-
return new Naming_1.Namer("properties", s => propertyNameStyle(s, p.type.kind === "bool"), [
|
|
210
|
-
"_",
|
|
211
|
-
"the",
|
|
212
|
-
"one",
|
|
213
|
-
"some",
|
|
214
|
-
"another"
|
|
215
|
-
]);
|
|
216
|
-
}
|
|
217
|
-
makeUnionMemberNamer() {
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
makeEnumCaseNamer() {
|
|
221
|
-
return new Naming_1.Namer("enum-cases", propertyNameStyle, []);
|
|
222
|
-
}
|
|
223
|
-
namedTypeToNameForTopLevel(type) {
|
|
224
|
-
return type;
|
|
225
|
-
}
|
|
226
|
-
emitDescriptionBlock(lines) {
|
|
227
|
-
this.emitCommentLines(lines, "/// ");
|
|
228
|
-
}
|
|
229
|
-
emitBlock(line, f) {
|
|
230
|
-
this.emitLine(line, " {");
|
|
231
|
-
this.indent(f);
|
|
232
|
-
this.emitLine("}");
|
|
233
|
-
}
|
|
234
|
-
emitMethod(declaration, f) {
|
|
235
|
-
this.emitLine(declaration);
|
|
236
|
-
this.emitLine("{");
|
|
237
|
-
this.indent(f);
|
|
238
|
-
this.emitLine("}");
|
|
239
|
-
}
|
|
240
|
-
emitExtraComments(...comments) {
|
|
241
|
-
if (!this._options.extraComments)
|
|
242
|
-
return;
|
|
243
|
-
for (const comment of comments) {
|
|
244
|
-
this.emitLine("// ", comment);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
startFile(basename, extension) {
|
|
248
|
-
(0, Support_1.assert)(this._currentFilename === undefined, "Previous file wasn't finished");
|
|
249
|
-
// FIXME: The filenames should actually be Sourcelikes, too
|
|
250
|
-
this._currentFilename = `${this.sourcelikeToString(basename)}.${extension}`;
|
|
251
|
-
}
|
|
252
|
-
finishFile() {
|
|
253
|
-
super.finishFile((0, Support_1.defined)(this._currentFilename));
|
|
254
|
-
this._currentFilename = undefined;
|
|
255
|
-
}
|
|
256
|
-
memoryAttribute(t, isNullable) {
|
|
257
|
-
return (0, TypeUtils_1.matchType)(t, _anyType => "copy", _nullType => "copy", _boolType => (isNullable ? "strong" : "assign"), _integerType => (isNullable ? "strong" : "assign"), _doubleType => (isNullable ? "strong" : "assign"), _stringType => "copy", _arrayType => "copy", _classType => "strong", _mapType => "copy", _enumType => "assign", unionType => {
|
|
258
|
-
const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
|
|
259
|
-
return nullable !== null ? this.memoryAttribute(nullable, true) : "copy";
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
objcType(t, nullableOrBoxed = false) {
|
|
263
|
-
return (0, TypeUtils_1.matchType)(t, _anyType => ["id", ""],
|
|
264
|
-
// For now, we're treating nulls just like any
|
|
265
|
-
_nullType => ["id", ""], _boolType => (nullableOrBoxed ? ["NSNumber", " *"] : ["BOOL", ""]), _integerType => (nullableOrBoxed ? ["NSNumber", " *"] : ["NSInteger", ""]), _doubleType => (nullableOrBoxed ? ["NSNumber", " *"] : ["double", ""]), _stringType => ["NSString", " *"], arrayType => {
|
|
266
|
-
const itemType = arrayType.items;
|
|
267
|
-
const itemTypeName = this.objcType(itemType, true);
|
|
268
|
-
// NSArray<id>* === NSArray*
|
|
269
|
-
if ((0, TypeUtils_1.isAnyOrNull)(itemType)) {
|
|
270
|
-
return ["NSArray", " *"];
|
|
271
|
-
}
|
|
272
|
-
return [["NSArray<", itemTypeName, ">"], " *"];
|
|
273
|
-
}, classType => [this.nameForNamedType(classType), " *"], mapType => [["NSDictionary<NSString *, ", this.objcType(mapType.values, true), ">"], " *"], enumType => [this.nameForNamedType(enumType), " *"], unionType => {
|
|
274
|
-
const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
|
|
275
|
-
return nullable !== null ? this.objcType(nullable, true) : ["id", ""];
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
jsonType(t) {
|
|
279
|
-
return (0, TypeUtils_1.matchType)(t, _anyType => ["id", ""],
|
|
280
|
-
// For now, we're treating nulls just like any
|
|
281
|
-
_nullType => ["id", ""], _boolType => ["NSNumber", " *"], _integerType => ["NSNumber", " *"], _doubleType => ["NSNumber", " *"], _stringType => ["NSString", " *"], _arrayType => ["NSArray", " *"], _classType => ["NSDictionary<NSString *, id>", " *"], mapType => [["NSDictionary<NSString *, ", this.jsonType(mapType.values), ">"], " *"], _enumType => ["NSString", " *"], unionType => {
|
|
282
|
-
const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
|
|
283
|
-
return nullable !== null ? this.jsonType(nullable) : ["id", ""];
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
fromDynamicExpression(t, ...dynamic) {
|
|
287
|
-
return (0, TypeUtils_1.matchType)(t, _anyType => dynamic, _nullType => dynamic, _boolType => dynamic, _integerType => dynamic, _doubleType => dynamic, _stringType => dynamic, arrayType => ["map(", dynamic, ", λ(id x, ", this.fromDynamicExpression(arrayType.items, "x"), "))"], classType => ["[", this.nameForNamedType(classType), " fromJSONDictionary:", dynamic, "]"], mapType => ["map(", dynamic, ", λ(id x, ", this.fromDynamicExpression(mapType.values, "x"), "))"], enumType => ["[", this.nameForNamedType(enumType), " withValue:", dynamic, "]"], unionType => {
|
|
288
|
-
const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
|
|
289
|
-
return nullable !== null ? this.fromDynamicExpression(nullable, dynamic) : dynamic;
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
toDynamicExpression(t, typed) {
|
|
293
|
-
return (0, TypeUtils_1.matchType)(t, _anyType => ["NSNullify(", typed, ")"], _nullType => ["NSNullify(", typed, ")"],
|
|
294
|
-
// Sadly, KVC
|
|
295
|
-
_boolType => [typed, ` ? @YES : @NO`], _integerType => typed, _doubleType => typed, _stringType => typed, arrayType => {
|
|
296
|
-
if (this.implicitlyConvertsFromJSON(arrayType)) {
|
|
297
|
-
// TODO check each value type
|
|
298
|
-
return typed;
|
|
299
|
-
}
|
|
300
|
-
return ["map(", typed, ", λ(id x, ", this.toDynamicExpression(arrayType.items, "x"), "))"];
|
|
301
|
-
}, _classType => ["[", typed, " JSONDictionary]"], mapType => {
|
|
302
|
-
if (this.implicitlyConvertsFromJSON(mapType)) {
|
|
303
|
-
// TODO check each value type
|
|
304
|
-
return typed;
|
|
305
|
-
}
|
|
306
|
-
return ["map(", typed, ", λ(id x, ", this.toDynamicExpression(mapType.values, "x"), "))"];
|
|
307
|
-
}, _enumType => ["[", typed, " value]"], unionType => {
|
|
308
|
-
const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
|
|
309
|
-
if (nullable !== null) {
|
|
310
|
-
if (this.implicitlyConvertsFromJSON(nullable)) {
|
|
311
|
-
return ["NSNullify(", typed, ")"];
|
|
312
|
-
}
|
|
313
|
-
else {
|
|
314
|
-
return ["NSNullify(", this.toDynamicExpression(nullable, typed), ")"];
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
// TODO support unions
|
|
319
|
-
return typed;
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
implicitlyConvertsFromJSON(t) {
|
|
324
|
-
if (t instanceof Type_1.ClassType) {
|
|
325
|
-
return false;
|
|
326
|
-
}
|
|
327
|
-
else if (t instanceof Type_1.EnumType) {
|
|
328
|
-
return false;
|
|
329
|
-
}
|
|
330
|
-
else if (t instanceof Type_1.ArrayType) {
|
|
331
|
-
return this.implicitlyConvertsFromJSON(t.items);
|
|
332
|
-
}
|
|
333
|
-
else if (t instanceof Type_1.MapType) {
|
|
334
|
-
return this.implicitlyConvertsFromJSON(t.values);
|
|
335
|
-
}
|
|
336
|
-
else if (t.isPrimitive()) {
|
|
337
|
-
return true;
|
|
338
|
-
}
|
|
339
|
-
else if (t instanceof Type_1.UnionType) {
|
|
340
|
-
const nullable = (0, TypeUtils_1.nullableFromUnion)(t);
|
|
341
|
-
if (nullable !== null) {
|
|
342
|
-
return this.implicitlyConvertsFromJSON(nullable);
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
// We don't support unions yet, so this is just untyped
|
|
346
|
-
return true;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
else {
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
implicitlyConvertsToJSON(t) {
|
|
354
|
-
return this.implicitlyConvertsFromJSON(t) && "bool" !== t.kind;
|
|
355
|
-
}
|
|
356
|
-
emitPropertyAssignment(propertyName, jsonName, propertyType) {
|
|
357
|
-
const name = ["_", propertyName];
|
|
358
|
-
(0, TypeUtils_1.matchType)(propertyType, anyType => this.emitLine(name, " = ", this.fromDynamicExpression(anyType, name), ";"), nullType => this.emitLine(name, " = ", this.fromDynamicExpression(nullType, name), ";"), boolType => this.emitLine(name, " = ", this.fromDynamicExpression(boolType, name), ";"), integerType => this.emitLine(name, " = ", this.fromDynamicExpression(integerType, name), ";"), doubleType => this.emitLine(name, " = ", this.fromDynamicExpression(doubleType, name), ";"), stringType => this.emitLine(name, " = ", this.fromDynamicExpression(stringType, name), ";"), arrayType => this.emitLine(name, " = ", this.fromDynamicExpression(arrayType, name), ";"), classType => this.emitLine(name, " = ", this.fromDynamicExpression(classType, ["(id)", name]), ";"), mapType => {
|
|
359
|
-
const itemType = mapType.values;
|
|
360
|
-
this.emitLine(name, " = map(", name, ", ", ["λ(id x, ", this.fromDynamicExpression(itemType, "x"), ")"], ");");
|
|
361
|
-
}, enumType => this.emitLine(name, " = ", this.fromDynamicExpression(enumType, ["(id)", name]), ";"), unionType => {
|
|
362
|
-
const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
|
|
363
|
-
if (nullable !== null) {
|
|
364
|
-
this.emitPropertyAssignment(propertyName, jsonName, nullable);
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
// TODO This is a union, but for now we just leave it dynamic
|
|
368
|
-
this.emitLine(name, " = ", this.fromDynamicExpression(unionType, name), ";");
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
emitPrivateClassInterface(_, name) {
|
|
373
|
-
this.emitLine("@interface ", name, " (JSONConversion)");
|
|
374
|
-
this.emitLine("+ (instancetype)fromJSONDictionary:(NSDictionary *)dict;");
|
|
375
|
-
this.emitLine("- (NSDictionary *)JSONDictionary;");
|
|
376
|
-
this.emitLine("@end");
|
|
377
|
-
}
|
|
378
|
-
pointerAwareTypeName(t) {
|
|
379
|
-
const name = t instanceof Type_1.Type ? this.objcType(t) : t;
|
|
380
|
-
const isPointer = name[1] !== "";
|
|
381
|
-
return isPointer ? name : [name, " "];
|
|
382
|
-
}
|
|
383
|
-
emitNonClassTopLevelTypedef(t, name) {
|
|
384
|
-
let nonPointerTypeName = this.objcType(t)[0];
|
|
385
|
-
this.emitLine("typedef ", nonPointerTypeName, " ", name, ";");
|
|
386
|
-
}
|
|
387
|
-
topLevelFromDataPrototype(name) {
|
|
388
|
-
return [name, " *_Nullable ", name, "FromData(NSData *data, NSError **error)"];
|
|
389
|
-
}
|
|
390
|
-
topLevelFromJSONPrototype(name) {
|
|
391
|
-
return [name, " *_Nullable ", name, "FromJSON(NSString *json, NSStringEncoding encoding, NSError **error)"];
|
|
392
|
-
}
|
|
393
|
-
topLevelToDataPrototype(name, pad = false) {
|
|
394
|
-
const parameter = this.variableNameForTopLevel(name);
|
|
395
|
-
const padding = pad ? (0, Strings_1.repeatString)(" ", this.sourcelikeToString(name).length - "NSData".length) : "";
|
|
396
|
-
return ["NSData", padding, " *_Nullable ", name, "ToData(", name, " *", parameter, ", NSError **error)"];
|
|
397
|
-
}
|
|
398
|
-
topLevelToJSONPrototype(name, pad = false) {
|
|
399
|
-
const parameter = this.variableNameForTopLevel(name);
|
|
400
|
-
const padding = pad ? (0, Strings_1.repeatString)(" ", this.sourcelikeToString(name).length - "NSString".length) : "";
|
|
401
|
-
return [
|
|
402
|
-
"NSString",
|
|
403
|
-
padding,
|
|
404
|
-
" *_Nullable ",
|
|
405
|
-
name,
|
|
406
|
-
"ToJSON(",
|
|
407
|
-
name,
|
|
408
|
-
" *",
|
|
409
|
-
parameter,
|
|
410
|
-
", NSStringEncoding encoding, NSError **error)"
|
|
411
|
-
];
|
|
412
|
-
}
|
|
413
|
-
emitTopLevelFunctionDeclarations(_, name) {
|
|
414
|
-
this.emitLine(this.topLevelFromDataPrototype(name), ";");
|
|
415
|
-
this.emitLine(this.topLevelFromJSONPrototype(name), ";");
|
|
416
|
-
this.emitLine(this.topLevelToDataPrototype(name, true), ";");
|
|
417
|
-
this.emitLine(this.topLevelToJSONPrototype(name, true), ";");
|
|
418
|
-
}
|
|
419
|
-
emitTryCatchAsError(inTry, inCatch) {
|
|
420
|
-
this.emitLine("@try {");
|
|
421
|
-
this.indent(inTry);
|
|
422
|
-
this.emitLine("} @catch (NSException *exception) {");
|
|
423
|
-
this.indent(() => {
|
|
424
|
-
this.emitLine(`*error = [NSError errorWithDomain:@"JSONSerialization" code:-1 userInfo:@{ @"exception": exception }];`);
|
|
425
|
-
inCatch();
|
|
426
|
-
});
|
|
427
|
-
this.emitLine("}");
|
|
428
|
-
}
|
|
429
|
-
emitTopLevelFunctions(t, name) {
|
|
430
|
-
const parameter = this.variableNameForTopLevel(name);
|
|
431
|
-
this.ensureBlankLine();
|
|
432
|
-
this.emitMethod(this.topLevelFromDataPrototype(name), () => {
|
|
433
|
-
this.emitTryCatchAsError(() => {
|
|
434
|
-
this.emitLine("id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:error];");
|
|
435
|
-
this.emitLine("return *error ? nil : ", this.fromDynamicExpression(t, "json"), ";");
|
|
436
|
-
}, () => this.emitLine("return nil;"));
|
|
437
|
-
});
|
|
438
|
-
this.ensureBlankLine();
|
|
439
|
-
this.emitMethod(this.topLevelFromJSONPrototype(name), () => {
|
|
440
|
-
this.emitLine("return ", name, "FromData([json dataUsingEncoding:encoding], error);");
|
|
441
|
-
});
|
|
442
|
-
this.ensureBlankLine();
|
|
443
|
-
this.emitMethod(this.topLevelToDataPrototype(name), () => {
|
|
444
|
-
this.emitTryCatchAsError(() => {
|
|
445
|
-
this.emitLine("id json = ", this.toDynamicExpression(t, parameter), ";");
|
|
446
|
-
this.emitLine("NSData *data = [NSJSONSerialization dataWithJSONObject:json options:kNilOptions error:error];");
|
|
447
|
-
this.emitLine("return *error ? nil : data;");
|
|
448
|
-
}, () => this.emitLine("return nil;"));
|
|
449
|
-
});
|
|
450
|
-
this.ensureBlankLine();
|
|
451
|
-
this.emitMethod(this.topLevelToJSONPrototype(name), () => {
|
|
452
|
-
this.emitLine("NSData *data = ", name, "ToData(", parameter, ", error);");
|
|
453
|
-
this.emitLine("return data ? [[NSString alloc] initWithData:data encoding:encoding] : nil;");
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
emitClassInterface(t, className) {
|
|
457
|
-
const isTopLevel = (0, collection_utils_1.mapContains)(this.topLevels, t);
|
|
458
|
-
this.emitDescription(this.descriptionForType(t));
|
|
459
|
-
this.emitLine("@interface ", className, " : NSObject");
|
|
460
|
-
if (DEBUG)
|
|
461
|
-
this.emitLine("@property NSDictionary<NSString *, id> *_json;");
|
|
462
|
-
this.emitPropertyTable(t, (name, _json, property) => {
|
|
463
|
-
let attributes = ["nonatomic"];
|
|
464
|
-
// TODO offer a 'readonly' option
|
|
465
|
-
// TODO We must add "copy" if it's NSCopy, otherwise "strong"
|
|
466
|
-
if (property.type.isNullable) {
|
|
467
|
-
attributes.push("nullable");
|
|
468
|
-
}
|
|
469
|
-
attributes.push(this.memoryAttribute(property.type, property.type.isNullable));
|
|
470
|
-
return [
|
|
471
|
-
["@property ", ["(", attributes.join(", "), ")"], " "],
|
|
472
|
-
[this.pointerAwareTypeName(property.type), name, ";"]
|
|
473
|
-
];
|
|
474
|
-
});
|
|
475
|
-
if (!this._options.justTypes && isTopLevel) {
|
|
476
|
-
if (t.getProperties().size > 0)
|
|
477
|
-
this.ensureBlankLine();
|
|
478
|
-
this.emitLine("+ (_Nullable instancetype)fromJSON:(NSString *)json encoding:(NSStringEncoding)encoding error:(NSError *_Nullable *)error;");
|
|
479
|
-
this.emitLine("+ (_Nullable instancetype)fromData:(NSData *)data error:(NSError *_Nullable *)error;");
|
|
480
|
-
this.emitLine("- (NSString *_Nullable)toJSON:(NSStringEncoding)encoding error:(NSError *_Nullable *)error;");
|
|
481
|
-
this.emitLine("- (NSData *_Nullable)toData:(NSError *_Nullable *)error;");
|
|
482
|
-
}
|
|
483
|
-
this.emitLine("@end");
|
|
484
|
-
}
|
|
485
|
-
hasIrregularProperties(t) {
|
|
486
|
-
let irregular = false;
|
|
487
|
-
this.forEachClassProperty(t, "none", (name, jsonName) => {
|
|
488
|
-
irregular = irregular || (0, Strings_1.stringEscape)(jsonName) !== this.sourcelikeToString(name);
|
|
489
|
-
});
|
|
490
|
-
return irregular;
|
|
491
|
-
}
|
|
492
|
-
hasUnsafeProperties(t) {
|
|
493
|
-
let unsafe = false;
|
|
494
|
-
this.forEachClassProperty(t, "none", (_, __, property) => {
|
|
495
|
-
unsafe = unsafe || !this.implicitlyConvertsToJSON(property.type);
|
|
496
|
-
});
|
|
497
|
-
return unsafe;
|
|
498
|
-
}
|
|
499
|
-
// TODO Implement NSCopying
|
|
500
|
-
emitClassImplementation(t, className) {
|
|
501
|
-
const isTopLevel = (0, collection_utils_1.mapContains)(this.topLevels, t);
|
|
502
|
-
const hasIrregularProperties = this.hasIrregularProperties(t);
|
|
503
|
-
const hasUnsafeProperties = this.hasUnsafeProperties(t);
|
|
504
|
-
this.emitLine("@implementation ", className);
|
|
505
|
-
if (!this._options.justTypes) {
|
|
506
|
-
this.emitMethod("+ (NSDictionary<NSString *, NSString *> *)properties", () => {
|
|
507
|
-
this.emitLine("static NSDictionary<NSString *, NSString *> *properties;");
|
|
508
|
-
this.emitLine("return properties = properties ? properties : @{");
|
|
509
|
-
this.indent(() => {
|
|
510
|
-
this.forEachClassProperty(t, "none", (name, jsonName) => this.emitLine(`@"${(0, Strings_1.stringEscape)(jsonName)}": @"`, name, `",`));
|
|
511
|
-
});
|
|
512
|
-
this.emitLine("};");
|
|
513
|
-
});
|
|
514
|
-
this.ensureBlankLine();
|
|
515
|
-
if (isTopLevel) {
|
|
516
|
-
this.emitMethod("+ (_Nullable instancetype)fromData:(NSData *)data error:(NSError *_Nullable *)error", () => {
|
|
517
|
-
this.emitLine("return ", className, "FromData(data, error);");
|
|
518
|
-
});
|
|
519
|
-
this.ensureBlankLine();
|
|
520
|
-
this.emitMethod("+ (_Nullable instancetype)fromJSON:(NSString *)json encoding:(NSStringEncoding)encoding error:(NSError *_Nullable *)error", () => {
|
|
521
|
-
this.emitLine("return ", className, "FromJSON(json, encoding, error);");
|
|
522
|
-
});
|
|
523
|
-
this.ensureBlankLine();
|
|
524
|
-
}
|
|
525
|
-
this.emitMethod("+ (instancetype)fromJSONDictionary:(NSDictionary *)dict", () => {
|
|
526
|
-
this.emitLine("return dict ? [[", className, " alloc] initWithJSONDictionary:dict] : nil;");
|
|
527
|
-
});
|
|
528
|
-
this.ensureBlankLine();
|
|
529
|
-
this.emitMethod("- (instancetype)initWithJSONDictionary:(NSDictionary *)dict", () => {
|
|
530
|
-
this.emitBlock("if (self = [super init])", () => {
|
|
531
|
-
if (DEBUG)
|
|
532
|
-
this.emitLine("__json = dict;");
|
|
533
|
-
this.emitLine("[self setValuesForKeysWithDictionary:dict];");
|
|
534
|
-
this.forEachClassProperty(t, "none", (name, jsonName, property) => {
|
|
535
|
-
if (!this.implicitlyConvertsFromJSON(property.type)) {
|
|
536
|
-
this.emitPropertyAssignment(name, jsonName, property.type);
|
|
537
|
-
}
|
|
538
|
-
});
|
|
539
|
-
});
|
|
540
|
-
this.emitLine("return self;");
|
|
541
|
-
});
|
|
542
|
-
this.ensureBlankLine();
|
|
543
|
-
this.emitMethod("- (void)setValue:(nullable id)value forKey:(NSString *)key", () => {
|
|
544
|
-
this.emitLine("id resolved = ", className, ".properties[key];");
|
|
545
|
-
this.emitLine("if (resolved) [super setValue:value forKey:resolved];");
|
|
546
|
-
});
|
|
547
|
-
// setNilValueForKey: is automatically invoked by the NSObject setValue:forKey: when it is passed nil for a scalar (a.k.a. non-nullable) object
|
|
548
|
-
// The approach below sets the scalar to 0 in this case, and therefore assumes an initializer with incomplete data shouldn't be grounds for raising an exception.
|
|
549
|
-
// Put another way, if the initializer didn't have a key at all, there wouldn't be an exception raised, so sending nil for something probably shouldn't cause one.
|
|
550
|
-
this.ensureBlankLine();
|
|
551
|
-
this.emitMethod("- (void)setNilValueForKey:(NSString *)key", () => {
|
|
552
|
-
this.emitLine("id resolved = ", className, ".properties[key];");
|
|
553
|
-
this.emitLine("if (resolved) [super setValue:@(0) forKey:resolved];");
|
|
554
|
-
});
|
|
555
|
-
this.ensureBlankLine();
|
|
556
|
-
this.emitMethod("- (NSDictionary *)JSONDictionary", () => {
|
|
557
|
-
if (!hasIrregularProperties && !hasUnsafeProperties) {
|
|
558
|
-
this.emitLine("return [self dictionaryWithValuesForKeys:", className, ".properties.allValues];");
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
this.emitLine("id dict = [[self dictionaryWithValuesForKeys:", className, ".properties.allValues] mutableCopy];");
|
|
562
|
-
this.ensureBlankLine();
|
|
563
|
-
if (hasIrregularProperties) {
|
|
564
|
-
this.emitExtraComments("Rewrite property names that differ in JSON");
|
|
565
|
-
this.emitBlock(["for (id jsonName in ", className, ".properties)"], () => {
|
|
566
|
-
this.emitLine(`id propertyName = `, className, `.properties[jsonName];`);
|
|
567
|
-
this.emitBlock(`if (![jsonName isEqualToString:propertyName])`, () => {
|
|
568
|
-
this.emitLine(`dict[jsonName] = dict[propertyName];`);
|
|
569
|
-
this.emitLine(`[dict removeObjectForKey:propertyName];`);
|
|
570
|
-
});
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
if (hasUnsafeProperties) {
|
|
574
|
-
this.ensureBlankLine();
|
|
575
|
-
this.emitExtraComments("Map values that need translation");
|
|
576
|
-
this.emitLine("[dict addEntriesFromDictionary:@{");
|
|
577
|
-
this.indent(() => {
|
|
578
|
-
this.forEachClassProperty(t, "none", (propertyName, jsonKey, property) => {
|
|
579
|
-
if (!this.implicitlyConvertsToJSON(property.type)) {
|
|
580
|
-
const key = (0, Strings_1.stringEscape)(jsonKey);
|
|
581
|
-
const name = ["_", propertyName];
|
|
582
|
-
this.emitLine('@"', key, '": ', this.toDynamicExpression(property.type, name), ",");
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
});
|
|
586
|
-
this.emitLine("}];");
|
|
587
|
-
}
|
|
588
|
-
this.ensureBlankLine();
|
|
589
|
-
this.emitLine("return dict;");
|
|
590
|
-
});
|
|
591
|
-
if (isTopLevel) {
|
|
592
|
-
this.ensureBlankLine();
|
|
593
|
-
this.emitMethod(`- (NSData *_Nullable)toData:(NSError *_Nullable *)error`, () => {
|
|
594
|
-
this.emitLine("return ", className, "ToData(self, error);");
|
|
595
|
-
});
|
|
596
|
-
this.ensureBlankLine();
|
|
597
|
-
this.emitMethod(`- (NSString *_Nullable)toJSON:(NSStringEncoding)encoding error:(NSError *_Nullable *)error`, () => {
|
|
598
|
-
this.emitLine("return ", className, "ToJSON(self, encoding, error);");
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
this.emitLine("@end");
|
|
603
|
-
}
|
|
604
|
-
emitMark(label) {
|
|
605
|
-
this.ensureBlankLine();
|
|
606
|
-
this.emitLine(`#pragma mark - ${label}`);
|
|
607
|
-
this.ensureBlankLine();
|
|
608
|
-
}
|
|
609
|
-
variableNameForTopLevel(name) {
|
|
610
|
-
const camelCaseName = (0, Source_1.modifySource)(serialized => {
|
|
611
|
-
// 1. remove class prefix
|
|
612
|
-
serialized = serialized.slice(this._classPrefix.length);
|
|
613
|
-
// 2. camel case
|
|
614
|
-
return (0, Strings_1.camelCase)(serialized);
|
|
615
|
-
}, name);
|
|
616
|
-
return camelCaseName;
|
|
617
|
-
}
|
|
618
|
-
emitPseudoEnumInterface(enumType, enumName) {
|
|
619
|
-
this.emitDescription(this.descriptionForType(enumType));
|
|
620
|
-
this.emitLine("@interface ", enumName, " : NSObject");
|
|
621
|
-
this.emitLine("@property (nonatomic, readonly, copy) NSString *value;");
|
|
622
|
-
this.emitLine("+ (instancetype _Nullable)withValue:(NSString *)value;");
|
|
623
|
-
this.forEachEnumCase(enumType, "none", (name, _) => {
|
|
624
|
-
this.emitLine("+ (", enumName, " *)", name, ";");
|
|
625
|
-
});
|
|
626
|
-
this.emitLine("@end");
|
|
627
|
-
}
|
|
628
|
-
emitPseudoEnumImplementation(enumType, enumName) {
|
|
629
|
-
this.emitLine("@implementation ", enumName);
|
|
630
|
-
const instances = [enumName, ".", staticEnumValuesIdentifier];
|
|
631
|
-
this.emitMethod(["+ (NSDictionary<NSString *, ", enumName, " *> *)", staticEnumValuesIdentifier], () => {
|
|
632
|
-
this.emitLine("static NSDictionary<NSString *, ", enumName, " *> *", staticEnumValuesIdentifier, ";");
|
|
633
|
-
this.emitLine("return ", staticEnumValuesIdentifier, " = ", staticEnumValuesIdentifier, " ? ", staticEnumValuesIdentifier, " : @{");
|
|
634
|
-
this.indent(() => {
|
|
635
|
-
this.forEachEnumCase(enumType, "none", (_, jsonValue) => {
|
|
636
|
-
const value = ['@"', (0, Strings_1.stringEscape)(jsonValue), '"'];
|
|
637
|
-
this.emitLine(value, ": [[", enumName, " alloc] initWithValue:", value, "],");
|
|
638
|
-
});
|
|
639
|
-
});
|
|
640
|
-
this.emitLine("};");
|
|
641
|
-
});
|
|
642
|
-
this.ensureBlankLine();
|
|
643
|
-
this.forEachEnumCase(enumType, "none", (name, jsonValue) => {
|
|
644
|
-
this.emitLine("+ (", enumName, " *)", name, " { return ", instances, '[@"', (0, Strings_1.stringEscape)(jsonValue), '"]; }');
|
|
645
|
-
});
|
|
646
|
-
this.ensureBlankLine();
|
|
647
|
-
this.emitMethod("+ (instancetype _Nullable)withValue:(NSString *)value", () => this.emitLine("return ", instances, "[value];"));
|
|
648
|
-
this.ensureBlankLine();
|
|
649
|
-
this.emitMethod("- (instancetype)initWithValue:(NSString *)value", () => {
|
|
650
|
-
this.emitLine("if (self = [super init]) _value = value;");
|
|
651
|
-
this.emitLine("return self;");
|
|
652
|
-
});
|
|
653
|
-
this.ensureBlankLine();
|
|
654
|
-
this.emitLine("- (NSUInteger)hash { return _value.hash; }");
|
|
655
|
-
this.emitLine("@end");
|
|
656
|
-
}
|
|
657
|
-
emitSourceStructure(proposedFilename) {
|
|
658
|
-
const fileMode = proposedFilename !== "stdout";
|
|
659
|
-
if (!fileMode) {
|
|
660
|
-
// We don't have a filename, so we use a top-level name
|
|
661
|
-
const firstTopLevel = (0, Support_1.defined)((0, collection_utils_1.mapFirst)(this.topLevels));
|
|
662
|
-
proposedFilename = this.sourcelikeToString(this.nameForNamedType(firstTopLevel)) + ".m";
|
|
663
|
-
}
|
|
664
|
-
const [filename, extension] = splitExtension(proposedFilename);
|
|
665
|
-
if (this._options.features.interface) {
|
|
666
|
-
this.startFile(filename, "h");
|
|
667
|
-
if (this.leadingComments !== undefined) {
|
|
668
|
-
this.emitCommentLines(this.leadingComments);
|
|
669
|
-
}
|
|
670
|
-
else if (!this._options.justTypes) {
|
|
671
|
-
this.emitCommentLines(["To parse this JSON:", ""]);
|
|
672
|
-
this.emitLine("// NSError *error;");
|
|
673
|
-
this.forEachTopLevel("none", (t, topLevelName) => {
|
|
674
|
-
const fromJsonExpression = t instanceof Type_1.ClassType
|
|
675
|
-
? ["[", topLevelName, " fromJSON:json encoding:NSUTF8Encoding error:&error];"]
|
|
676
|
-
: [topLevelName, "FromJSON(json, NSUTF8Encoding, &error);"];
|
|
677
|
-
this.emitLine("// ", topLevelName, " *", this.variableNameForTopLevel(topLevelName), " = ", fromJsonExpression);
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
this.ensureBlankLine();
|
|
681
|
-
this.emitLine(`#import <Foundation/Foundation.h>`);
|
|
682
|
-
this.ensureBlankLine();
|
|
683
|
-
// Emit @class declarations for top-level array+maps and classes
|
|
684
|
-
this.forEachNamedType("none", (_, className) => this.emitLine("@class ", className, ";"), (_, enumName) => this.emitLine("@class ", enumName, ";"), () => null);
|
|
685
|
-
this.ensureBlankLine();
|
|
686
|
-
this.ensureBlankLine();
|
|
687
|
-
this.emitLine("NS_ASSUME_NONNULL_BEGIN");
|
|
688
|
-
this.ensureBlankLine();
|
|
689
|
-
if (this.haveEnums) {
|
|
690
|
-
this.emitMark("Boxed enums");
|
|
691
|
-
this.forEachEnum("leading-and-interposing", (t, n) => this.emitPseudoEnumInterface(t, n));
|
|
692
|
-
}
|
|
693
|
-
// Emit interfaces for top-level array+maps and classes
|
|
694
|
-
this.forEachTopLevel("leading-and-interposing", (t, n) => this.emitNonClassTopLevelTypedef(t, n), t => !(t instanceof Type_1.ClassType));
|
|
695
|
-
const hasTopLevelNonClassTypes = (0, collection_utils_1.iterableSome)(this.topLevels, ([_, t]) => !(t instanceof Type_1.ClassType));
|
|
696
|
-
if (!this._options.justTypes && (hasTopLevelNonClassTypes || this._options.marshallingFunctions)) {
|
|
697
|
-
this.ensureBlankLine();
|
|
698
|
-
this.emitMark("Top-level marshaling functions");
|
|
699
|
-
this.forEachTopLevel("leading-and-interposing", (t, n) => this.emitTopLevelFunctionDeclarations(t, n),
|
|
700
|
-
// Objective-C developers get freaked out by C functions, so we don't
|
|
701
|
-
// declare them for top-level object types (we always need them for non-object types)
|
|
702
|
-
t => this._options.marshallingFunctions || !(t instanceof Type_1.ClassType));
|
|
703
|
-
}
|
|
704
|
-
this.emitMark("Object interfaces");
|
|
705
|
-
this.forEachNamedType("leading-and-interposing", (c, className) => this.emitClassInterface(c, className), () => null, () => null);
|
|
706
|
-
this.ensureBlankLine();
|
|
707
|
-
this.emitLine("NS_ASSUME_NONNULL_END");
|
|
708
|
-
this.finishFile();
|
|
709
|
-
}
|
|
710
|
-
if (this._options.features.implementation) {
|
|
711
|
-
this.startFile(filename, extension);
|
|
712
|
-
this.emitLine(`#import "${filename}.h"`);
|
|
713
|
-
this.ensureBlankLine();
|
|
714
|
-
if (!this._options.justTypes) {
|
|
715
|
-
this.ensureBlankLine();
|
|
716
|
-
this.emitExtraComments("Shorthand for simple blocks");
|
|
717
|
-
this.emitLine(`#define λ(decl, expr) (^(decl) { return (expr); })`);
|
|
718
|
-
this.ensureBlankLine();
|
|
719
|
-
this.emitExtraComments("nil → NSNull conversion for JSON dictionaries");
|
|
720
|
-
this.emitBlock("static id NSNullify(id _Nullable x)", () => this.emitLine("return (x == nil || x == NSNull.null) ? NSNull.null : x;"));
|
|
721
|
-
this.ensureBlankLine();
|
|
722
|
-
this.emitLine("NS_ASSUME_NONNULL_BEGIN");
|
|
723
|
-
this.ensureBlankLine();
|
|
724
|
-
// We wouldn't need to emit these private iterfaces if we emitted implementations in forward-order
|
|
725
|
-
// but the code is more readable and explicit if we do this.
|
|
726
|
-
if (this._options.extraComments) {
|
|
727
|
-
this.emitMark("Private model interfaces");
|
|
728
|
-
}
|
|
729
|
-
this.forEachNamedType("leading-and-interposing", (c, className) => this.emitPrivateClassInterface(c, className), () => null, () => null);
|
|
730
|
-
if (this.haveEnums) {
|
|
731
|
-
if (this._options.extraComments) {
|
|
732
|
-
this.ensureBlankLine();
|
|
733
|
-
this.emitExtraComments("These enum-like reference types are needed so that enum", "values can be contained by NSArray and NSDictionary.");
|
|
734
|
-
this.ensureBlankLine();
|
|
735
|
-
}
|
|
736
|
-
this.forEachEnum("leading-and-interposing", (t, n) => this.emitPseudoEnumImplementation(t, n));
|
|
737
|
-
}
|
|
738
|
-
this.ensureBlankLine();
|
|
739
|
-
this.emitMapFunction();
|
|
740
|
-
this.ensureBlankLine();
|
|
741
|
-
this.emitMark("JSON serialization");
|
|
742
|
-
this.forEachTopLevel("leading-and-interposing", (t, n) => this.emitTopLevelFunctions(t, n));
|
|
743
|
-
}
|
|
744
|
-
this.forEachNamedType("leading-and-interposing", (c, className) => this.emitClassImplementation(c, className), () => null, () => null);
|
|
745
|
-
if (!this._options.justTypes) {
|
|
746
|
-
this.ensureBlankLine();
|
|
747
|
-
this.emitLine("NS_ASSUME_NONNULL_END");
|
|
748
|
-
}
|
|
749
|
-
this.finishFile();
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
get needsMap() {
|
|
753
|
-
// TODO this isn't complete (needs union support, for example)
|
|
754
|
-
function needsMap(t) {
|
|
755
|
-
return (t instanceof Type_1.MapType ||
|
|
756
|
-
t instanceof Type_1.ArrayType ||
|
|
757
|
-
(t instanceof Type_1.ClassType && (0, collection_utils_1.mapSome)(t.getProperties(), p => needsMap(p.type))));
|
|
758
|
-
}
|
|
759
|
-
return (0, collection_utils_1.iterableSome)(this.typeGraph.allTypesUnordered(), needsMap);
|
|
760
|
-
}
|
|
761
|
-
emitMapFunction() {
|
|
762
|
-
if (this.needsMap) {
|
|
763
|
-
this.emitMultiline(`static id map(id collection, id (^f)(id value)) {
|
|
764
|
-
id result = nil;
|
|
765
|
-
if ([collection isKindOfClass:NSArray.class]) {
|
|
766
|
-
result = [NSMutableArray arrayWithCapacity:[collection count]];
|
|
767
|
-
for (id x in collection) [result addObject:f(x)];
|
|
768
|
-
} else if ([collection isKindOfClass:NSDictionary.class]) {
|
|
769
|
-
result = [NSMutableDictionary dictionaryWithCapacity:[collection count]];
|
|
770
|
-
for (id key in collection) [result setObject:f([collection objectForKey:key]) forKey:key];
|
|
771
|
-
}
|
|
772
|
-
return result;
|
|
773
|
-
}`);
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
exports.ObjectiveCRenderer = ObjectiveCRenderer;
|