@defold-typescript/types 0.50.1 → 0.52.0

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 (166) hide show
  1. package/api-availability.json +4 -58
  2. package/api-signatures.json +1128 -1552
  3. package/api-targets.json +15 -5
  4. package/examples/translations.json +19 -71
  5. package/fixtures/messages_doc.json +20 -39
  6. package/generated/b2d_world.d.ts +10 -10
  7. package/generated/buffer.d.ts +9 -9
  8. package/generated/builtin-messages.d.ts +16 -14
  9. package/generated/bullet3d_collision_object.d.ts +1 -1
  10. package/generated/bullet3d_constraint.d.ts +109 -7
  11. package/generated/bullet3d_shape.d.ts +2 -2
  12. package/generated/collectionfactory.d.ts +1 -1
  13. package/generated/collectionproxy.d.ts +2 -2
  14. package/generated/factory.d.ts +4 -2
  15. package/generated/go.d.ts +114 -220
  16. package/generated/graphics.d.ts +5 -0
  17. package/generated/gui.d.ts +148 -371
  18. package/generated/http.d.ts +4 -2
  19. package/generated/image.d.ts +56 -4
  20. package/generated/kinds/gui-script.d.ts +3 -0
  21. package/generated/kinds/render-script.d.ts +15 -15
  22. package/generated/kinds/script.d.ts +1 -0
  23. package/generated/liveupdate.d.ts +5 -1
  24. package/generated/material.d.ts +3 -3
  25. package/generated/model.d.ts +4 -5
  26. package/generated/particlefx.d.ts +20 -1
  27. package/generated/physics.d.ts +48 -4
  28. package/generated/render-script-modules/b2d.d.ts +711 -0
  29. package/generated/render-script-modules/bullet3d.d.ts +73 -0
  30. package/generated/render-script-modules/collectionfactory.d.ts +25 -0
  31. package/generated/render-script-modules/collectionproxy.d.ts +39 -0
  32. package/generated/render-script-modules/factory.d.ts +25 -0
  33. package/generated/render-script-modules/go.d.ts +436 -0
  34. package/generated/render-script-modules/label.d.ts +105 -0
  35. package/generated/render-script-modules/model.d.ts +89 -0
  36. package/generated/render-script-modules/particlefx.d.ts +59 -0
  37. package/generated/render-script-modules/physics.d.ts +333 -0
  38. package/generated/render-script-modules/resource.d.ts +1233 -0
  39. package/generated/render-script-modules/sound.d.ts +227 -0
  40. package/generated/render-script-modules/sprite.d.ts +68 -0
  41. package/generated/render-script-modules/tilemap.d.ts +43 -0
  42. package/generated/render.d.ts +175 -21
  43. package/generated/resource.d.ts +31 -10
  44. package/generated/sprite.d.ts +49 -1
  45. package/generated/sys.d.ts +78 -10
  46. package/generated/tilemap.d.ts +4 -4
  47. package/generated/versions/defold-1.12.4/buffer.d.ts +8 -8
  48. package/generated/versions/defold-1.12.4/collectionfactory.d.ts +1 -1
  49. package/generated/versions/defold-1.12.4/collectionproxy.d.ts +1 -1
  50. package/generated/versions/defold-1.12.4/factory.d.ts +4 -2
  51. package/generated/versions/defold-1.12.4/go.d.ts +115 -343
  52. package/generated/versions/defold-1.12.4/graphics.d.ts +1 -0
  53. package/generated/versions/defold-1.12.4/gui.d.ts +151 -513
  54. package/generated/versions/defold-1.12.4/http.d.ts +4 -2
  55. package/generated/versions/defold-1.12.4/image.d.ts +83 -3
  56. package/generated/versions/defold-1.12.4/index.d.ts +2 -0
  57. package/generated/versions/defold-1.12.4/liveupdate.d.ts +4 -0
  58. package/generated/versions/defold-1.12.4/model.d.ts +4 -5
  59. package/generated/versions/defold-1.12.4/particlefx.d.ts +22 -1
  60. package/generated/versions/defold-1.12.4/physics.d.ts +47 -3
  61. package/generated/versions/defold-1.12.4/render.d.ts +119 -15
  62. package/generated/versions/defold-1.12.4/resource.d.ts +43 -10
  63. package/generated/versions/defold-1.12.4/sprite.d.ts +58 -1
  64. package/generated/versions/defold-1.12.4/sys.d.ts +101 -6
  65. package/generated/versions/defold-1.12.4/tilemap.d.ts +4 -4
  66. package/generated/versions/defold-1.12.4/vmath.d.ts +0 -24
  67. package/generated/versions/defold-1.13.0/buffer.d.ts +8 -8
  68. package/generated/versions/defold-1.13.0/collectionfactory.d.ts +1 -1
  69. package/generated/versions/defold-1.13.0/collectionproxy.d.ts +1 -1
  70. package/generated/versions/defold-1.13.0/factory.d.ts +4 -2
  71. package/generated/versions/defold-1.13.0/go.d.ts +115 -370
  72. package/generated/versions/defold-1.13.0/graphics.d.ts +1 -0
  73. package/generated/versions/defold-1.13.0/gui.d.ts +151 -513
  74. package/generated/versions/defold-1.13.0/http.d.ts +4 -2
  75. package/generated/versions/defold-1.13.0/image.d.ts +83 -3
  76. package/generated/versions/defold-1.13.0/index.d.ts +2 -0
  77. package/generated/versions/defold-1.13.0/liveupdate.d.ts +4 -0
  78. package/generated/versions/defold-1.13.0/material.d.ts +3 -1
  79. package/generated/versions/defold-1.13.0/model.d.ts +4 -5
  80. package/generated/versions/defold-1.13.0/particlefx.d.ts +22 -1
  81. package/generated/versions/defold-1.13.0/physics.d.ts +47 -3
  82. package/generated/versions/defold-1.13.0/render.d.ts +182 -16
  83. package/generated/versions/defold-1.13.0/resource.d.ts +43 -10
  84. package/generated/versions/defold-1.13.0/sprite.d.ts +58 -1
  85. package/generated/versions/defold-1.13.0/sys.d.ts +101 -6
  86. package/generated/versions/defold-1.13.0/tilemap.d.ts +4 -4
  87. package/generated/versions/defold-1.13.0/vmath.d.ts +0 -24
  88. package/generated/versions/defold-1.13.1/buffer.d.ts +8 -8
  89. package/generated/versions/defold-1.13.1/collectionfactory.d.ts +1 -1
  90. package/generated/versions/defold-1.13.1/collectionproxy.d.ts +1 -1
  91. package/generated/versions/defold-1.13.1/factory.d.ts +4 -2
  92. package/generated/versions/defold-1.13.1/go.d.ts +115 -370
  93. package/generated/versions/defold-1.13.1/graphics.d.ts +1 -0
  94. package/generated/versions/defold-1.13.1/gui.d.ts +151 -529
  95. package/generated/versions/defold-1.13.1/http.d.ts +4 -2
  96. package/generated/versions/defold-1.13.1/image.d.ts +83 -3
  97. package/generated/versions/defold-1.13.1/index.d.ts +3 -0
  98. package/generated/versions/defold-1.13.1/liveupdate.d.ts +4 -0
  99. package/generated/versions/defold-1.13.1/material.d.ts +3 -1
  100. package/generated/versions/defold-1.13.1/model.d.ts +4 -5
  101. package/generated/versions/defold-1.13.1/particlefx.d.ts +22 -1
  102. package/generated/versions/defold-1.13.1/physics.d.ts +47 -3
  103. package/generated/versions/defold-1.13.1/render.d.ts +182 -16
  104. package/generated/versions/defold-1.13.1/resource.d.ts +43 -10
  105. package/generated/versions/defold-1.13.1/sprite.d.ts +58 -1
  106. package/generated/versions/defold-1.13.1/sys.d.ts +101 -6
  107. package/generated/versions/defold-1.13.1/tilemap.d.ts +4 -4
  108. package/generated/versions/defold-1.13.1/vmath.d.ts +0 -24
  109. package/generated/versions/defold-1.13.2/b2d_world.d.ts +10 -10
  110. package/generated/versions/defold-1.13.2/buffer.d.ts +9 -9
  111. package/generated/versions/defold-1.13.2/bullet3d_collision_object.d.ts +1 -1
  112. package/generated/versions/defold-1.13.2/bullet3d_constraint.d.ts +109 -7
  113. package/generated/versions/defold-1.13.2/bullet3d_shape.d.ts +2 -2
  114. package/generated/versions/defold-1.13.2/collectionfactory.d.ts +1 -1
  115. package/generated/versions/defold-1.13.2/collectionproxy.d.ts +2 -2
  116. package/generated/versions/defold-1.13.2/factory.d.ts +4 -2
  117. package/generated/versions/defold-1.13.2/go.d.ts +114 -220
  118. package/generated/versions/defold-1.13.2/graphics.d.ts +1 -0
  119. package/generated/versions/defold-1.13.2/gui.d.ts +148 -371
  120. package/generated/versions/defold-1.13.2/http.d.ts +4 -2
  121. package/generated/versions/defold-1.13.2/image.d.ts +56 -4
  122. package/generated/versions/defold-1.13.2/index.d.ts +3 -0
  123. package/generated/versions/defold-1.13.2/liveupdate.d.ts +5 -1
  124. package/generated/versions/defold-1.13.2/material.d.ts +3 -3
  125. package/generated/versions/defold-1.13.2/model.d.ts +4 -5
  126. package/generated/versions/defold-1.13.2/particlefx.d.ts +20 -1
  127. package/generated/versions/defold-1.13.2/physics.d.ts +48 -4
  128. package/generated/versions/defold-1.13.2/render.d.ts +164 -20
  129. package/generated/versions/defold-1.13.2/resource.d.ts +31 -10
  130. package/generated/versions/defold-1.13.2/sprite.d.ts +49 -1
  131. package/generated/versions/defold-1.13.2/sys.d.ts +78 -10
  132. package/generated/versions/defold-1.13.2/tilemap.d.ts +4 -4
  133. package/generated/versions/defold-1.13.2/vmath.d.ts +0 -24
  134. package/generated/versions/defold-1.13.2/window.d.ts +1 -1
  135. package/generated/vmath.d.ts +0 -24
  136. package/generated/window.d.ts +1 -1
  137. package/identity-vocabulary.json +98 -7
  138. package/index.d.ts +3 -0
  139. package/package.json +3 -1
  140. package/scripts/generate-api-availability.ts +6 -22
  141. package/scripts/generate-api-signatures.ts +87 -21
  142. package/scripts/materialize-version.ts +53 -6
  143. package/scripts/regen.ts +256 -44
  144. package/scripts/signature-store-fs.ts +1 -0
  145. package/scripts/target-version.ts +26 -0
  146. package/src/api-doc.ts +26 -0
  147. package/src/component-properties.d.ts +226 -6
  148. package/src/core-types.ts +82 -20
  149. package/src/doc-corrections.ts +53 -5
  150. package/src/emit-dts.ts +1300 -269
  151. package/src/emit-messages.ts +289 -0
  152. package/src/engine-globals.d.ts +8 -2
  153. package/src/go-overloads.d.ts +80 -15
  154. package/src/gui-overloads.d.ts +489 -0
  155. package/src/gui-texture-removal.d.ts +41 -0
  156. package/src/index.ts +2 -0
  157. package/src/lifecycle.ts +46 -37
  158. package/src/luals-type-expr.ts +6 -1
  159. package/src/msg-overloads.d.ts +25 -13
  160. package/src/physics-event-guard.d.ts +39 -0
  161. package/src/render-overloads.d.ts +2 -2
  162. package/src/return-correction-provenance.ts +36 -6
  163. package/src/signature-store.ts +50 -0
  164. package/src/timers.d.ts +2 -1
  165. package/src/vmath-overloads.d.ts +26 -0
  166. package/src/window-event-guard.d.ts +5 -3
