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.
Files changed (174) hide show
  1. package/README.md +1 -1
  2. package/dist/{cli/CompressedJSONFromStream.d.ts → CompressedJSONFromStream.d.ts} +1 -1
  3. package/dist/{cli/CompressedJSONFromStream.js → CompressedJSONFromStream.js} +2 -2
  4. package/dist/{cli/GraphQLIntrospection.d.ts → GraphQLIntrospection.d.ts} +0 -0
  5. package/dist/{cli/GraphQLIntrospection.js → GraphQLIntrospection.js} +1 -1
  6. package/dist/{cli/TypeSource.d.ts → TypeSource.d.ts} +2 -2
  7. package/dist/{cli/TypeSource.js → TypeSource.js} +0 -0
  8. package/dist/{cli/URLGrammar.d.ts → URLGrammar.d.ts} +0 -0
  9. package/dist/{cli/URLGrammar.js → URLGrammar.js} +1 -1
  10. package/dist/{cli/index.d.ts → index.d.ts} +2 -1
  11. package/dist/{cli/index.js → index.js} +4 -4
  12. package/package.json +61 -77
  13. package/dist/quicktype-core/Annotation.d.ts +0 -8
  14. package/dist/quicktype-core/Annotation.js +0 -16
  15. package/dist/quicktype-core/ConvenienceRenderer.d.ts +0 -138
  16. package/dist/quicktype-core/ConvenienceRenderer.js +0 -668
  17. package/dist/quicktype-core/DateTime.d.ts +0 -10
  18. package/dist/quicktype-core/DateTime.js +0 -57
  19. package/dist/quicktype-core/DeclarationIR.d.ts +0 -14
  20. package/dist/quicktype-core/DeclarationIR.js +0 -167
  21. package/dist/quicktype-core/EncodedMarkovChain.d.ts +0 -1
  22. package/dist/quicktype-core/EncodedMarkovChain.js +0 -4
  23. package/dist/quicktype-core/GatherNames.d.ts +0 -2
  24. package/dist/quicktype-core/GatherNames.js +0 -333
  25. package/dist/quicktype-core/Graph.d.ts +0 -12
  26. package/dist/quicktype-core/Graph.js +0 -220
  27. package/dist/quicktype-core/GraphRewriting.d.ts +0 -87
  28. package/dist/quicktype-core/GraphRewriting.js +0 -421
  29. package/dist/quicktype-core/MakeTransformations.d.ts +0 -4
  30. package/dist/quicktype-core/MakeTransformations.js +0 -193
  31. package/dist/quicktype-core/MarkovChain.d.ts +0 -15
  32. package/dist/quicktype-core/MarkovChain.js +0 -154
  33. package/dist/quicktype-core/Messages.d.ts +0 -294
  34. package/dist/quicktype-core/Messages.js +0 -105
  35. package/dist/quicktype-core/Naming.d.ts +0 -64
  36. package/dist/quicktype-core/Naming.js +0 -356
  37. package/dist/quicktype-core/Renderer.d.ts +0 -50
  38. package/dist/quicktype-core/Renderer.js +0 -274
  39. package/dist/quicktype-core/RendererOptions.d.ts +0 -71
  40. package/dist/quicktype-core/RendererOptions.js +0 -141
  41. package/dist/quicktype-core/Run.d.ts +0 -174
  42. package/dist/quicktype-core/Run.js +0 -393
  43. package/dist/quicktype-core/Source.d.ts +0 -65
  44. package/dist/quicktype-core/Source.js +0 -204
  45. package/dist/quicktype-core/TargetLanguage.d.ts +0 -34
  46. package/dist/quicktype-core/TargetLanguage.js +0 -66
  47. package/dist/quicktype-core/Transformers.d.ts +0 -209
  48. package/dist/quicktype-core/Transformers.js +0 -836
  49. package/dist/quicktype-core/Type.d.ts +0 -206
  50. package/dist/quicktype-core/Type.js +0 -716
  51. package/dist/quicktype-core/TypeBuilder.d.ts +0 -61
  52. package/dist/quicktype-core/TypeBuilder.js +0 -324
  53. package/dist/quicktype-core/TypeGraph.d.ts +0 -75
  54. package/dist/quicktype-core/TypeGraph.js +0 -420
  55. package/dist/quicktype-core/TypeUtils.d.ts +0 -33
  56. package/dist/quicktype-core/TypeUtils.js +0 -230
  57. package/dist/quicktype-core/UnifyClasses.d.ts +0 -16
  58. package/dist/quicktype-core/UnifyClasses.js +0 -159
  59. package/dist/quicktype-core/UnionBuilder.d.ts +0 -49
  60. package/dist/quicktype-core/UnionBuilder.js +0 -282
  61. package/dist/quicktype-core/attributes/AccessorNames.d.ts +0 -18
  62. package/dist/quicktype-core/attributes/AccessorNames.js +0 -182
  63. package/dist/quicktype-core/attributes/Constraints.d.ts +0 -38
  64. package/dist/quicktype-core/attributes/Constraints.js +0 -172
  65. package/dist/quicktype-core/attributes/Description.d.ts +0 -9
  66. package/dist/quicktype-core/attributes/Description.js +0 -97
  67. package/dist/quicktype-core/attributes/EnumValues.d.ts +0 -8
  68. package/dist/quicktype-core/attributes/EnumValues.js +0 -31
  69. package/dist/quicktype-core/attributes/StringTypes.d.ts +0 -28
  70. package/dist/quicktype-core/attributes/StringTypes.js +0 -189
  71. package/dist/quicktype-core/attributes/TypeAttributes.d.ts +0 -34
  72. package/dist/quicktype-core/attributes/TypeAttributes.js +0 -119
  73. package/dist/quicktype-core/attributes/TypeNames.d.ts +0 -46
  74. package/dist/quicktype-core/attributes/TypeNames.js +0 -274
  75. package/dist/quicktype-core/attributes/URIAttributes.d.ts +0 -8
  76. package/dist/quicktype-core/attributes/URIAttributes.js +0 -85
  77. package/dist/quicktype-core/index.d.ts +0 -48
  78. package/dist/quicktype-core/index.js +0 -180
  79. package/dist/quicktype-core/input/CompressedJSON.d.ts +0 -69
  80. package/dist/quicktype-core/input/CompressedJSON.js +0 -276
  81. package/dist/quicktype-core/input/FetchingJSONSchemaStore.d.ts +0 -6
  82. package/dist/quicktype-core/input/FetchingJSONSchemaStore.js +0 -18
  83. package/dist/quicktype-core/input/Inference.d.ts +0 -22
  84. package/dist/quicktype-core/input/Inference.js +0 -240
  85. package/dist/quicktype-core/input/Inputs.d.ts +0 -48
  86. package/dist/quicktype-core/input/Inputs.js +0 -145
  87. package/dist/quicktype-core/input/JSONSchemaInput.d.ts +0 -91
  88. package/dist/quicktype-core/input/JSONSchemaInput.js +0 -1041
  89. package/dist/quicktype-core/input/JSONSchemaStore.d.ts +0 -8
  90. package/dist/quicktype-core/input/JSONSchemaStore.js +0 -36
  91. package/dist/quicktype-core/input/PostmanCollection.d.ts +0 -5
  92. package/dist/quicktype-core/input/PostmanCollection.js +0 -60
  93. package/dist/quicktype-core/input/io/NodeIO.d.ts +0 -3
  94. package/dist/quicktype-core/input/io/NodeIO.js +0 -87
  95. package/dist/quicktype-core/input/io/get-stream/buffer-stream.d.ts +0 -2
  96. package/dist/quicktype-core/input/io/get-stream/buffer-stream.js +0 -45
  97. package/dist/quicktype-core/input/io/get-stream/index.d.ts +0 -9
  98. package/dist/quicktype-core/input/io/get-stream/index.js +0 -52
  99. package/dist/quicktype-core/language/All.d.ts +0 -3
  100. package/dist/quicktype-core/language/All.js +0 -57
  101. package/dist/quicktype-core/language/CPlusPlus.d.ts +0 -241
  102. package/dist/quicktype-core/language/CPlusPlus.js +0 -1847
  103. package/dist/quicktype-core/language/CSharp.d.ts +0 -201
  104. package/dist/quicktype-core/language/CSharp.js +0 -1850
  105. package/dist/quicktype-core/language/Crystal.d.ts +0 -37
  106. package/dist/quicktype-core/language/Crystal.js +0 -337
  107. package/dist/quicktype-core/language/Dart.d.ts +0 -66
  108. package/dist/quicktype-core/language/Dart.js +0 -576
  109. package/dist/quicktype-core/language/Elm.d.ts +0 -58
  110. package/dist/quicktype-core/language/Elm.js +0 -522
  111. package/dist/quicktype-core/language/Golang.d.ts +0 -51
  112. package/dist/quicktype-core/language/Golang.js +0 -460
  113. package/dist/quicktype-core/language/Haskell.d.ts +0 -56
  114. package/dist/quicktype-core/language/Haskell.js +0 -411
  115. package/dist/quicktype-core/language/JSONSchema.d.ts +0 -31
  116. package/dist/quicktype-core/language/JSONSchema.js +0 -169
  117. package/dist/quicktype-core/language/Java.d.ts +0 -125
  118. package/dist/quicktype-core/language/Java.js +0 -1081
  119. package/dist/quicktype-core/language/JavaScript.d.ts +0 -68
  120. package/dist/quicktype-core/language/JavaScript.js +0 -435
  121. package/dist/quicktype-core/language/JavaScriptPropTypes.d.ts +0 -40
  122. package/dist/quicktype-core/language/JavaScriptPropTypes.js +0 -213
  123. package/dist/quicktype-core/language/JavaScriptUnicodeMaps.d.ts +0 -2
  124. package/dist/quicktype-core/language/JavaScriptUnicodeMaps.js +0 -134
  125. package/dist/quicktype-core/language/Kotlin.d.ts +0 -109
  126. package/dist/quicktype-core/language/Kotlin.js +0 -832
  127. package/dist/quicktype-core/language/Objective-C.d.ts +0 -79
  128. package/dist/quicktype-core/language/Objective-C.js +0 -777
  129. package/dist/quicktype-core/language/Php.d.ts +0 -80
  130. package/dist/quicktype-core/language/Php.js +0 -702
  131. package/dist/quicktype-core/language/Pike.d.ts +0 -37
  132. package/dist/quicktype-core/language/Pike.js +0 -276
  133. package/dist/quicktype-core/language/Python.d.ts +0 -107
  134. package/dist/quicktype-core/language/Python.js +0 -969
  135. package/dist/quicktype-core/language/Rust.d.ts +0 -56
  136. package/dist/quicktype-core/language/Rust.js +0 -309
  137. package/dist/quicktype-core/language/Swift.d.ts +0 -96
  138. package/dist/quicktype-core/language/Swift.js +0 -1211
  139. package/dist/quicktype-core/language/TypeScriptFlow.d.ts +0 -77
  140. package/dist/quicktype-core/language/TypeScriptFlow.js +0 -286
  141. package/dist/quicktype-core/language/ruby/index.d.ts +0 -52
  142. package/dist/quicktype-core/language/ruby/index.js +0 -557
  143. package/dist/quicktype-core/language/ruby/keywords.d.ts +0 -3
  144. package/dist/quicktype-core/language/ruby/keywords.js +0 -358
  145. package/dist/quicktype-core/rewrites/CombineClasses.d.ts +0 -3
  146. package/dist/quicktype-core/rewrites/CombineClasses.js +0 -125
  147. package/dist/quicktype-core/rewrites/ExpandStrings.d.ts +0 -4
  148. package/dist/quicktype-core/rewrites/ExpandStrings.js +0 -143
  149. package/dist/quicktype-core/rewrites/FlattenStrings.d.ts +0 -3
  150. package/dist/quicktype-core/rewrites/FlattenStrings.js +0 -45
  151. package/dist/quicktype-core/rewrites/FlattenUnions.d.ts +0 -3
  152. package/dist/quicktype-core/rewrites/FlattenUnions.js +0 -47
  153. package/dist/quicktype-core/rewrites/InferMaps.d.ts +0 -3
  154. package/dist/quicktype-core/rewrites/InferMaps.js +0 -117
  155. package/dist/quicktype-core/rewrites/ReplaceObjectType.d.ts +0 -3
  156. package/dist/quicktype-core/rewrites/ReplaceObjectType.js +0 -60
  157. package/dist/quicktype-core/rewrites/ResolveIntersections.d.ts +0 -3
  158. package/dist/quicktype-core/rewrites/ResolveIntersections.js +0 -244
  159. package/dist/quicktype-core/support/Acronyms.d.ts +0 -10
  160. package/dist/quicktype-core/support/Acronyms.js +0 -1128
  161. package/dist/quicktype-core/support/Chance.d.ts +0 -38
  162. package/dist/quicktype-core/support/Chance.js +0 -2146
  163. package/dist/quicktype-core/support/Converters.d.ts +0 -6
  164. package/dist/quicktype-core/support/Converters.js +0 -16
  165. package/dist/quicktype-core/support/Strings.d.ts +0 -44
  166. package/dist/quicktype-core/support/Strings.js +0 -525
  167. package/dist/quicktype-core/support/Support.d.ts +0 -29
  168. package/dist/quicktype-core/support/Support.js +0 -162
  169. package/dist/quicktype-graphql-input/GraphQLSchema.d.ts +0 -645
  170. package/dist/quicktype-graphql-input/GraphQLSchema.js +0 -39
  171. package/dist/quicktype-graphql-input/index.d.ts +0 -17
  172. package/dist/quicktype-graphql-input/index.js +0 -407
  173. package/dist/quicktype-typescript-input/index.d.ts +0 -2
  174. 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;