package/scripts/regen.ts CHANGED
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname, resolve } from "node:path";
3
3
  import messagesDoc from "../fixtures/messages_doc.json" with { type: "json" };
4
4
  import {
5
+ type ApiFunction,
5
6
  type ApiModule,
6
7
  parseDefoldApiDoc,
7
8
  type SkipOverloadRule,
@@ -15,10 +16,10 @@ import {
15
16
  type SymbolSignature,
16
17
  } from "../src/emit-dts";
17
18
  import {
18
- applyMessageDeprecations,
19
- applyMessageFieldCorrections,
19
+ applyMessageOverlays,
20
20
  type EmitBuiltinMessagesOptions,
21
21
  emitBuiltinMessages,
22
+ type MessageCatalog,
22
23
  parseMessagesDoc,
23
24
  } from "../src/emit-messages";
24
25
  import type { TranslationStore } from "../src/example-store";
@@ -43,6 +44,7 @@ import { loadTranslations } from "./example-store-io";
43
44
  import { synthesizeProseConstants } from "./prose-constants";
44
45
  import { restoreSharedHandleMethods } from "./shared-handle-methods";
45
46
  import { groupDocsByNamespace, mergeApiDocs, type readZip } from "./sync-api-docs";
47
+ import { compareVersions, versionOf } from "./target-version";
46
48
 
47
49
  export interface ApiTargetModule {
48
50
  readonly namespace: string;
@@ -399,21 +401,24 @@ export interface MessagesManifestEntry {
399
401
 
400
402
  // Unlike MODULE_MANIFEST, this surface is hand-maintained: Defold ships no
401
403
  // machine-readable export for built-in message ids, so refresh fixtures/
402
- // messages_doc.json by hand from the Defold API reference. The
403
- // message-payload-drift test guards the payload shapes against drift.
404
+ // messages_doc.json by hand from the default target's API reference. The
405
+ // message-payload-drift test holds its message ids, field names and optionality
406
+ // to that reference in both directions; what only the engine states is
407
+ // MESSAGE_ENGINE_CORRECTIONS.
404
408
  export const MESSAGES_MANIFEST: MessagesManifestEntry = {
405
409
  doc: messagesDoc,
406
410
  outFile: "builtin-messages.d.ts",
407
411
  };
408
412
 
413
+ export function builtinMessagesCatalog(entry: MessagesManifestEntry): MessageCatalog {
414
+ return applyMessageOverlays(parseMessagesDoc(entry.doc));
415
+ }
416
+
409
417
  export function generateBuiltinMessagesDeclaration(
410
418
  entry: MessagesManifestEntry,
411
419
  opts: EmitBuiltinMessagesOptions = {},
412
420
  ): string {
413
- return emitBuiltinMessages(
414
- applyMessageFieldCorrections(applyMessageDeprecations(parseMessagesDoc(entry.doc))),
415
- opts,
416
- );
421
+ return emitBuiltinMessages(builtinMessagesCatalog(entry), opts);
417
422
  }
418
423
 
419
424
  export interface GenerateResult {
@@ -456,21 +461,32 @@ export interface GenerateOptions {
456
461
  translations?: TranslationStore;
457
462
  urlParameters?: UrlParameterTable;
458
463
  registeredConstants?: ReadonlySet<string>;
464
+ bindingEvidence?: ReadonlySet<string>;
465
+ nilRaisingSlots?: ReadonlyMap<string, readonly number[]>;
459
466
  // The modules the entry is emitted beside, the entry among them. Routing
460
467
  // reads this set instead of looking the entry up in a committed manifest, so
461
468
  // a surface built with its own import root still routes as a whole.
462
469
  surface?: readonly ModuleManifestEntry[];
463
470
  }
464
471
 
472
+ // What a target's own engine source decides for its emit (`targetBindingOptions`).
473
+ export type TargetBindingOptions = Pick<
474
+ GenerateOptions,
475
+ "registeredConstants" | "bindingEvidence" | "nilRaisingSlots"
476
+ >;
477
+
465
478
  interface PreparedGeneratedModule {
466
479
  module: ApiModule;
467
480
  knownConstantFqns: ReadonlySet<string>;
468
481
  translations: TranslationStore;
469
482
  urlParameters: UrlParameterTable;
470
483
  registeredConstants: ReadonlySet<string> | undefined;
484
+ bindingEvidence: ReadonlySet<string> | undefined;
485
+ nilRaisingSlots: ReadonlyMap<string, readonly number[]> | undefined;
471
486
  typeLeaves: Readonly<Record<string, string>> | undefined;
472
487
  declaredTypes: ReadonlyMap<string, string> | undefined;
473
488
  dropped: string[];
489
+ withheldFunctions: ApiFunction[];
474
490
  }
475
491
 
476
492
  // Parse a manifest entry, apply its `skipFunctions` and `skipOverloads` filters, and resolve the
@@ -482,7 +498,7 @@ function prepareGeneratedModule(
482
498
  options?: GenerateOptions,
483
499
  ): PreparedGeneratedModule {
484
500
  const routed = routedModuleOf(entry, options?.surface);
485
- const { module, dropped } = routed?.prepared ?? withheldApiModule(entry);
501
+ const { module, dropped, withheldFunctions } = routed?.prepared ?? withheldApiModule(entry);
486
502
  const knownConstantFqns = options?.knownConstantFqns ?? collectConstantFqns();
487
503
  const translations = options?.translations ?? loadTranslations();
488
504
  const urlParameters = options?.urlParameters ?? committedUrlParameters();
@@ -492,14 +508,17 @@ function prepareGeneratedModule(
492
508
  translations,
493
509
  urlParameters,
494
510
  registeredConstants: options?.registeredConstants,
511
+ bindingEvidence: options?.bindingEvidence,
512
+ nilRaisingSlots: options?.nilRaisingSlots,
495
513
  typeLeaves: entry.typeLeaves,
496
514
  declaredTypes: routed?.declaredTypes,
497
515
  dropped,
516
+ withheldFunctions,
498
517
  };
499
518
  }
500
519
 
501
520
  interface RoutedSurface {
502
- readonly modules: ReadonlyMap<ModuleManifestEntry, { module: ApiModule; dropped: string[] }>;
521
+ readonly modules: ReadonlyMap<ModuleManifestEntry, WithheldModule>;
503
522
  readonly declaredTypes: ReadonlyMap<string, string>;
504
523
  }
505
524
 
@@ -513,10 +532,7 @@ function routeSurface(entries: readonly ModuleManifestEntry[]): RoutedSurface {
513
532
  modules: new Map(
514
533
  entries.map((member, index) => [
515
534
  member,
516
- {
517
- module: routed[index] as ApiModule,
518
- dropped: (withheld[index] as { dropped: string[] }).dropped,
519
- },
535
+ { ...(withheld[index] as WithheldModule), module: routed[index] as ApiModule },
520
536
  ]),
521
537
  ),
522
538
  declaredTypes: declaredTypePaths(routed),
@@ -534,7 +550,7 @@ function routedModuleOf(
534
550
  callerSurface?: readonly ModuleManifestEntry[],
535
551
  ):
536
552
  | {
537
- prepared: { module: ApiModule; dropped: string[] };
553
+ prepared: WithheldModule;
538
554
  declaredTypes: ReadonlyMap<string, string>;
539
555
  }
540
556
  | undefined {
@@ -622,8 +638,14 @@ function committedSurfaceOf(
622
638
  };
623
639
  }
624
640
 
641
+ interface WithheldModule {
642
+ module: ApiModule;
643
+ dropped: string[];
644
+ withheldFunctions: ApiFunction[];
645
+ }
646
+
625
647
  // The parsed module with the entry's `skipFunctions` and `skipOverloads` applied.
626
- function withheldApiModule(entry: ModuleManifestEntry): { module: ApiModule; dropped: string[] } {
648
+ function withheldApiModule(entry: ModuleManifestEntry): WithheldModule {
627
649
  let module = parseDefoldApiDoc(entry.doc);
628
650
  const prefix = `${module.namespace}.`;
629
651
  const dropped: string[] = [];
@@ -651,7 +673,8 @@ function withheldApiModule(entry: ModuleManifestEntry): { module: ApiModule; dro
651
673
  }
652
674
  return withheld(name);
653
675
  };
654
- module.functions = module.functions.filter((fn) => !withheld(fn.name));
676
+ const withheldFunctions = module.functions.filter((fn) => withheld(fn.name));
677
+ module.functions = module.functions.filter((fn) => !withheldFunctions.includes(fn));
655
678
  module.variables = module.variables.filter((v) => !withheld(v.name));
656
679
  const withheldConstants = new Set<string>();
657
680
  module.constants = module.constants.filter((c) => {
@@ -667,7 +690,7 @@ function withheldApiModule(entry: ModuleManifestEntry): { module: ApiModule; dro
667
690
  if (module.structs) module.structs = module.structs.filter((s) => !withheldType(s.name));
668
691
  module.typedefs = module.typedefs.filter((t) => t.aliasOf === undefined || !withheldType(t.name));
669
692
  module = withholdOverloads(module, entry.skipOverloads ?? []);
670
- return { module, dropped };
693
+ return { module, dropped, withheldFunctions };
671
694
  }
672
695
 
673
696
  // The field corrections one target's runtime entries leave inert: every entry is
@@ -739,15 +762,21 @@ export function generateModuleDeclaration(
739
762
  translations,
740
763
  urlParameters,
741
764
  registeredConstants,
765
+ bindingEvidence,
766
+ nilRaisingSlots,
742
767
  typeLeaves,
743
768
  declaredTypes,
744
769
  dropped,
770
+ withheldFunctions,
745
771
  } = prepareGeneratedModule(entry, options);
746
772
  const emitted = emitDeclarations(module, {
747
773
  knownConstantFqns,
748
774
  translations,
749
775
  urlParameters,
776
+ withheldFunctions,
750
777
  ...(registeredConstants ? { registeredConstants } : {}),
778
+ ...(bindingEvidence ? { bindingEvidence } : {}),
779
+ ...(nilRaisingSlots ? { nilRaisingSlots } : {}),
751
780
  ...(typeLeaves ? { typeLeaves } : {}),
752
781
  ...(declaredTypes ? { declaredTypes } : {}),
753
782
  ...(entry.indexBaseSource ? { indexBaseSource: entry.indexBaseSource } : {}),
@@ -772,13 +801,19 @@ export function generateModuleSignatures(
772
801
  knownConstantFqns,
773
802
  urlParameters,
774
803
  registeredConstants,
804
+ bindingEvidence,
805
+ nilRaisingSlots,
775
806
  typeLeaves,
776
807
  declaredTypes,
808
+ withheldFunctions,
777
809
  } = prepareGeneratedModule(entry, options);
778
810
  return emitSymbolSignatures(module, {
779
811
  knownConstantFqns,
780
812
  urlParameters,
813
+ withheldFunctions,
781
814
  ...(registeredConstants ? { registeredConstants } : {}),
815
+ ...(bindingEvidence ? { bindingEvidence } : {}),
816
+ ...(nilRaisingSlots ? { nilRaisingSlots } : {}),
782
817
  ...(typeLeaves ? { typeLeaves } : {}),
783
818
  ...(declaredTypes ? { declaredTypes } : {}),
784
819
  });
@@ -845,9 +880,17 @@ export function kindStdlibReferences(entry: KindManifestEntry): string {
845
880
  // `generateKindIndex` stays pure; `srcAugmentationScopingViolations` in
846
881
  // `./augmentation-namespaces` is what catches a future restricted augmentation
847
882
  // added without one, by reading the namespaces each file really re-opens.
883
+ // `since` is the first Defold release, a bare semver, whose engine has what the
884
+ // augmentation declares; a surface generated for an older target omits it.
885
+ // `requiresGoInstance` lists the exact functions an augmentation declares that
886
+ // need a game object, so it rides no index of a kind without one; the same
887
+ // guard checks this list against the functions the file declares, in both
888
+ // directions.
848
889
  interface UniversalExtraImport {
849
890
  readonly specifier: string;
850
891
  readonly restrictedTo?: string;
892
+ readonly since?: string;
893
+ readonly requiresGoInstance?: readonly string[];
851
894
  }
852
895
 
853
896
  const UNIVERSAL_EXTRA_IMPORTS: readonly UniversalExtraImport[] = [
@@ -857,10 +900,19 @@ const UNIVERSAL_EXTRA_IMPORTS: readonly UniversalExtraImport[] = [
857
900
  { specifier: "../../src/msg-overloads" },
858
901
  { specifier: "../../src/message-guard" },
859
902
  { specifier: "../../src/window-event-guard" },
903
+ { specifier: "../../src/physics-event-guard" },
860
904
  { specifier: "../../src/scene-addresses" },
861
- { specifier: "../../src/go-overloads" },
905
+ // `go.property` is listed by hand: `GetScript` finds no `.script` instance in
906
+ // a render script and returns null rather than raising, and `Script_Property`
907
+ // raises on that null itself, a check the bindings manifest does not record.
908
+ {
909
+ specifier: "../../src/go-overloads",
910
+ requiresGoInstance: ["go.get", "go.set", "go.property"],
911
+ },
862
912
  { specifier: "../../src/component-properties" },
863
913
  { specifier: "../../src/render-overloads", restrictedTo: "render" },
914
+ { specifier: "../../src/gui-overloads", restrictedTo: "gui" },
915
+ { specifier: "../../src/gui-texture-removal", restrictedTo: "gui", since: "1.13.1" },
864
916
  { specifier: "../../src/vmath-overloads" },
865
917
  { specifier: "../../src/sys-overloads" },
866
918
  ];
@@ -883,14 +935,57 @@ export const RESTRICTED_SRC_AUGMENTATIONS: Readonly<Record<string, string>> = Ob
883
935
  ).map((entry) => [entry.specifier.slice(SRC_IMPORT_PREFIX.length), entry.restrictedTo as string]),
884
936
  );
885
937
 
886
- // Read those augmentations as surface-root files. Mirrors
887
- // `loadTargetEditorModules`: a missing file throws with its path rather than
888
- // filtering silently, so a renamed augmentation fails loud instead of vanishing
889
- // from every materialized surface.
938
+ // The `src/*` augmentations that declare a function needing a game object, as
939
+ // `<module name> -> <the functions it declares that need one>`. Exported so the
940
+ // scoping guard and the wall probe read the same list.
941
+ export const GO_INSTANCE_SRC_FUNCTIONS: Readonly<Record<string, readonly string[]>> =
942
+ Object.fromEntries(
943
+ UNIVERSAL_EXTRA_IMPORTS.filter(
944
+ (entry) =>
945
+ entry.requiresGoInstance !== undefined && entry.specifier.startsWith(SRC_IMPORT_PREFIX),
946
+ ).map((entry) => [
947
+ entry.specifier.slice(SRC_IMPORT_PREFIX.length),
948
+ entry.requiresGoInstance as readonly string[],
949
+ ]),
950
+ );
951
+
952
+ // The same augmentations as module names. Exported so the materialized kind
953
+ // indexes drop them the same way the in-repo ones do.
954
+ export const GO_INSTANCE_SRC_AUGMENTATIONS: readonly string[] =
955
+ Object.keys(GO_INSTANCE_SRC_FUNCTIONS);
956
+
957
+ // The `src/*` augmentations gated to a release, as `<module name> -> <since>`.
958
+ export const SRC_AUGMENTATION_GATES: Readonly<Record<string, string>> = Object.fromEntries(
959
+ UNIVERSAL_EXTRA_IMPORTS.filter(
960
+ (entry) => entry.since !== undefined && entry.specifier.startsWith(SRC_IMPORT_PREFIX),
961
+ ).map((entry) => [entry.specifier.slice(SRC_IMPORT_PREFIX.length), entry.since as string]),
962
+ );
963
+
964
+ function admitsTarget(entry: UniversalExtraImport, target: ApiTarget): boolean {
965
+ return entry.since === undefined || compareVersions(versionOf(target), entry.since) >= 0;
966
+ }
967
+
968
+ // The `src/*` augmentations a surface generated for `target` carries: those
969
+ // whose gate the target's version meets. Every surface writer reads this one
970
+ // filter, so the committed indexes, the kind indexes and both materializers
971
+ // agree on which arms a target declares.
972
+ export function srcAugmentationModulesFor(target: ApiTarget): readonly string[] {
973
+ return UNIVERSAL_EXTRA_IMPORTS.filter(
974
+ (entry) => entry.specifier.startsWith(SRC_IMPORT_PREFIX) && admitsTarget(entry, target),
975
+ ).map((entry) => entry.specifier.slice(SRC_IMPORT_PREFIX.length));
976
+ }
977
+
978
+ // Read those augmentations as surface-root files, narrowed to `target`'s set
979
+ // when one is given. Mirrors `loadTargetEditorModules`: a missing file throws
980
+ // with its path rather than filtering silently, so a renamed augmentation fails
981
+ // loud instead of vanishing from every materialized surface.
890
982
  export function loadSrcAugmentations(
891
983
  packageRoot: string = PACKAGE_ROOT,
984
+ target?: ApiTarget,
892
985
  ): { path: string; contents: string }[] {
893
- return SRC_AUGMENTATION_MODULES.map((name) => {
986
+ const modules =
987
+ target === undefined ? SRC_AUGMENTATION_MODULES : srcAugmentationModulesFor(target);
988
+ return modules.map((name) => {
894
989
  const from = resolve(packageRoot, "src", `${name}.d.ts`);
895
990
  let contents: string;
896
991
  try {
@@ -902,6 +997,76 @@ export function loadSrcAugmentations(
902
997
  });
903
998
  }
904
999
 
1000
+ export const GO_INSTANCE_FUNCTIONS_FILE = "go-instance-functions.json";
1001
+
1002
+ export type GoInstanceFunctions = Readonly<Record<string, readonly string[]>>;
1003
+
1004
+ // The functions that need a game-object instance on `target`, keyed by fqn,
1005
+ // read from the manifest `go-instance-functions.ts` commits beside the target's
1006
+ // fixtures. `null` for a target with no vendored engine source to derive it
1007
+ // from, whose surfaces keep every function.
1008
+ export function loadGoInstanceFunctions(
1009
+ target: ApiTarget,
1010
+ packageRoot: string = PACKAGE_ROOT,
1011
+ ): GoInstanceFunctions | null {
1012
+ const path = resolve(packageRoot, target.fixturesDir, GO_INSTANCE_FUNCTIONS_FILE);
1013
+ if (!existsSync(path)) return null;
1014
+ return JSON.parse(readFileSync(path, "utf8")) as GoInstanceFunctions;
1015
+ }
1016
+
1017
+ // The functions a kind with no game object omits, by the bare name of the
1018
+ // module declaring them: `<module> -> <local names>`. A module declaring none,
1019
+ // or declaring only names its skip rules already withhold, has no entry.
1020
+ export function goInstanceWalls(
1021
+ modules: readonly ModuleManifestEntry[],
1022
+ needsGoInstance: GoInstanceFunctions | null,
1023
+ ): Map<string, string[]> {
1024
+ const walls = new Map<string, string[]>();
1025
+ if (needsGoInstance === null) return walls;
1026
+ const fqns = Object.keys(needsGoInstance);
1027
+ for (const entry of modules) {
1028
+ const prefix = `${entry.namespace}.`;
1029
+ const localOf = (name: string): string =>
1030
+ name.startsWith(prefix) ? name.slice(prefix.length) : name;
1031
+ const declared = new Set(parseDefoldApiDoc(entry.doc).functions.map((fn) => localOf(fn.name)));
1032
+ const rules = entry.skipFunctions ?? [];
1033
+ const skipped = (local: string): boolean =>
1034
+ rules.some((rule) => (rule.endsWith(".") ? local.startsWith(rule) : local === rule));
1035
+ const walled = fqns
1036
+ .filter((fqn) => fqn.startsWith(prefix))
1037
+ .map(localOf)
1038
+ .filter((local) => !local.includes(".") && declared.has(local) && !skipped(local))
1039
+ .sort();
1040
+ if (walled.length > 0) walls.set(entry.outFile.replace(/\.d\.ts$/, ""), walled);
1041
+ }
1042
+ return walls;
1043
+ }
1044
+
1045
+ // The modules a kind with no game object is emitted from: each walled module is
1046
+ // replaced by a copy that withholds the functions needing one and lands in
1047
+ // `dir`, one level below the surface root. The surface is returned whole
1048
+ // because a copy routes its types across its siblings, never alone.
1049
+ export function goInstanceFreeSurface(
1050
+ modules: readonly ModuleManifestEntry[],
1051
+ walls: ReadonlyMap<string, readonly string[]>,
1052
+ dir: string,
1053
+ ): { surface: ModuleManifestEntry[]; copies: ModuleManifestEntry[] } {
1054
+ const copies: ModuleManifestEntry[] = [];
1055
+ const surface = modules.map((entry) => {
1056
+ const walled = walls.get(entry.outFile.replace(/\.d\.ts$/, ""));
1057
+ if (walled === undefined) return entry;
1058
+ const copy: ModuleManifestEntry = {
1059
+ ...entry,
1060
+ outFile: `${dir}/${entry.outFile}`,
1061
+ importsFrom: oneLevelDeeper(entry.importsFrom ?? "../src/core-types"),
1062
+ skipFunctions: [...(entry.skipFunctions ?? []), ...walled],
1063
+ };
1064
+ copies.push(copy);
1065
+ return copy;
1066
+ });
1067
+ return { surface, copies };
1068
+ }
1069
+
905
1070
  const DEFAULT_FACTORY_MODULE = "../../src/lifecycle";
906
1071
 
907
1072
  export interface KindManifestEntry {
@@ -927,12 +1092,23 @@ export interface KindManifestEntry {
927
1092
  readonly propertyTypes?: boolean;
928
1093
  // Whether the kind's VM is LuaJIT. The editor runs plain Lua 5.1.
929
1094
  readonly jit?: boolean;
1095
+ // Set for a kind whose script has no game object: the directory, beside the
1096
+ // surface root, holding copies of the modules that declare a function needing
1097
+ // one, with those functions withheld. Its index imports the copies instead.
1098
+ readonly goInstanceFreeDir?: string;
930
1099
  }
931
1100
 
932
1101
  export const KIND_MODULE_MANIFEST: readonly KindManifestEntry[] = [
933
1102
  { kind: "script", factory: "defineScript" },
934
1103
  { kind: "gui-script", restricted: "gui", factory: "defineGuiScript" },
935
- { kind: "render-script", restricted: "render", factory: "defineRenderScript" },
1104
+ {
1105
+ kind: "render-script",
1106
+ restricted: "render",
1107
+ factory: "defineRenderScript",
1108
+ // Only the GUI component registers a game-object resolver
1109
+ // (`comp_gui.cpp`), so every `CheckGOInstance` raises in a render script.
1110
+ goInstanceFreeDir: "render-script-modules",
1111
+ },
936
1112
  {
937
1113
  kind: "editor-script",
938
1114
  // Empty on purpose: the emitted namespaces come from the declaring target's
@@ -979,17 +1155,30 @@ export function generateKindIndex(kind: string, target: ApiTarget = DEFAULT_TARG
979
1155
  const entry = KIND_MODULE_MANIFEST.find((e) => e.kind === kind);
980
1156
  if (!entry) throw new Error(`unknown script kind: ${kind}`);
981
1157
  const srcPrefix = targetSrcPrefix(target);
1158
+ // A kind with no game object loses what needs one, on a target whose engine
1159
+ // source records what that is; a module declaring such a function is
1160
+ // imported from its filtered copy.
1161
+ const freeDir = entry.goInstanceFreeDir;
1162
+ const needsGoInstance = freeDir === undefined ? null : loadGoInstanceFunctions(target);
1163
+ const walls = goInstanceWalls(MODULE_MANIFEST, needsGoInstance);
982
1164
  const universalNamespaces = MODULE_MANIFEST.filter(
983
1165
  (m) => !Object.hasOwn(RESTRICTED_NAMESPACES, m.namespace),
984
- ).map((m) => `../${m.outFile.replace(/\.d\.ts$/, "")}`);
1166
+ )
1167
+ .map((m) => m.outFile.replace(/\.d\.ts$/, ""))
1168
+ .sort()
1169
+ .map((base) => (walls.has(base) ? `../${freeDir}/${base}` : `../${base}`));
985
1170
  // An augmentation bound to a restricted namespace rides only that namespace's
986
- // kind index; every unmarked entry stays universal.
1171
+ // kind index; every unmarked entry stays universal. A gated entry rides only a
1172
+ // target its gate admits, and a marked one only a kind with a game object.
987
1173
  const extraImports = UNIVERSAL_EXTRA_IMPORTS.filter(
988
- (extra) => extra.restrictedTo === undefined || extra.restrictedTo === entry.restricted,
1174
+ (extra) =>
1175
+ (extra.restrictedTo === undefined || extra.restrictedTo === entry.restricted) &&
1176
+ (needsGoInstance === null || extra.requiresGoInstance === undefined) &&
1177
+ admitsTarget(extra, target),
989
1178
  ).map((extra) => extra.specifier);
990
1179
  const modules = (
991
1180
  entry.only === undefined
992
- ? [...new Set([...universalNamespaces.sort(), ...extraImports.sort()])]
1181
+ ? [...new Set([...universalNamespaces, ...extraImports.sort()])]
993
1182
  : [...editorKindModules(target), ...(entry.extraModules ?? [])]
994
1183
  ).map((path) => retargetSrcPath(path, srcPrefix));
995
1184
  const lines = modules.map((path) => `import "${path}";`);
@@ -1034,11 +1223,11 @@ export function generateVersionIndex(
1034
1223
  // The authored augmentations a committed per-version index imports, addressed
1035
1224
  // back into the package's `src/`. The in-repo surface has no copies beside its
1036
1225
  // modules, so a skipped symbol would otherwise be declared on no versioned
1037
- // surface at all. Derived from `SRC_AUGMENTATION_MODULES`, so a new augmentation
1226
+ // surface at all. Derived from `srcAugmentationModulesFor`, so a new augmentation
1038
1227
  // reaches the pinned surfaces on the same edit that reaches the materialized ones.
1039
1228
  export function versionSrcAugmentationImports(target: ApiTarget): string[] {
1040
1229
  const srcPrefix = target.coreTypesImport.slice(0, -"core-types".length);
1041
- return SRC_AUGMENTATION_MODULES.map((name) => `${srcPrefix}${name}`);
1230
+ return srcAugmentationModulesFor(target).map((name) => `${srcPrefix}${name}`);
1042
1231
  }
1043
1232
 
1044
1233
  // The `src/`-relative prefix a kind index living in `<generatedDir>/kinds/` needs
@@ -1069,6 +1258,9 @@ export function targetKindManifest(target: ApiTarget): readonly KindManifestEntr
1069
1258
 
1070
1259
  // Every `src/*` augmentation bound to a kind-restricted namespace carries its
1071
1260
  // `restrictedTo` marker, and every marker names a namespace its file re-opens.
1261
+ // Likewise `requiresGoInstance` sits on exactly the files declaring a function
1262
+ // the default target's manifest lists, read from this package whatever root the
1263
+ // files come from, and lists exactly the functions its file declares.
1072
1264
  // Exported so a test can reach the guard the entry point runs; never called on
1073
1265
  // import, so the dynamic import below stays unreached from an installed package.
1074
1266
  export async function assertSrcAugmentationScoping(
@@ -1076,13 +1268,18 @@ export async function assertSrcAugmentationScoping(
1076
1268
  ): Promise<number> {
1077
1269
  // Imported here rather than at module scope: it imports the devDependency
1078
1270
  // `typescript`, and `resolve` loads this module from an installed package.
1079
- const { srcAugmentationScopingViolations } = await import("./augmentation-namespaces");
1080
- const files = loadSrcAugmentations(packageRoot);
1081
- const violations = srcAugmentationScopingViolations(
1082
- files,
1083
- RESTRICTED_SRC_AUGMENTATIONS,
1084
- RESTRICTED_NAMESPACES,
1271
+ const { goInstanceMarkerViolations, srcAugmentationScopingViolations } = await import(
1272
+ "./augmentation-namespaces"
1085
1273
  );
1274
+ const files = loadSrcAugmentations(packageRoot);
1275
+ const violations = [
1276
+ ...srcAugmentationScopingViolations(files, RESTRICTED_SRC_AUGMENTATIONS, RESTRICTED_NAMESPACES),
1277
+ ...goInstanceMarkerViolations(
1278
+ files,
1279
+ GO_INSTANCE_SRC_FUNCTIONS,
1280
+ new Set(Object.keys(loadGoInstanceFunctions(DEFAULT_TARGET) ?? {})),
1281
+ ),
1282
+ ];
1086
1283
  if (violations.length > 0) {
1087
1284
  throw new Error(`src augmentation scoping violations:\n${violations.join("\n")}`);
1088
1285
  }
@@ -1127,14 +1324,12 @@ export async function regenerate(
1127
1324
 
1128
1325
  // Imported here rather than at module scope: the vendored engine bindings are
1129
1326
  // not published, and `resolve` loads this module from an installed package.
1130
- const { registeredConstantFqns } = await import("./engine-binding-extract");
1327
+ const { targetBindingOptions } = await import("./binding-pin");
1131
1328
  const generated = resolve(import.meta.dir, "..", "generated");
1132
1329
  io.mkdir(resolve(generated, "editor-vm"));
1133
- const defaultRegistered = registeredConstantFqns(DEFAULT_TARGET);
1330
+ const defaultBinding = targetBindingOptions(DEFAULT_TARGET);
1134
1331
  for (const entry of MODULE_MANIFEST) {
1135
- const { contents, dropped } = generateModuleDeclaration(entry, {
1136
- ...(defaultRegistered ? { registeredConstants: defaultRegistered } : {}),
1137
- });
1332
+ const { contents, dropped } = generateModuleDeclaration(entry, defaultBinding);
1138
1333
  if (dropped.length > 0) {
1139
1334
  io.log(`note: dropped skipped member(s) from ${entry.namespace}: ${dropped.join(", ")}`);
1140
1335
  }
@@ -1183,10 +1378,9 @@ export async function regenerate(
1183
1378
  };
1184
1379
  for (const entry of VERSIONED_MODULE_MANIFEST) {
1185
1380
  const target = versionedTargets.find((t) => t.id === entry.versionId);
1186
- const registeredConstants = target ? registeredConstantFqns(target) : undefined;
1187
1381
  const { contents, dropped } = generateModuleDeclaration(
1188
1382
  entry,
1189
- registeredConstants ? { registeredConstants } : undefined,
1383
+ target ? targetBindingOptions(target) : undefined,
1190
1384
  );
1191
1385
  if (dropped.length > 0) {
1192
1386
  io.log(
@@ -1222,6 +1416,24 @@ export async function regenerate(
1222
1416
  }
1223
1417
  }
1224
1418
 
1419
+ // The copies a kind with no game object imports instead of the modules that
1420
+ // declare a function needing one; `generateKindIndex` routes to this same set.
1421
+ const defaultWalls = goInstanceWalls(MODULE_MANIFEST, loadGoInstanceFunctions(DEFAULT_TARGET));
1422
+ for (const entry of KIND_MODULE_MANIFEST) {
1423
+ if (entry.goInstanceFreeDir === undefined) continue;
1424
+ const { surface, copies } = goInstanceFreeSurface(
1425
+ MODULE_MANIFEST,
1426
+ defaultWalls,
1427
+ entry.goInstanceFreeDir,
1428
+ );
1429
+ io.mkdir(resolve(generated, entry.goInstanceFreeDir));
1430
+ for (const copy of copies) {
1431
+ const out = resolve(generated, copy.outFile);
1432
+ io.write(out, generateModuleDeclaration(copy, { ...defaultBinding, surface }).contents);
1433
+ io.log(`wrote ${out}`);
1434
+ }
1435
+ }
1436
+
1225
1437
  const kindsDir = resolve(generated, "kinds");
1226
1438
  io.mkdir(kindsDir);
1227
1439
  for (const entry of KIND_MODULE_MANIFEST) {
@@ -23,6 +23,7 @@ export const BASE_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures",
23
23
  export const SOCKET_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "socket.json");
24
24
  export const VMATH_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "vmath.json");
25
25
  export const GO_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "go.json");
26
+ export const GUI_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "gui.json");
26
27
  export const MSG_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "msg.json");
27
28
  export const RENDER_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "render.json");
28
29
  export const SYS_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "sys.json");
@@ -0,0 +1,26 @@
1
+ const VERSION_FROM_ID = /^defold-(\d+\.\d+\.\d+)$/;
2
+
3
+ // A ref-doc target names its release outright; a committed one carries it in
4
+ // its id.
5
+ export function versionOf(target: {
6
+ readonly id: string;
7
+ readonly source?: { readonly version: string } | null;
8
+ }): string {
9
+ if (target.source) return target.source.version;
10
+ const match = VERSION_FROM_ID.exec(target.id);
11
+ if (!match?.[1]) throw new Error(`cannot derive a release version from target id "${target.id}"`);
12
+ return match[1];
13
+ }
14
+
15
+ function versionTuple(version: string): number[] {
16
+ return version.split(".").map((part) => Number.parseInt(part, 10));
17
+ }
18
+
19
+ export function compareVersions(a: string, b: string): number {
20
+ const [ta, tb] = [versionTuple(a), versionTuple(b)];
21
+ for (let index = 0; index < Math.max(ta.length, tb.length); index += 1) {
22
+ const diff = (ta[index] ?? 0) - (tb[index] ?? 0);
23
+ if (diff !== 0) return diff;
24
+ }
25
+ return 0;
26
+ }
package/src/api-doc.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { correctedDoc, docCorrectionKey } from "./doc-corrections";
2
+ import { SCRIPT_HOOK_NAMES } from "./lifecycle";
2
3
 
3
4
  export interface ApiModule {
4
5
  namespace: string;
@@ -16,6 +17,12 @@ export interface ApiModule {
16
17
  enums?: ApiEnum[];
17
18
  /** Each ref-doc `STRUCT`. Absent on a hand-built module, read as an empty list. */
18
19
  structs?: ApiStruct[];
20
+ /**
21
+ * Each lifecycle hook the reference documents as a bare-named `FUNCTION` under
22
+ * `go` or `gui`. The engine calls it as a script global and binds nothing under
23
+ * the name. Absent on a hand-built module.
24
+ */
25
+ scriptHooks?: ApiFunction[];
19
26
  }
20
27
 
21
28
  /** A ref-doc `STRUCT`: a named table shape. */
@@ -193,6 +200,17 @@ export const FUNCTION_NAME_CORRECTIONS: ReadonlyMap<string, FunctionNameCorrecti
193
200
  ],
194
201
  ]);
195
202
 
203
+ // The engine reads each hook a script defines with `lua_getglobal` over
204
+ // `SCRIPT_FUNCTION_NAMES` (`gameobject_script.cpp`, and `gui.cpp` for GUI
205
+ // scripts) and registers no module function under the name, yet the reference
206
+ // documents the hooks as bare-named `go` and `gui` functions.
207
+ export const SCRIPT_HOOK_NAMESPACES: ReadonlySet<string> = new Set(["go", "gui"]);
208
+ const SCRIPT_HOOK_NAME_SET: ReadonlySet<string> = new Set(SCRIPT_HOOK_NAMES);
209
+
210
+ function isScriptHook(namespace: string, name: string): boolean {
211
+ return SCRIPT_HOOK_NAMESPACES.has(namespace) && SCRIPT_HOOK_NAME_SET.has(name);
212
+ }
213
+
196
214
  export function parseDefoldApiDoc(input: unknown): ApiModule {
197
215
  if (!isRecord(input)) {
198
216
  throw new Error(`parseDefoldApiDoc: expected object, got ${describeKind(input)}`);
@@ -218,12 +236,17 @@ export function parseDefoldApiDoc(input: unknown): ApiModule {
218
236
  const typedefs: ApiTypedef[] = [];
219
237
  const enums: ApiEnum[] = [];
220
238
  const structs: ApiStruct[] = [];
239
+ const scriptHooks: ApiFunction[] = [];
221
240
 
222
241
  for (const element of elements) {
223
242
  if (!isRecord(element)) continue;
224
243
  const type = element.type;
225
244
  if (type === "FUNCTION") {
226
245
  const fn = withDocCorrections(parseFunction(element));
246
+ if (isScriptHook(namespace, fn.name)) {
247
+ scriptHooks.push(fn);
248
+ continue;
249
+ }
227
250
  const corrected = FUNCTION_NAME_CORRECTIONS.get(fn.name);
228
251
  functions.push(corrected === undefined ? fn : { ...fn, name: corrected.name });
229
252
  } else if (type === "VARIABLE") {
@@ -264,6 +287,7 @@ export function parseDefoldApiDoc(input: unknown): ApiModule {
264
287
  typedefs,
265
288
  enums,
266
289
  structs,
290
+ scriptHooks,
267
291
  };
268
292
  }
269
293
 
@@ -310,6 +334,8 @@ function withDocCorrections(fn: ApiFunction): ApiFunction {
310
334
  };
311
335
  return {
312
336
  ...fn,
337
+ brief: correctedDoc(docCorrectionKey(fn.name, "brief"), fn.brief),
338
+ description: correctedDoc(docCorrectionKey(fn.name, "description"), fn.description),
313
339
  parameters: fn.parameters.map(correct("param")),
314
340
  returnValues: fn.returnValues.map(correct("return")),
315
341
  };