@lucent-lang/lucent 0.1.2 → 0.1.3

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 (31) hide show
  1. package/bin/lucent.cjs +2 -0
  2. package/dist/{bench-Ec_oPBhN.js → bench-BLZugR80.js} +1 -1
  3. package/dist/{build-B2E9SkG_.js → build-C1Uct_mH.js} +1 -1
  4. package/dist/{build-check-DYWM9LHo.js → build-check-hlYTmPRd.js} +1 -1
  5. package/dist/{check-DzsBZmBa.js → check-BksBP--n.js} +1 -1
  6. package/dist/cli.js +15 -11
  7. package/dist/{codes-D-6LxUqD.js → codes-B6AgFgAq.js} +24 -2
  8. package/dist/compiler.js +3 -3
  9. package/dist/{dashboard--hlNXMUi.js → dashboard-CzOJghrS.js} +1 -1
  10. package/dist/{dev-ClJalHD4.js → dev-CtaNF3sP.js} +3 -3
  11. package/dist/{explain-Byit07F-.js → explain-ImANcx5a.js} +1 -1
  12. package/dist/{pipeline-rDlFUUa1.js → pipeline-DXFTV3Mg.js} +21 -7
  13. package/dist/{project-MN6cwMwO.js → project-Bp9I-fLP.js} +254 -5
  14. package/dist/{sdk-coverage-DL81IAi9.js → sdk-coverage-BpbKBG_O.js} +33 -4
  15. package/dist/{sdk-diff-DbPQmOSD.js → sdk-diff-BueKDJQB.js} +3 -3
  16. package/dist/{sdk-lock-BWHZdSu-.js → sdk-lock-CKLnZ0Wl.js} +2 -2
  17. package/dist/{sdk-prefetch-D-MAqtZs.js → sdk-prefetch-rk6MuMe6.js} +2 -2
  18. package/dist/{sdk-search-BDercg36.js → sdk-search-U_2M81lq.js} +2 -2
  19. package/dist/{sdk-show-DEdKobD7.js → sdk-show-DG6H40fp.js} +2 -2
  20. package/dist/{sdk-usage-D_ly-uLw.js → sdk-usage-Cc7u1i0L.js} +1 -1
  21. package/dist/{src-Bzpv4-ox.js → src-DMbXwPlK.js} +2156 -522
  22. package/lib/sdk/android.d.ts +12 -0
  23. package/lib/sdk/compose.d.ts +17 -4
  24. package/lib/sdk/ui.d.ts +21 -0
  25. package/package.json +4 -4
  26. package/runtime/cpp/lucent/platform/android.cpp +152 -16
  27. package/runtime/cpp/lucent/platform/android.h +79 -2
  28. package/runtime/cpp/lucent/platform/ios.h +7 -0
  29. package/runtime/cpp/lucent/platform/ios_ui.h +20 -0
  30. package/runtime/cpp/rn/LucentComponentView.mm +12 -0
  31. package/runtime/cpp/rn/LucentViewSizing.h +9 -1
@@ -1,4 +1,4 @@
1
- import { n as Explanations, r as docsUrl, t as Codes } from "./codes-D-6LxUqD.js";
1
+ import { n as Explanations, r as docsUrl, t as Codes } from "./codes-B6AgFgAq.js";
2
2
  import { n as lucentPackages, t as lucentPackageOf } from "./packages-CSmKeaAh.js";
3
3
  import { createRequire } from "node:module";
4
4
  import fs from "node:fs";
@@ -13,19 +13,23 @@ import { spawnSync } from "node:child_process";
13
13
  var CompileError = class extends Error {
14
14
  node;
15
15
  code;
16
- constructor(node, code, message) {
16
+ fix;
17
+ constructor(node, code, message, fix) {
17
18
  super(message);
18
19
  this.node = node;
19
20
  this.code = code;
21
+ this.fix = fix;
20
22
  }
21
23
  };
22
- function fail$2(node, code, message) {
23
- throw new CompileError(node, code, message);
24
+ function fail$2(node, code, message, fix) {
25
+ throw new CompileError(node, code, message, fix);
24
26
  }
25
27
  function toDiagnostic(e) {
28
+ const fix = e.fix ? { fix: e.fix } : {};
26
29
  if (!e.node) return {
27
30
  code: e.code,
28
- message: e.message
31
+ message: e.message,
32
+ ...fix
29
33
  };
30
34
  const sf = e.node.getSourceFile();
31
35
  const start = e.node.getStart(sf);
@@ -37,7 +41,8 @@ function toDiagnostic(e) {
37
41
  line: line + 1,
38
42
  column: character + 1,
39
43
  start,
40
- length: e.node.getEnd() - start
44
+ length: e.node.getEnd() - start,
45
+ ...fix
41
46
  };
42
47
  }
43
48
  function formatDiagnostic(d) {
@@ -1407,10 +1412,17 @@ const mods$1 = (ms) => [...ms ?? []].sort((a, b) => MODIFIER_ORDER.indexOf(a) -
1407
1412
  const annotations = (as, indent) => (as ?? []).map((a) => `${indent}@${a}`);
1408
1413
  const params$3 = (ps, indent) => ps.map((p) => `${ident(p.name)}: ${printType$2(p.type)}${p.default ? ` = ${expr$2(p.default, PREC$1.lowest, indent)}` : ""}`).join(", ");
1409
1414
  function fun(f, indent) {
1410
- const tps = f.typeParams?.length ? `<${f.typeParams.map(ident).join(", ")}> ` : "";
1415
+ const bounds = (n) => f.bounds?.[n] ?? [];
1416
+ const typeParam = (n) => {
1417
+ const [only, ...more] = bounds(n);
1418
+ return only && !more.length ? `${ident(n)} : ${printType$2(only)}` : ident(n);
1419
+ };
1420
+ const where = (f.typeParams ?? []).filter((n) => bounds(n).length > 1).flatMap((n) => bounds(n).map((b) => `${ident(n)} : ${printType$2(b)}`));
1421
+ const tps = f.typeParams?.length ? `<${f.typeParams.map(typeParam).join(", ")}> ` : "";
1411
1422
  const receiver = f.receiver ? `${printType$2(f.receiver)}.` : "";
1412
1423
  const ret = f.ret ? `: ${printType$2(f.ret)}` : "";
1413
- const head = `${indent}${mods$1(f.modifiers)}fun ${tps}${receiver}${ident(f.name)}(${params$3(f.params, indent)})${ret}`;
1424
+ const clause = where.length ? ` where ${where.join(", ")}` : "";
1425
+ const head = `${indent}${mods$1(f.modifiers)}fun ${tps}${receiver}${ident(f.name)}(${params$3(f.params, indent)})${ret}${clause}`;
1414
1426
  return [...annotations(f.annotations, indent), ...f.body ? [
1415
1427
  `${head} {`,
1416
1428
  ...block$1(f.body, indent + INDENT$2),
@@ -1495,6 +1507,11 @@ const fn$4 = (params, ret) => ({
1495
1507
  params,
1496
1508
  ret
1497
1509
  });
1510
+ const blockFunction = (params, ret) => ({
1511
+ k: "blockFunction",
1512
+ params,
1513
+ ret
1514
+ });
1498
1515
  const opaque = (of) => ({
1499
1516
  k: "opaque",
1500
1517
  of
@@ -1526,6 +1543,10 @@ const arrayLiteral = (items) => ({
1526
1543
  k: "arrayLiteral",
1527
1544
  items
1528
1545
  });
1546
+ const tupleLiteral = (items) => ({
1547
+ k: "tupleLiteral",
1548
+ items
1549
+ });
1529
1550
  const dictionaryLiteral = (entries) => ({
1530
1551
  k: "dictionaryLiteral",
1531
1552
  entries
@@ -1622,10 +1643,11 @@ const INDENT$1 = " ";
1622
1643
  function printType$1(t) {
1623
1644
  switch (t.k) {
1624
1645
  case "named": return t.args?.length ? `${t.name}<${t.args.map(printType$1).join(", ")}>` : t.name;
1625
- case "optional": return t.of.k === "cFunction" || t.of.k === "function" ? `(${printType$1(t.of)})?` : `${printType$1(t.of)}?`;
1646
+ case "optional": return t.of.k === "cFunction" || t.of.k === "blockFunction" || t.of.k === "function" ? `(${printType$1(t.of)})?` : `${printType$1(t.of)}?`;
1626
1647
  case "array": return `[${printType$1(t.of)}]`;
1627
1648
  case "dictionary": return `[${printType$1(t.key)}: ${printType$1(t.value)}]`;
1628
1649
  case "cFunction": return `@convention(c) (${t.params.map(printType$1).join(", ")}) -> ${printType$1(t.ret)}`;
1650
+ case "blockFunction": return `@convention(block) (${t.params.map(printType$1).join(", ")}) -> ${printType$1(t.ret)}`;
1629
1651
  case "function": return `(${t.params.map(printType$1).join(", ")}) -> ${printType$1(t.ret)}`;
1630
1652
  case "opaque": return `some ${printType$1(t.of)}`;
1631
1653
  }
@@ -1704,6 +1726,7 @@ function bare(e, indent) {
1704
1726
  case "self": return "self";
1705
1727
  case "member": return `${expr$1(e.object, PREC.postfix, indent)}.${e.name}`;
1706
1728
  case "arrayLiteral": return `[${e.items.map((x) => expr$1(x, PREC.assign, indent)).join(", ")}]`;
1729
+ case "tupleLiteral": return `(${e.items.map((x) => expr$1(x, PREC.assign, indent)).join(", ")})`;
1707
1730
  case "dictionaryLiteral":
1708
1731
  if (!e.entries.length) return "[:]";
1709
1732
  return `[${e.entries.map((x) => `${expr$1(x.key, PREC.assign, indent)}: ${expr$1(x.value, PREC.assign, indent)}`).join(", ")}]`;
@@ -1894,7 +1917,7 @@ function bareType(t) {
1894
1917
  case "array": return `${t.readonly ? "readonly " : ""}${type$1(t.of, At.arrayElement)}[]`;
1895
1918
  case "union": return t.members.map((m) => type$1(m, At.unionMember)).join(" | ");
1896
1919
  case "intersection": return t.members.map((m) => type$1(m, At.intersectionMember)).join(" & ");
1897
- case "tuple": return `[${t.elements.map((e) => e.optional ? `${type$1(e.type, At.arrayElement)}?` : printType(e.type)).join(", ")}]`;
1920
+ case "tuple": return `[${t.elements.map((e) => e.name ? `${e.name}${e.optional ? "?" : ""}: ${printType(e.type)}` : e.optional ? `${type$1(e.type, At.arrayElement)}?` : printType(e.type)).join(", ")}]`;
1898
1921
  case "fn": return `(${params$1(t.params)}) => ${printType(t.ret)}`;
1899
1922
  case "object": return t.members.length ? `{ ${t.members.map((m) => `${m.readonly ? "readonly " : ""}${propertyName$2(m.name)}${m.optional ? "?" : ""}: ${printType(m.type)}`).join("; ")} }` : "{}";
1900
1923
  case "literal": return typeof t.value === "bigint" ? `${t.value}n` : JSON.stringify(t.value);
@@ -1962,6 +1985,14 @@ function member$2(m) {
1962
1985
  case "property": {
1963
1986
  const mods = `${m.private ? "private " : ""}${m.static ? "static " : ""}${m.readonly ? "readonly " : ""}`;
1964
1987
  const name = m.computed ? `[${m.name}]` : propertyName$2(m.name);
1988
+ if (m.set) {
1989
+ const at = `${INDENT}${m.private ? "private " : ""}${m.static ? "static " : ""}`;
1990
+ return [
1991
+ ...doc,
1992
+ `${at}get ${name}(): ${printType(m.type)};`,
1993
+ `${at}set ${name}(value: ${printType(m.set)});`
1994
+ ];
1995
+ }
1965
1996
  return [...doc, `${INDENT}${mods}${name}${m.optional ? "?" : ""}: ${printType(m.type)};`];
1966
1997
  }
1967
1998
  case "call": return [...doc, `${INDENT}${typeParams(m.typeParams)}(${params$1(m.params)}): ${printType(m.ret)};`];
@@ -2146,7 +2177,7 @@ const stmt = (s) => ({
2146
2177
  const blank = { k: "blank" };
2147
2178
  //#endregion
2148
2179
  //#region ../codegen/src/xml/index.ts
2149
- const element$1 = (name, attributes = {}, children) => children ? {
2180
+ const element$2 = (name, attributes = {}, children) => children ? {
2150
2181
  name,
2151
2182
  attributes,
2152
2183
  children
@@ -2365,7 +2396,7 @@ const PRIMS$1 = [
2365
2396
  "uint64"
2366
2397
  ];
2367
2398
  function parseSchemaType(s, module = "", typeParams = []) {
2368
- const toks = s.match(/@\w+|=>|[()[\]<>?,]|[\w.$]+/g) ?? [];
2399
+ const toks = s.match(/@\w+|=>|[()[\]<>?,:]|[\w.$]+/g) ?? [];
2369
2400
  let p = 0;
2370
2401
  const expect = (t) => {
2371
2402
  if (toks[p++] !== t) throw new Error(`schema type ${s}: expected ${t}`);
@@ -2430,6 +2461,26 @@ function parseSchemaType(s, module = "", typeParams = []) {
2430
2461
  nullable: false
2431
2462
  };
2432
2463
  }
2464
+ if (name === "Tuple") {
2465
+ const of = [];
2466
+ const labels = [];
2467
+ for (;;) {
2468
+ if (toks[p + 1] === ":") {
2469
+ labels.push(toks[p]);
2470
+ p += 2;
2471
+ }
2472
+ of.push(type());
2473
+ if (toks[p] !== ",") break;
2474
+ p++;
2475
+ }
2476
+ expect(">");
2477
+ return {
2478
+ k: "tuple",
2479
+ of,
2480
+ ...labels.length === of.length ? { labels } : {},
2481
+ nullable: false
2482
+ };
2483
+ }
2433
2484
  const args = [type()];
2434
2485
  while (toks[p] === ",") {
2435
2486
  p++;
@@ -2578,6 +2629,7 @@ function formatSchemaType(t) {
2578
2629
  }
2579
2630
  case "record": return t.cf ? `CFDictionary${q}` : `Record<${formatSchemaType(t.of)}>${q}`;
2580
2631
  case "set": return `Set<${formatSchemaType(t.of)}>${q}`;
2632
+ case "tuple": return `Tuple<${t.of.map((x, i) => `${t.labels ? `${t.labels[i]}: ` : ""}${formatSchemaType(x)}`).join(", ")}>${q}`;
2581
2633
  case "out": return `Out<${formatSchemaType(t.of)}>${q}`;
2582
2634
  case "classOf": return `Class<${t.param}>${q}`;
2583
2635
  case "tparam": return `${t.name}${q}`;
@@ -3864,13 +3916,15 @@ const CLASS_KINDS = {
3864
3916
  };
3865
3917
  function classView(k, internal, c) {
3866
3918
  const bounds = boundsOf(c.typeParameters);
3919
+ const upperBounds = upperBoundsOf(c.typeParameters, []);
3867
3920
  const view = membersView({
3868
3921
  kind: CLASS_KINDS[c.kind],
3869
3922
  ...c.data ? { data: true } : {},
3870
3923
  ...c.fun ? { fun: true } : {},
3871
3924
  ...c.modality === "sealed" ? { sealed: c.sealedSubclasses } : {},
3872
3925
  ...c.valueClass ? { value: c.valueClass } : {},
3873
- ...bounds ? { bounds } : {}
3926
+ ...bounds ? { bounds } : {},
3927
+ ...upperBounds ? { upperBounds } : {}
3874
3928
  }, [c]);
3875
3929
  for (const ctor of c.constructors) {
3876
3930
  if (ctor.jvm) view.members.set(ctor.jvm.name + ctor.jvm.descriptor, {
@@ -3902,7 +3956,8 @@ function membersView(facts, owners) {
3902
3956
  if (!f.jvm) continue;
3903
3957
  view.members.set(f.jvm.name + f.jvm.descriptor, {
3904
3958
  role: "function",
3905
- function: f
3959
+ function: f,
3960
+ outer: owner.typeParameters ?? []
3906
3961
  });
3907
3962
  if (f.parameters.some((p) => p.declaresDefault)) view.overloaded.add(f.jvm.name);
3908
3963
  }
@@ -3931,6 +3986,38 @@ function boundsOf(params) {
3931
3986
  }
3932
3987
  return Object.keys(bounds).length ? bounds : void 0;
3933
3988
  }
3989
+ function upperBoundsOf(params, outer) {
3990
+ const names = new Map([...outer, ...params].map((p) => [p.id, p.name]));
3991
+ const bounds = boundsOf(params) ?? {};
3992
+ const upper = {};
3993
+ for (const p of params) {
3994
+ if (bounds[p.name] !== "other") continue;
3995
+ const refs = p.upperBounds.map((b) => typeRef(b, names));
3996
+ if (refs.every((r) => r !== void 0)) upper[p.name] = refs;
3997
+ }
3998
+ return Object.keys(upper).length ? upper : void 0;
3999
+ }
4000
+ function typeRef(t, names) {
4001
+ const c = t.classifier;
4002
+ const name = "class" in c ? c.class.replaceAll("/", ".") : "typeAlias" in c ? c.typeAlias.replaceAll("/", ".") : names.get(c.typeParameter);
4003
+ if (!name) return void 0;
4004
+ const args = [];
4005
+ for (const a of t.arguments) {
4006
+ if (a === "*") {
4007
+ args.push("*");
4008
+ continue;
4009
+ }
4010
+ if (a.variance !== "invariant") return void 0;
4011
+ const ref = typeRef(a.type, names);
4012
+ if (!ref) return void 0;
4013
+ args.push(ref);
4014
+ }
4015
+ return {
4016
+ name,
4017
+ ...args.length ? { args } : {},
4018
+ ...t.nullable ? { nullable: true } : {}
4019
+ };
4020
+ }
3934
4021
  function kotlinSignature(member) {
3935
4022
  switch (member.role) {
3936
4023
  case "function": {
@@ -3940,6 +4027,7 @@ function kotlinSignature(member) {
3940
4027
  type: f.receiver
3941
4028
  }] : [];
3942
4029
  const bounds = boundsOf(f.typeParameters);
4030
+ const upperBounds = upperBoundsOf(f.typeParameters, member.outer);
3943
4031
  return {
3944
4032
  name: f.name,
3945
4033
  params: [
@@ -3955,7 +4043,8 @@ function kotlinSignature(member) {
3955
4043
  facts: {
3956
4044
  ...f.suspend ? { suspend: true } : {},
3957
4045
  ...f.receiver ? { extension: true } : {},
3958
- ...bounds ? { bounds } : {}
4046
+ ...bounds ? { bounds } : {},
4047
+ ...upperBounds ? { upperBounds } : {}
3959
4048
  }
3960
4049
  };
3961
4050
  }
@@ -4010,7 +4099,7 @@ function jvmSymbol(internal, member) {
4010
4099
  let extractorHash;
4011
4100
  function extractorVersion() {
4012
4101
  if (extractorHash) return extractorHash;
4013
- return extractorHash = "9bb0f2e9";
4102
+ return extractorHash = "ed6f33c6";
4014
4103
  }
4015
4104
  const contentHashes = /* @__PURE__ */ new Map();
4016
4105
  function contentHash(files) {
@@ -4057,7 +4146,7 @@ function jarArtifact(file) {
4057
4146
  }
4058
4147
  function iosProvenance(module, source, sdkVersion, target) {
4059
4148
  return {
4060
- artifact: source.pod ? `pod:${source.pod}` : source.kind === "sdk" ? `sdk:iphonesimulator${sdkVersion}` : `${source.kind}:${module}`,
4149
+ artifact: source.pod ? `pod:${source.pod}` : source.spm ? `spm:${source.spm}` : source.kind === "sdk" ? `sdk:iphonesimulator${sdkVersion}` : `${source.kind}:${module}`,
4061
4150
  kind: source.kind,
4062
4151
  ...source.files.length ? { contentHash: contentHash(source.files) } : {},
4063
4152
  target,
@@ -4459,11 +4548,27 @@ function extractAndroid(opts) {
4459
4548
  });
4460
4549
  throw new Unsupported$1("java.lang.Class");
4461
4550
  }
4462
- if (!known.has(t.name)) throw new Unsupported$1(t.name.replace(/\//g, "."));
4463
4551
  const typeArg = (a, i) => {
4464
4552
  const at = argument(i, t.args.length);
4465
4553
  return boxedAs(at, a) ?? typeOf(a, true, tparams, at);
4466
4554
  };
4555
+ if (kotlinFunction$1(t, kt)) {
4556
+ const last = t.args.length - 1;
4557
+ const result = argument(last, t.args.length);
4558
+ try {
4559
+ return nullable({
4560
+ k: "fn",
4561
+ params: t.args.slice(0, last).map(typeArg),
4562
+ ret: classOfKotlin(result) === "kotlin/Unit" ? parseSchemaType("void") : typeArg(t.args[last], last),
4563
+ escaping: true,
4564
+ main: false,
4565
+ nullable: false
4566
+ });
4567
+ } catch (e) {
4568
+ if (!(e instanceof Unsupported$1)) throw e;
4569
+ }
4570
+ }
4571
+ if (!known.has(t.name)) throw new Unsupported$1(t.name.replace(/\//g, "."));
4467
4572
  if (readOnlyList(t, kt)) try {
4468
4573
  return nullable({
4469
4574
  k: "array",
@@ -4693,6 +4798,9 @@ function extractAndroid(opts) {
4693
4798
  if (ks?.name && ks.name !== m.name) {
4694
4799
  method.name = ks.name;
4695
4800
  method.java = m.name;
4801
+ } else if (member && mangled(m.name)) {
4802
+ method.name = m.name.slice(0, m.name.indexOf("-"));
4803
+ method.java = m.name;
4696
4804
  }
4697
4805
  if (Object.keys(kotlinFacts).length) method.kotlin = kotlinFacts;
4698
4806
  if (m.access & ACC.STATIC) method.static = true;
@@ -4815,6 +4923,9 @@ function boxedAs(kt, t) {
4815
4923
  function readOnlyList(t, kt) {
4816
4924
  return t.name === "java/util/List" && t.args.length === 1 && !!kt && !kt.platform && classOfKotlin(kt) === "kotlin/collections/List" && typeArgument(kt, 0) !== void 0;
4817
4925
  }
4926
+ function kotlinFunction$1(t, kt) {
4927
+ return /^kotlin\/jvm\/functions\/Function\d+$/.test(t.name) && !!kt && !kt.platform && !kt.suspend && !kt.annotations?.length && classOfKotlin(kt) === `kotlin/${t.name.slice(t.name.lastIndexOf("/") + 1)}` && kt.arguments.length === t.args.length && kt.arguments.every((a) => a !== "*");
4928
+ }
4818
4929
  function typeArgument(kt, i) {
4819
4930
  const a = kt?.arguments[i];
4820
4931
  return a && a !== "*" ? a.type : void 0;
@@ -5276,18 +5387,32 @@ function parseType(frags, r) {
5276
5387
  }
5277
5388
  if (tok === "(") {
5278
5389
  const items = [];
5390
+ const labels = [];
5279
5391
  while (toks[p] !== ")") {
5392
+ const label = toks[p];
5393
+ if (typeof label === "string" && /^\w+$/.test(label) && toks[p + 1] === ":") {
5394
+ labels.push(label);
5395
+ p += 2;
5396
+ }
5280
5397
  items.push(type());
5281
5398
  if (toks[p] === ",") p++;
5282
5399
  else break;
5283
5400
  }
5284
5401
  if (toks[p++] !== ")") throw new Unsupported("closures and tuples");
5285
5402
  if (toks[p] === "->") {
5403
+ if (labels.length) throw new Unsupported("closures with labeled parameters");
5286
5404
  p++;
5287
5405
  return closure(items, attrs);
5288
5406
  }
5289
- if (items.length === 1 && !attrs.length) return items[0];
5290
- throw new Unsupported("tuples");
5407
+ if (items.length === 1 && !attrs.length && !labels.length) return items[0];
5408
+ if (!items.length && !attrs.length) return parseSchemaType("void");
5409
+ if (attrs.length) throw new Unsupported(`type syntax ${attrs.join(" ")}`);
5410
+ return {
5411
+ k: "tuple",
5412
+ of: items,
5413
+ ...labels.length === items.length ? { labels } : {},
5414
+ nullable: false
5415
+ };
5291
5416
  }
5292
5417
  if (tok === "->") throw new Unsupported("closures and tuples");
5293
5418
  if (attrs.length) throw new Unsupported(`type syntax ${attrs.join(" ")}`);
@@ -5621,6 +5746,7 @@ function undeclaredType(t, declared) {
5621
5746
  case "record":
5622
5747
  case "out": return undeclaredType(t.of, declared);
5623
5748
  case "fn": return [...t.params, t.ret].map((x) => undeclaredType(x, declared)).find(Boolean);
5749
+ case "tuple": return t.of.map((x) => undeclaredType(x, declared)).find(Boolean);
5624
5750
  default: return;
5625
5751
  }
5626
5752
  }
@@ -5666,8 +5792,8 @@ const NOT_JAVA = /* @__PURE__ */ new Set([
5666
5792
  "id",
5667
5793
  "record",
5668
5794
  "set",
5795
+ "tuple",
5669
5796
  "out",
5670
- "fn",
5671
5797
  "error"
5672
5798
  ]);
5673
5799
  const SWIFT_SCALARS = {
@@ -5932,26 +6058,19 @@ function needsKotlinShim(member) {
5932
6058
  return !!k?.suspend || !!k?.unboxed || "params" in member && member.params.some((p) => p.kotlin?.suspendFunction);
5933
6059
  }
5934
6060
  function bounded$1(owner, member) {
5935
- const other = (bounds) => !!bounds && Object.values(bounds).includes("other");
5936
- return other(owner?.kotlin?.bounds) || other(member.kotlin?.bounds);
6061
+ const unwritable = (facts) => Object.entries(facts?.bounds ?? {}).some(([name, bound]) => bound === "other" && !facts?.upperBounds?.[name]);
6062
+ return unwritable(owner?.kotlin) || unwritable(member.kotlin);
5937
6063
  }
5938
6064
  function omitsKotlinDefault(owner, member, param) {
5939
6065
  return !!param.kotlin?.default && !bounded$1(owner, member);
5940
6066
  }
5941
- const KOTLIN_SHIM_REFUSALS = [
5942
- [(owner, member) => bounded$1(owner, member), {
5943
- rule: "kotlin-shim-generic",
5944
- reason: "generic Kotlin members whose type parameters have bounds are not supported through a shim yet"
5945
- }],
5946
- [(_, __, role) => role === "set", {
5947
- rule: "kotlin-shim",
5948
- reason: "assigning Kotlin value classes is not supported yet"
5949
- }],
5950
- [(_, __, role) => role === "implement", {
5951
- rule: "kotlin-shim",
5952
- reason: "Lucent classes cannot implement suspend functions or value-class members yet"
5953
- }]
5954
- ];
6067
+ const KOTLIN_SHIM_REFUSALS = [[(owner, member) => bounded$1(owner, member), {
6068
+ rule: "kotlin-shim-generic",
6069
+ reason: "generic Kotlin members bounded by a projected type (`T : List<out R>`) are not supported through a shim yet"
6070
+ }], [(owner, _, role) => role === "implement" && !owner?.interface, {
6071
+ rule: "kotlin-shim",
6072
+ reason: "Lucent classes cannot override a Kotlin class's suspend or value-class members yet"
6073
+ }]];
5955
6074
  const UI_APPLIER$1 = "androidx.compose.ui.UiComposable";
5956
6075
  const simpleName = (kotlinName) => kotlinName.slice(kotlinName.lastIndexOf("/") + 1);
5957
6076
  const KOTLIN_SOURCE_REFUSALS = [
@@ -6011,9 +6130,9 @@ function refusalOf(owner, member, backend, role) {
6011
6130
  };
6012
6131
  }
6013
6132
  const jvmName = "java" in member ? member.java : void 0;
6014
- if (backend === "jni" && role === "implement" && jvmName && !javaIdentifier(jvmName)) return {
6133
+ if (backend === "jni" && role === "implement" && !owner?.interface && jvmName && !javaIdentifier(jvmName)) return {
6015
6134
  rule: "jvm-mangled-name",
6016
- reason: `a method whose JVM name Java cannot write (${jvmName}) cannot be implemented`
6135
+ reason: `a method whose JVM name Java cannot write (${jvmName}) cannot be overridden`
6017
6136
  };
6018
6137
  if (backend !== "swift-shim") return void 0;
6019
6138
  if (role === "new" && member.swift?.async) return {
@@ -6051,9 +6170,12 @@ function requirementDelivery(backend, owner, m) {
6051
6170
  return !isVoid || owner?.mainActor || m.mainActor ? "sync" : "queued";
6052
6171
  }
6053
6172
  function resultOwnership(owner, member, module, role, facts) {
6054
- if (module.platform !== "ios" || member.swift || role !== "call" || !("returns" in member)) return facts;
6173
+ const cFunction = "cFunction" in member ? member.cFunction?.name : void 0;
6174
+ const made = role === "new" && !!cFunction;
6175
+ if (module.platform !== "ios" || member.swift) return facts;
6176
+ if (!made && (role !== "call" || !("returns" in member))) return facts;
6055
6177
  if (facts.ownership !== "unknown") return facts;
6056
- const rule = owner ? /^(alloc|new|copy|mutableCopy|create)(?![a-z])/.test(member.selector ?? member.name) ? "objc-method-family" : void 0 : /Create|Copy/.test(member.name) ? "cf-create-rule" : void 0;
6178
+ const rule = cFunction ? /Create|Copy/.test(cFunction) ? "cf-create-rule" : void 0 : owner ? /^(alloc|new|copy|mutableCopy|create)(?![a-z])/.test(member.selector ?? ("name" in member ? member.name : "")) ? "objc-method-family" : void 0 : /Create|Copy/.test("name" in member ? member.name : "") ? "cf-create-rule" : void 0;
6057
6179
  if (!rule) return facts;
6058
6180
  const evidence = {
6059
6181
  fact: "ownership",
@@ -6141,6 +6263,11 @@ function kindConversion(t, place, ctx) {
6141
6263
  type: t,
6142
6264
  of: [inner(t.of, { element: true })]
6143
6265
  };
6266
+ case "tuple": return {
6267
+ op: "copy-tuple",
6268
+ type: t,
6269
+ of: t.of.map((x) => inner(x, { element: true }))
6270
+ };
6144
6271
  case "record": return withDetail({
6145
6272
  op: "copy-record",
6146
6273
  type: t,
@@ -6255,9 +6382,15 @@ function kotlinSourceRule(t, place) {
6255
6382
  }
6256
6383
  function jniRule(t, place, ctx) {
6257
6384
  if (t.k === "array" && !t.list && t.of.k === "tparam" && place.flow === "in") return "arrays of a type parameter's values cannot be passed to Java yet";
6385
+ if (ctx.backend === "jni" && t.k === "fn" && [...t.params, t.ret].some((x) => x.k === "fn")) return "Kotlin functions taking or giving functions are not supported yet";
6258
6386
  if (ctx.role !== "implement") return void 0;
6259
6387
  if (place.offered && t.k === "prim" && t.name === "char") return "a char argument is not supported yet";
6260
- if (place.result && t.k !== "prim" && t.k !== "string" && t.k !== "tparam") return `Lucent functions cannot return a ${formatSchemaType({
6388
+ if (place.result && ![
6389
+ "prim",
6390
+ "string",
6391
+ "tparam",
6392
+ "ref"
6393
+ ].includes(t.k)) return `Lucent functions cannot return a ${formatSchemaType({
6261
6394
  ...t,
6262
6395
  nullable: false
6263
6396
  })} to Java yet`;
@@ -6299,6 +6432,21 @@ function swiftRule(t, place, ctx) {
6299
6432
  case "date":
6300
6433
  case "id":
6301
6434
  case "tparam": return;
6435
+ case "fn": {
6436
+ const blockable = (x, result) => {
6437
+ if (x.k === "prim") return result && x.name === "void" || !!SWIFT_SCALARS[x.name] && !x.nullable;
6438
+ if (x.k === "string") return true;
6439
+ if (x.k !== "ref") return false;
6440
+ const facts = ctx.types(x.module, x.name);
6441
+ return (facts?.kind === "class" || facts?.kind === "protocol") && !facts.swift;
6442
+ };
6443
+ if (![...t.params.map((x) => blockable(x, false)), blockable(t.ret, true)].every(Boolean)) return not("closures taking or giving values other than numbers, booleans, strings and Objective-C objects");
6444
+ return t.nullable ? not("optional closures") : void 0;
6445
+ }
6446
+ case "tuple":
6447
+ if (t.of.some((x) => x.nullable)) return not("tuples of optional values");
6448
+ if (t.of.some((x) => isStruct(x, ctx))) return not("tuples of C structs");
6449
+ return t.nullable ? not("optional tuples") : void 0;
6302
6450
  case "array":
6303
6451
  case "record":
6304
6452
  if (t.of.nullable) return not("collections of optional values");
@@ -6351,6 +6499,51 @@ function hasUnion$1(t, ctx) {
6351
6499
  return swift !== void 0 && swift !== true && !!swift.cases;
6352
6500
  }
6353
6501
  //#endregion
6502
+ //#region ../bindgen/src/c-swift-names.ts
6503
+ function cSwiftNames(dirs) {
6504
+ const out = /* @__PURE__ */ new Map();
6505
+ for (const dir of dirs) {
6506
+ const files = fs.existsSync(dir) ? fs.readdirSync(dir) : [];
6507
+ for (const f of files.filter((x) => x.endsWith(".h"))) for (const [name, swift] of attributeNames(fs.readFileSync(path.join(dir, f), "utf8"))) out.set(name, swift);
6508
+ for (const f of files.filter((x) => x.endsWith(".apinotes"))) for (const [name, swift] of apiNoteNames(fs.readFileSync(path.join(dir, f), "utf8"))) out.set(name, swift);
6509
+ }
6510
+ return out;
6511
+ }
6512
+ function apiNoteNames(text) {
6513
+ const out = [];
6514
+ const items = text.split(/^\s*- (?=Name:)/m).slice(1);
6515
+ for (const item of items) {
6516
+ const name = /^Name:\s*(\w+)/.exec(item)?.[1];
6517
+ const own = item.split(/\n(?=\S|\s*- )/)[0];
6518
+ const swift = /^\s*SwiftName:\s*'?([^'\n]+?)'?\s*$/m.exec(own)?.[1];
6519
+ if (name && swift) out.push([name, swift]);
6520
+ }
6521
+ return out;
6522
+ }
6523
+ function attributeNames(text) {
6524
+ const out = [];
6525
+ for (const m of text.matchAll(/\b(?:CF|NS|CG)_SWIFT_NAME\(([^()]*\([^()]*\))\)|swift_name\("([^"]+)"\)/g)) {
6526
+ const swift = m[1] ?? m[2];
6527
+ const before = text.slice(0, m.index);
6528
+ const start = Math.max(before.lastIndexOf(";"), before.lastIndexOf("}")) + 1;
6529
+ const name = /\b(\w+)\s*\(/.exec(before.slice(start))?.[1];
6530
+ if (name) out.push([name, swift]);
6531
+ }
6532
+ return out;
6533
+ }
6534
+ function swiftMemberOf(swift) {
6535
+ const m = /^(?:(getter|setter):)?([\w.]+)\.(\w+)\(([^)]*)\)$/.exec(swift);
6536
+ if (!m) return void 0;
6537
+ const [, accessor, type, name, args] = m;
6538
+ const self = args.split(":").filter((l) => l !== "").indexOf("self");
6539
+ return {
6540
+ kind: accessor === "getter" || accessor === "setter" ? accessor : name === "init" ? "init" : "method",
6541
+ type,
6542
+ name,
6543
+ ...self >= 0 ? { self } : {}
6544
+ };
6545
+ }
6546
+ //#endregion
6354
6547
  //#region ../bindgen/src/swift.ts
6355
6548
  const TYPE_KINDS$1 = {
6356
6549
  "swift.struct": "struct",
@@ -6562,7 +6755,9 @@ function addSwiftDeclarations(ctx) {
6562
6755
  bytes: true
6563
6756
  }
6564
6757
  });
6565
- if (bound.ctors.length) cls.constructors = bound.ctors;
6758
+ const apart = factoriesOfSameTyped(bound.ctors, `${module}.${cls.name}`);
6759
+ bound.methods.push(...apart.factories);
6760
+ if (apart.ctors.length) cls.constructors = apart.ctors;
6566
6761
  if (bound.methods.length) cls.methods = bound.methods;
6567
6762
  if (bound.props.length) cls.properties = bound.props;
6568
6763
  mod.types.push(cls);
@@ -6580,7 +6775,11 @@ function addSwiftDeclarations(ctx) {
6580
6775
  const methods = withoutPropertyNames(bound.methods, cls.properties ?? [], bound.symbols, skip);
6581
6776
  for (const m of methods) if (!has(cls.methods, m.name)) (cls.methods ??= []).push(m);
6582
6777
  for (const p of bound.props) if (!has(cls.properties, p.name)) (cls.properties ??= []).push(p);
6583
- if (bound.ctors.length && !cls.constructors?.length) cls.constructors = bound.ctors;
6778
+ if (bound.ctors.length && !cls.constructors?.length) {
6779
+ const apart = factoriesOfSameTyped(bound.ctors, `${module}.${cls.name}`);
6780
+ for (const f of apart.factories) if (!has(cls.methods, f.name)) (cls.methods ??= []).push(f);
6781
+ if (apart.ctors.length) cls.constructors = apart.ctors;
6782
+ }
6584
6783
  }
6585
6784
  for (const s of g.symbols) {
6586
6785
  const usr = s.identifier.precise;
@@ -6862,6 +7061,44 @@ function payload(c, r) {
6862
7061
  } : { type };
6863
7062
  });
6864
7063
  }
7064
+ function factoriesOfSameTyped(ctors, self) {
7065
+ const key = (c) => c.params.map((p) => typeKind(formatSchemaType({
7066
+ ...p.type,
7067
+ nullable: false
7068
+ }))).join(",");
7069
+ const groups = /* @__PURE__ */ new Map();
7070
+ for (const c of ctors) groups.set(key(c), [...groups.get(key(c)) ?? [], c]);
7071
+ const capitalized = (w) => w.charAt(0).toUpperCase() + w.slice(1);
7072
+ const byLabels = (c) => `with${splitName(c.swift?.name ?? "init()").labels.filter((l) => l !== "_").map(capitalized).join("")}`;
7073
+ const unlabeled = (c) => splitName(c.swift?.name ?? "init()").labels.every((l) => l === "_");
7074
+ const byTypes = (c) => `with${c.params.map((p) => capitalized(formatSchemaType(p.type).replace(/\W/g, ""))).join("")}`;
7075
+ const factories = [];
7076
+ const turned = /* @__PURE__ */ new Set();
7077
+ for (const all of groups.values()) {
7078
+ if (all.length < 2) continue;
7079
+ const bare = all.filter((c) => !c.params.length || unlabeled(c));
7080
+ const group = bare.length === 1 ? all.filter((c) => c !== bare[0]) : all;
7081
+ const labelled = group.map(byLabels);
7082
+ const names = new Set(labelled).size === group.length ? labelled : group.map(byTypes);
7083
+ if (new Set(names).size !== group.length) continue;
7084
+ group.forEach((c, i) => {
7085
+ factories.push({
7086
+ ...c,
7087
+ name: names[i],
7088
+ static: true,
7089
+ returns: parseSchemaType(self)
7090
+ });
7091
+ turned.add(c);
7092
+ });
7093
+ }
7094
+ return {
7095
+ ctors: ctors.filter((c) => !turned.has(c)),
7096
+ factories
7097
+ };
7098
+ }
7099
+ function typeKind(t) {
7100
+ return /^(double|float|CGFloat|NSInteger|NSUInteger|u?int(8|16|32|64)?|short|byte)$/.test(t) ? "number" : t;
7101
+ }
6865
7102
  //#endregion
6866
7103
  //#region ../bindgen/src/ios.ts
6867
7104
  const DEFAULT_TARGET = "arm64-apple-ios15.1-simulator";
@@ -7142,6 +7379,26 @@ function externalUsrs(g) {
7142
7379
  for (const r of g.relationships) if (r.target.startsWith("c:") && !declared.has(r.target)) out.add(r.target);
7143
7380
  return out;
7144
7381
  }
7382
+ function withInheritedInitializers(mod) {
7383
+ const classes = new Map(mod.types.filter((t) => t.kind === "class").map((c) => [c.name, c]));
7384
+ for (const cls of classes.values()) {
7385
+ if (!cls.inheritsInit || !cls.constructors?.length) continue;
7386
+ let inherited;
7387
+ for (let at = cls.extends, depth = 0; at && depth < 64 && !inherited; depth++) {
7388
+ const [owner, ...rest] = at.split(".");
7389
+ const sup = owner === mod.module ? classes.get(rest.join(".")) : void 0;
7390
+ if (!sup) break;
7391
+ const own = (sup.constructors ?? []).filter((c) => !c.factory);
7392
+ if (own.length) inherited = own;
7393
+ else if (!sup.inheritsInit) break;
7394
+ at = sup.extends;
7395
+ }
7396
+ if (inherited) {
7397
+ cls.constructors.push(...inherited.map((c) => ({ ...c })));
7398
+ delete cls.inheritsInit;
7399
+ }
7400
+ }
7401
+ }
7145
7402
  function keepInheritedNonNull(mod, unaudited) {
7146
7403
  const classes = new Map(mod.types.filter((t) => t.kind === "class").map((c) => [c.name, c]));
7147
7404
  const inheritedNonNull = (cls, p) => {
@@ -7293,7 +7550,7 @@ function inheritedConformances(classUsr, lineage) {
7293
7550
  }
7294
7551
  return out;
7295
7552
  }
7296
- function buildIosSchema(module, g, names, values) {
7553
+ function buildIosSchema(module, g, names, values, importedNames = /* @__PURE__ */ new Map()) {
7297
7554
  const refs = new Map(names.flatMap((n) => Object.entries(n.refs)));
7298
7555
  const aliases = new Map(names.flatMap((n) => Object.entries(n.aliases)));
7299
7556
  const unaudited = /* @__PURE__ */ new Set();
@@ -7401,15 +7658,90 @@ function buildIosSchema(module, g, names, values) {
7401
7658
  properties: props
7402
7659
  });
7403
7660
  }
7661
+ const cfMembers = (cls, list, setters) => {
7662
+ const r = resolver();
7663
+ for (const mem of list) {
7664
+ const fn = /^c:@F@(\w+)$/.exec(mem.identifier.precise)?.[1];
7665
+ if (!fn || unavailable(mem)) continue;
7666
+ const imported = importedNames.get(fn);
7667
+ const member = imported ? swiftMemberOf(imported) : void 0;
7668
+ const symbol = graphSymbol(mem.identifier.precise);
7669
+ const v = since(mem);
7670
+ try {
7671
+ if (!member) throw new Unsupported(`${fn}'s Swift name is in no API notes or header Lucent reads`);
7672
+ const k = mem.kind.identifier;
7673
+ if (k === "swift.property" || k === "swift.type.property") {
7674
+ if (member.kind !== "getter") continue;
7675
+ const setter = setters.get(`${member.type}.${member.name}`);
7676
+ const p = {
7677
+ name: mem.names.title,
7678
+ type: parseType(propertyType(mem.declarationFragments ?? []), r),
7679
+ cFunctions: {
7680
+ getter: fn,
7681
+ ...setter ? { setter } : {}
7682
+ },
7683
+ symbol
7684
+ };
7685
+ if (!setter) p.readonly = true;
7686
+ if (member.self === void 0) p.static = true;
7687
+ if (v && v !== cls.since) p.since = v;
7688
+ (cls.properties ??= []).push(p);
7689
+ continue;
7690
+ }
7691
+ const sig = mem.functionSignature;
7692
+ const params = (sig?.parameters ?? []).map((pp) => ({
7693
+ name: pp.internalName ?? pp.name,
7694
+ type: parseType(afterColon(pp.declarationFragments), r)
7695
+ }));
7696
+ if (k === "swift.init") {
7697
+ if (/\binit\?/.test(declText(mem))) throw new Unsupported("a failable initializer");
7698
+ const c = {
7699
+ params,
7700
+ cFunction: { name: fn },
7701
+ symbol
7702
+ };
7703
+ if (v && v !== cls.since) c.since = v;
7704
+ (cls.constructors ??= []).push(c);
7705
+ continue;
7706
+ }
7707
+ if (k !== "swift.method" && k !== "swift.type.method") continue;
7708
+ const m = {
7709
+ name: splitName(mem.names.title).base,
7710
+ params,
7711
+ returns: sig?.returns?.length ? parseType(sig.returns, r) : parseSchemaType("void"),
7712
+ cFunction: {
7713
+ name: fn,
7714
+ ...member.self !== void 0 ? { self: member.self } : {}
7715
+ },
7716
+ symbol
7717
+ };
7718
+ if (member.self === void 0) m.static = true;
7719
+ if (v && v !== cls.since) m.since = v;
7720
+ (cls.methods ??= []).push(m);
7721
+ } catch (e) {
7722
+ if (e instanceof Unsupported) skip(cls.name, mem, e.message);
7723
+ else throw e;
7724
+ }
7725
+ }
7726
+ if (cls.methods) disambiguate(cls.methods);
7727
+ };
7728
+ const setters = /* @__PURE__ */ new Map();
7729
+ for (const [fn, imported] of importedNames) {
7730
+ const member = swiftMemberOf(imported);
7731
+ if (member?.kind === "setter") setters.set(`${member.type}.${member.name}`, fn);
7732
+ }
7404
7733
  for (const s of g.symbols) {
7405
7734
  const handle = s.kind.identifier === "swift.class" ? typedefName(s.identifier.precise) : void 0;
7406
- if (handle && !unavailable(s)) mod.types.push({
7735
+ if (!handle || unavailable(s)) continue;
7736
+ const cls = {
7407
7737
  kind: "class",
7408
7738
  name: s.pathComponents.join("_"),
7409
7739
  native: handle,
7410
7740
  cf: true,
7411
7741
  symbol: graphSymbol(s.identifier.precise)
7412
- });
7742
+ };
7743
+ cfMembers(cls, members.get(s.identifier.precise) ?? [], setters);
7744
+ mod.types.push(cls);
7413
7745
  }
7414
7746
  const objcClasses = /* @__PURE__ */ new Map();
7415
7747
  for (const s of g.symbols) {
@@ -7492,10 +7824,10 @@ function buildIosSchema(module, g, names, values) {
7492
7824
  type: withEscaping(parseType(afterColon(pp.declarationFragments), r), escaping[i])
7493
7825
  }));
7494
7826
  if (mem.kind.identifier === "swift.init") {
7495
- if (kind === "cm") continue;
7496
7827
  const c = {
7497
7828
  params,
7498
7829
  selector,
7830
+ ...kind === "cm" ? { factory: true } : {},
7499
7831
  symbol
7500
7832
  };
7501
7833
  if (facts) c.facts = facts;
@@ -7520,7 +7852,9 @@ function buildIosSchema(module, g, names, values) {
7520
7852
  const twin = asyncTwins.get(mem.identifier.precise);
7521
7853
  if (twin) try {
7522
7854
  const tr = twin.functionSignature?.returns;
7523
- method.async = { returns: tr?.length ? parseType(tr, r) : parseSchemaType("void") };
7855
+ const settled = tr?.length ? parseType(tr, r) : parseSchemaType("void");
7856
+ if (settled.k === "tuple") throw new Unsupported("tuples");
7857
+ method.async = { returns: settled };
7524
7858
  if (/\bthrows\b/.test(declText(twin))) method.async.throws = true;
7525
7859
  const asyncName = splitName(twin.names.title).base;
7526
7860
  if (asyncName !== base) method.async.name = asyncName;
@@ -7551,7 +7885,7 @@ function buildIosSchema(module, g, names, values) {
7551
7885
  if (swiftName) swiftNames.set(x, swiftName);
7552
7886
  delete x.swiftName;
7553
7887
  }
7554
- if (!ctors.length && !initUnavailable && k === "swift.class") {
7888
+ if (!ctors.some((c) => !c.factory) && !initUnavailable && k === "swift.class") {
7555
7889
  if (cls.extends) cls.inheritsInit = true;
7556
7890
  else ctors.push({
7557
7891
  params: [],
@@ -7621,6 +7955,7 @@ function buildIosSchema(module, g, names, values) {
7621
7955
  return !!t && (t.typeParams ?? 0) === arity;
7622
7956
  });
7623
7957
  keepInheritedNonNull(mod, unaudited);
7958
+ withInheritedInitializers(mod);
7624
7959
  resolveMemberKinds(mod, names);
7625
7960
  return mod;
7626
7961
  }
@@ -7863,7 +8198,7 @@ function iosArtifacts(memo, inputs) {
7863
8198
  }];
7864
8199
  const groups = /* @__PURE__ */ new Map();
7865
8200
  for (const [module, source] of sources) {
7866
- const id = source.pod ? `pod:${source.pod}` : `${source.kind}:${module}`;
8201
+ const id = source.pod ? `pod:${source.pod}` : source.spm ? `spm:${source.spm}` : `${source.kind}:${module}`;
7867
8202
  const group = groups.get(id) ?? {
7868
8203
  source,
7869
8204
  modules: []
@@ -7887,6 +8222,10 @@ function iosArtifacts(memo, inputs) {
7887
8222
  package: name,
7888
8223
  version: pod.version,
7889
8224
  buildFile: inputs.lockfile
8225
+ } : source.spm ? {
8226
+ package: source.spm.slice(0, source.spm.lastIndexOf("@")),
8227
+ version: source.spm.slice(source.spm.lastIndexOf("@") + 1),
8228
+ buildFile: inputs.resolved ?? files[0] ?? ""
7890
8229
  } : {
7891
8230
  package: modules[0],
7892
8231
  version: "",
@@ -8413,12 +8752,10 @@ function extractionCount() {
8413
8752
  return extractions;
8414
8753
  }
8415
8754
  const loaded$1 = /* @__PURE__ */ new Map();
8416
- const located$3 = /* @__PURE__ */ new Map();
8417
8755
  const iosSdks = /* @__PURE__ */ new Map();
8418
8756
  const headerIndexes = /* @__PURE__ */ new Map();
8419
8757
  function forgetLoadedSdks() {
8420
8758
  loaded$1.clear();
8421
- located$3.clear();
8422
8759
  iosSdks.clear();
8423
8760
  headerIndexes.clear();
8424
8761
  locatedByObject = /* @__PURE__ */ new WeakMap();
@@ -8601,7 +8938,11 @@ function locateIos(opts) {
8601
8938
  const includePaths = opts.ios?.includePaths ?? [];
8602
8939
  const root = cacheRoot(opts.cacheDir);
8603
8940
  const memo = memoDir(root);
8604
- const frameworkPaths = [...opts.ios?.frameworkPaths ?? [], ...(opts.ios?.frameworks ?? []).map((f) => podFramework(memo, f))];
8941
+ const frameworkPaths = [
8942
+ ...opts.ios?.frameworkPaths ?? [],
8943
+ ...(opts.ios?.frameworks ?? []).map((f) => podFramework(memo, f)),
8944
+ ...new Set((opts.ios?.swiftPackages?.modules ?? []).filter((m) => m.framework).map((m) => m.dir))
8945
+ ];
8605
8946
  const moduleMaps = opts.ios?.moduleMaps ?? [];
8606
8947
  const defines = opts.ios?.defines ?? [];
8607
8948
  const frameworks = path.join(sdk, "System/Library/Frameworks");
@@ -8638,6 +8979,17 @@ function locateIos(opts) {
8638
8979
  }
8639
8980
  }
8640
8981
  for (const map of moduleMaps) readMap(map);
8982
+ const packages = opts.ios?.swiftPackages;
8983
+ for (const m of packages?.modules ?? []) {
8984
+ if (m.framework) continue;
8985
+ modules.set(m.module, []);
8986
+ sources.set(m.module, {
8987
+ kind: "swift-module",
8988
+ files: [path.join(m.dir, `${m.module}.swiftmodule`)],
8989
+ spm: m.package
8990
+ });
8991
+ }
8992
+ const packageDirs = [...new Set((packages?.modules ?? []).filter((m) => !m.framework).map((m) => m.dir))];
8641
8993
  for (const dir of frameworkPaths) for (const f of fs.existsSync(dir) ? fs.readdirSync(dir) : []) {
8642
8994
  if (!f.endsWith(".framework")) continue;
8643
8995
  const name = f.slice(0, -10);
@@ -8649,6 +9001,10 @@ function locateIos(opts) {
8649
9001
  });
8650
9002
  frameworkDirs.set(name, dir);
8651
9003
  }
9004
+ for (const m of packages?.modules ?? []) {
9005
+ const source = m.framework ? sources.get(m.module) : void 0;
9006
+ if (source) source.spm = m.package;
9007
+ }
8652
9008
  for (const f of opts.ios?.frameworks ?? []) sources.set(f.module, {
8653
9009
  kind: "framework",
8654
9010
  files: [
@@ -8666,13 +9022,15 @@ function locateIos(opts) {
8666
9022
  if (pod) source.pod = `${pod}@${pods.get(pod).version}`;
8667
9023
  }
8668
9024
  }
9025
+ const deployment = opts.ios?.deploymentTarget;
8669
9026
  const ios = {
8670
9027
  modules: [],
8671
- includePaths,
9028
+ includePaths: [...includePaths, ...packageDirs],
8672
9029
  frameworkPaths,
8673
9030
  moduleMaps,
8674
9031
  defines,
8675
- xcrun
9032
+ xcrun,
9033
+ ...deployment ? { target: `arm64-apple-ios${deployment}-simulator` } : {}
8676
9034
  };
8677
9035
  const targetTriple = iosTarget(ios);
8678
9036
  const artifacts = iosArtifacts(memo, {
@@ -8685,7 +9043,8 @@ function locateIos(opts) {
8685
9043
  sources,
8686
9044
  lockfile,
8687
9045
  pods,
8688
- includePaths,
9046
+ ...packages?.resolved ? { resolved: packages.resolved } : {},
9047
+ includePaths: ios.includePaths ?? [],
8689
9048
  compilerArguments: defines.map((d) => `-D${d}`),
8690
9049
  targetTriple
8691
9050
  });
@@ -8707,7 +9066,8 @@ function locateIos(opts) {
8707
9066
  modules,
8708
9067
  umbrellas,
8709
9068
  frameworkDirs,
8710
- sources
9069
+ sources,
9070
+ packageFailures: packages?.failures ?? []
8711
9071
  }
8712
9072
  }, (a) => a.modules.filter((m) => byModule.get(m) === a));
8713
9073
  }
@@ -8821,7 +9181,9 @@ function iosNotFound(r, module) {
8821
9181
  ios.frameworkPaths?.length ? `${ios.frameworkPaths.length} framework path${ios.frameworkPaths.length === 1 ? "" : "s"}` : ""
8822
9182
  ].filter(Boolean);
8823
9183
  const pods = extra.length ? ` and the app's pods (${extra.join(", ")}); run pod install after adding a pod` : "; no pods were read: when it comes from a pod, run pod install first";
8824
- return { missing: `lucent:ios/${module} was not found in the SDK or the app's dependencies (${`looked in ${r.ios.frameworks}${pods}`})` };
9184
+ const where = `looked in ${r.ios.frameworks}${pods}`;
9185
+ const failed = r.ios.packageFailures;
9186
+ return { missing: `lucent:ios/${module} was not found in the SDK or the app's dependencies (${where})${failed.length ? `; the app's Swift packages could not all be built: ${failed.join("; ")}` : ""}` };
8825
9187
  }
8826
9188
  function extractIosModule(r, module) {
8827
9189
  const { modules, sdk: sdkPath, ios } = r.ios;
@@ -8838,7 +9200,7 @@ function extractIosModule(r, module) {
8838
9200
  referenced.delete(module);
8839
9201
  const names = [own, ...namesFor(r, [...referenced].filter((m) => modules.has(m)))];
8840
9202
  const headers = modules.get(module) ?? [`${module}/${module}.h`];
8841
- const schema = buildIosSchema(module, g, names, (enums) => enumValues(enums, headers, ios, sdkPath));
9203
+ const schema = buildIosSchema(module, g, names, (enums) => enumValues(enums, headers, ios, sdkPath), cSwiftNames(modules.get(module) ? [...new Set(headers.map((h) => path.dirname(h)))] : [path.join(r.ios.frameworkDirs.get(module) ?? r.ios.frameworks, `${module}.framework/Headers`)]));
8842
9204
  const umbrella = r.ios.umbrellas.get(module);
8843
9205
  const framework = r.ios.frameworkDirs.get(module) ?? (modules.get(module) ? void 0 : r.ios.frameworks);
8844
9206
  const inFramework = framework && frameworkUmbrella(framework, module);
@@ -8929,19 +9291,10 @@ let locatedByObject = /* @__PURE__ */ new WeakMap();
8929
9291
  function locate$1(platform, opts) {
8930
9292
  const byObject = locatedByObject.get(opts)?.get(platform);
8931
9293
  if (byObject) return byObject;
8932
- const found = locateByValue(platform, opts);
9294
+ const found = platform === "android" ? locateAndroid(opts) : locateIos(opts);
8933
9295
  locatedByObject.set(opts, (locatedByObject.get(opts) ?? /* @__PURE__ */ new Map()).set(platform, found));
8934
9296
  return found;
8935
9297
  }
8936
- function locateByValue(platform, opts) {
8937
- const k = `${platform}|${JSON.stringify(opts)}`;
8938
- let l = located$3.get(k);
8939
- if (!l) {
8940
- l = platform === "android" ? locateAndroid(opts) : locateIos(opts);
8941
- located$3.set(k, l);
8942
- }
8943
- return l;
8944
- }
8945
9298
  function load$1(platform, r, module) {
8946
9299
  if (!r.providers.has(module)) return { lookup: platform === "android" ? androidNotFound(r, module) : iosNotFound(r, module) };
8947
9300
  const dir = path.join(r.scope, module);
@@ -9807,6 +10160,97 @@ function formatCType(t) {
9807
10160
  }
9808
10161
  }
9809
10162
  //#endregion
10163
+ //#region ../compiler/src/package-versions.ts
10164
+ function compare$1(a, b) {
10165
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
10166
+ const d = (a[i] ?? 0) - (b[i] ?? 0);
10167
+ if (d) return d;
10168
+ }
10169
+ return 0;
10170
+ }
10171
+ function pessimisticUpper(v) {
10172
+ const head = v.length > 1 ? v.slice(0, -1) : [...v];
10173
+ head[head.length - 1] += 1;
10174
+ return head;
10175
+ }
10176
+ const POD_OPERATORS = {
10177
+ "=": (v) => ({
10178
+ lo: {
10179
+ v,
10180
+ inclusive: true
10181
+ },
10182
+ hi: {
10183
+ v,
10184
+ inclusive: true
10185
+ }
10186
+ }),
10187
+ ">=": (v) => ({ lo: {
10188
+ v,
10189
+ inclusive: true
10190
+ } }),
10191
+ ">": (v) => ({ lo: {
10192
+ v,
10193
+ inclusive: false
10194
+ } }),
10195
+ "<=": (v) => ({ hi: {
10196
+ v,
10197
+ inclusive: true
10198
+ } }),
10199
+ "<": (v) => ({ hi: {
10200
+ v,
10201
+ inclusive: false
10202
+ } }),
10203
+ "~>": (v) => ({
10204
+ lo: {
10205
+ v,
10206
+ inclusive: true
10207
+ },
10208
+ hi: {
10209
+ v: pessimisticUpper(v),
10210
+ inclusive: false
10211
+ }
10212
+ })
10213
+ };
10214
+ function intersect(a, b) {
10215
+ const pick = (x, y, sign) => {
10216
+ if (!x) return y;
10217
+ if (!y) return x;
10218
+ const d = compare$1(x.v, y.v) * sign;
10219
+ if (d !== 0) return d > 0 ? x : y;
10220
+ return {
10221
+ v: x.v,
10222
+ inclusive: x.inclusive && y.inclusive
10223
+ };
10224
+ };
10225
+ return {
10226
+ lo: pick(a.lo, b.lo, 1),
10227
+ hi: pick(a.hi, b.hi, -1)
10228
+ };
10229
+ }
10230
+ function isEmpty(r) {
10231
+ if (!r.lo || !r.hi) return false;
10232
+ const d = compare$1(r.lo.v, r.hi.v);
10233
+ return d > 0 || d === 0 && !(r.lo.inclusive && r.hi.inclusive);
10234
+ }
10235
+ function podRange(requirement) {
10236
+ let range = {};
10237
+ for (const part of requirement.split(",")) {
10238
+ const m = /^\s*(~>|>=|<=|>|<|=)?\s*(\d+(?:\.\d+)*)\s*$/.exec(part);
10239
+ if (!m) return void 0;
10240
+ range = intersect(range, POD_OPERATORS[m[1] ?? "="](m[2].split(".").map(Number)));
10241
+ }
10242
+ return range;
10243
+ }
10244
+ function podsCompatible(a, b) {
10245
+ const ra = podRange(a);
10246
+ const rb = podRange(b);
10247
+ return !ra || !rb || !isEmpty(intersect(ra, rb));
10248
+ }
10249
+ function compareVersions(a, b) {
10250
+ return compare$1(a.split(".").map(Number), b.split(".").map(Number));
10251
+ }
10252
+ const gradleCompatible = (a, b) => !a.endsWith("!!") && !b.endsWith("!!");
10253
+ //#endregion
9810
10254
  //#region ../compiler/src/sdk/schema.ts
9811
10255
  const MIN_IOS = "15.1";
9812
10256
  const JNI_PRIM$1 = {
@@ -9826,9 +10270,13 @@ function parseSdkType(s, module = "", typeParams = []) {
9826
10270
  }
9827
10271
  let sdkOptions = {};
9828
10272
  let deferredPlatforms = [];
10273
+ function oldestIos() {
10274
+ const target = sdkOptions.ios?.deploymentTarget;
10275
+ return target && compareVersions(target, "15.1") > 0 ? target : MIN_IOS;
10276
+ }
9829
10277
  function withSdkOptions(opts, f, deferred = []) {
9830
10278
  const saved = [sdkOptions, deferredPlatforms];
9831
- sdkOptions = opts ?? {};
10279
+ sdkOptions = { ...opts };
9832
10280
  deferredPlatforms = deferred;
9833
10281
  try {
9834
10282
  return f();
@@ -9836,6 +10284,10 @@ function withSdkOptions(opts, f, deferred = []) {
9836
10284
  [sdkOptions, deferredPlatforms] = saved;
9837
10285
  }
9838
10286
  }
10287
+ const WRAP_UNBOUND = {
10288
+ ios: "wrap it in Swift of your own whose types Lucent binds, in a local pod the app depends on",
10289
+ android: "wrap it in Kotlin of your own whose types Lucent binds, in a Gradle module the app depends on"
10290
+ };
9839
10291
  function platformSdkTyped(platform) {
9840
10292
  return !deferredPlatforms.includes(platform) && sdkAvailable(platform, sdkOptions);
9841
10293
  }
@@ -9862,6 +10314,9 @@ function sdkNamesOf(platform, module) {
9862
10314
  const n = sdkNames(platform, module, sdkOptions);
9863
10315
  return "names" in n ? n.names : void 0;
9864
10316
  }
10317
+ function sdkCacheDir() {
10318
+ return sdkOptions.cacheDir;
10319
+ }
9865
10320
  function currentSdkIdentity() {
9866
10321
  return sdkIdentity(sdkOptions);
9867
10322
  }
@@ -9904,6 +10359,7 @@ function jniDescriptor(params, returns, typeParams = []) {
9904
10359
  case "id":
9905
10360
  case "record":
9906
10361
  case "set":
10362
+ case "tuple":
9907
10363
  case "out":
9908
10364
  case "fn":
9909
10365
  case "error": return fail$1(`${t.k} is not a Java type`);
@@ -9964,12 +10420,261 @@ function blockConversion(t) {
9964
10420
  passed: true
9965
10421
  }, sdkTypeFacts("ios"));
9966
10422
  }
10423
+ function kotlinFunctionConversion(t) {
10424
+ return planConversion({
10425
+ ...t,
10426
+ nullable: false
10427
+ }, {
10428
+ backend: "jni",
10429
+ platform: "android",
10430
+ flow: "in",
10431
+ passed: true
10432
+ }, sdkTypeFacts("android"));
10433
+ }
10434
+ //#endregion
10435
+ //#region ../compiler/src/sdk/view-rules.ts
10436
+ const ROOT_VIEW = {
10437
+ ios: {
10438
+ module: "UIKit",
10439
+ name: "UIView"
10440
+ },
10441
+ android: {
10442
+ module: "android.view",
10443
+ name: "View"
10444
+ }
10445
+ };
10446
+ const LISTENER = /^setOn([A-Z]\w*)Listener$/;
10447
+ const SETTER = /^set([A-Z]\w*)$/;
10448
+ const REGISTER = "addAction:forControlEvents:";
10449
+ const INSERT_AT = /^insert\w*:atIndex:$/;
10450
+ const capitalized = (s) => s[0].toUpperCase() + s.slice(1);
10451
+ const decapitalized = (s) => s[0].toLowerCase() + s.slice(1);
10452
+ const singleBit = (value) => typeof value === "number" && value > 0 && (value & value - 1) === 0;
10453
+ function referenced(type, schema, find) {
10454
+ if (type.k !== "ref") return void 0;
10455
+ const decl = type.module === schema.module ? schema.types.find((t) => t.name === type.name) : find(type.module, type.name);
10456
+ return {
10457
+ module: type.module,
10458
+ name: type.name,
10459
+ decl
10460
+ };
10461
+ }
10462
+ function viewRules(cls, schema, find) {
10463
+ const types = ownTypes(schema);
10464
+ const where = schema.provenance?.artifact ?? schema.module;
10465
+ const why = (member, role) => unsupportedReason(planBinding(cls, member, schema, types, role));
10466
+ const props = [];
10467
+ const events = [];
10468
+ const refused = [];
10469
+ for (const p of cls.properties ?? []) {
10470
+ if (p.static || p.readonly || p.value !== void 0) continue;
10471
+ const reason = why(p, "set");
10472
+ if (reason) refused.push({
10473
+ name: p.name,
10474
+ reason
10475
+ });
10476
+ else props.push({
10477
+ kind: "property",
10478
+ name: p.name,
10479
+ member: p,
10480
+ explanation: `${cls.name}.${p.name}: a writable property${p.setter ? ` (${p.setter})` : ""}, in ${where}`
10481
+ });
10482
+ }
10483
+ const setters = /* @__PURE__ */ new Map();
10484
+ let children;
10485
+ for (const m of cls.methods ?? []) {
10486
+ if (m.static) continue;
10487
+ const [child, index] = m.params;
10488
+ if (m.params.length === 2 && child.type.k === "ref" && index.type.k === "prim" && (schema.platform === "ios" ? !!m.selector && INSERT_AT.test(m.selector) : m.name === "addView" && child.type.module === ROOT_VIEW.android.module && child.type.name === ROOT_VIEW.android.name) && !children) {
10489
+ children = {
10490
+ insert: m,
10491
+ explanation: `${cls.name}.${m.selector ?? m.name}: inserts a view at an index, in ${where}`
10492
+ };
10493
+ continue;
10494
+ }
10495
+ const listener = LISTENER.exec(m.name);
10496
+ if (listener && m.params.length === 1) {
10497
+ const name = `on${listener[1]}`;
10498
+ const ref = referenced(m.params[0].type, schema, find);
10499
+ const iface = ref?.decl?.kind === "class" ? ref.decl : void 0;
10500
+ const method = iface?.functional ? iface.methods?.find((x) => x.name === iface.functional && x.abstract) : void 0;
10501
+ if (!ref || !iface || !method) refused.push({
10502
+ name,
10503
+ reason: `${m.name}'s listener has more than one method: set it in setup code, with an object of a class implementing it`
10504
+ });
10505
+ else events.push({
10506
+ kind: "listener",
10507
+ name,
10508
+ setter: m,
10509
+ listener: {
10510
+ module: ref.module,
10511
+ name: ref.name
10512
+ },
10513
+ method,
10514
+ explanation: `${cls.name}.${m.name}: a listener with one method (${ref.name}.${method.name}), in ${where}`
10515
+ });
10516
+ continue;
10517
+ }
10518
+ if (m.selector === REGISTER && m.params.length === 2) {
10519
+ const ref = referenced(m.params[1].type, schema, find);
10520
+ if (ref?.decl?.kind === "enum") for (const c of ref.decl.cases.filter((x) => singleBit(x.value))) events.push({
10521
+ kind: "control",
10522
+ name: `on${capitalized(c.name)}`,
10523
+ register: m,
10524
+ events: {
10525
+ module: ref.module,
10526
+ name: ref.name
10527
+ },
10528
+ value: c.value,
10529
+ explanation: `${cls.name}.${REGISTER} with ${ref.name}.${c.name}: a control event, in ${where}`
10530
+ });
10531
+ continue;
10532
+ }
10533
+ const setter = SETTER.exec(m.name);
10534
+ if (schema.platform === "android" && setter && m.params.length === 1 && m.returns.k === "prim" && m.returns.name === "void") {
10535
+ const name = decapitalized(setter[1]);
10536
+ setters.set(name, [...setters.get(name) ?? [], m]);
10537
+ }
10538
+ }
10539
+ for (const [name, overloads] of setters) {
10540
+ if (props.some((p) => p.name === name)) continue;
10541
+ if (overloads.every((m) => m.typeParams?.length)) {
10542
+ refused.push({
10543
+ name,
10544
+ reason: `${overloads[0].name} is generic, and an attribute gives no type for it`
10545
+ });
10546
+ continue;
10547
+ }
10548
+ const usable = overloads.filter((m) => !m.typeParams?.length && !why(m, "call"));
10549
+ if (!usable.length) refused.push({
10550
+ name,
10551
+ reason: why(overloads[0], "call")
10552
+ });
10553
+ else props.push({
10554
+ kind: "setter",
10555
+ name,
10556
+ overloads: usable,
10557
+ explanation: `${cls.name}.${usable[0].name}: a setter taking one value, in ${where}`
10558
+ });
10559
+ }
10560
+ return {
10561
+ props,
10562
+ events,
10563
+ refused,
10564
+ ...children ? { children } : {}
10565
+ };
10566
+ }
10567
+ function isViewClass(cls, schema, find) {
10568
+ const root = ROOT_VIEW[schema.platform];
10569
+ let owner = cls;
10570
+ let module = schema.module;
10571
+ for (let depth = 0; owner && depth < 64; depth++) {
10572
+ if (module === root.module && owner.name === root.name) return true;
10573
+ if (owner.interface || !owner.extends) return false;
10574
+ const sup = parseSdkType(owner.extends, module);
10575
+ if (sup.k !== "ref") return false;
10576
+ if (sup.module === root.module && sup.name === root.name) return true;
10577
+ if (sup.module !== module && schema.platform === "ios") return true;
10578
+ const decl = sup.module === schema.module ? schema.types.find((t) => t.name === sup.name) : find(sup.module, sup.name);
10579
+ owner = decl?.kind === "class" ? decl : void 0;
10580
+ module = sup.module;
10581
+ }
10582
+ return false;
10583
+ }
10584
+ function viewConstruction(cls, schema, find) {
10585
+ if (schema.platform === "android") {
10586
+ const ctor = (cls.constructors ?? []).find((c) => !c.protected && c.params.length === 1 && c.params[0].type.k === "ref" && c.params[0].type.module === "android.content" && c.params[0].type.name === "Context");
10587
+ return ctor ? {
10588
+ kind: "context",
10589
+ ctor,
10590
+ owner: cls.name,
10591
+ module: schema.module
10592
+ } : {
10593
+ kind: "create",
10594
+ reason: `${cls.name} has no constructor taking only a Context`
10595
+ };
10596
+ }
10597
+ let owner = cls;
10598
+ let module = schema.module;
10599
+ for (let depth = 0; owner && depth < 32; depth++) {
10600
+ const ctors = owner.constructors ?? [];
10601
+ const frame = ctors.find((c) => c.selector === "initWithFrame:");
10602
+ const plain = ctors.find((c) => c.selector === "init" && !c.params.length);
10603
+ if (frame) return {
10604
+ kind: "frame",
10605
+ ctor: frame,
10606
+ owner: owner.name,
10607
+ module
10608
+ };
10609
+ if (plain) return {
10610
+ kind: "init",
10611
+ ctor: plain,
10612
+ owner: owner.name,
10613
+ module
10614
+ };
10615
+ if (ctors.length && !owner.inheritsInit) break;
10616
+ if (!owner.extends) break;
10617
+ const sup = parseSdkType(owner.extends, module);
10618
+ if (sup.k !== "ref") break;
10619
+ const decl = sup.module === schema.module ? schema.types.find((t) => t.name === sup.name) : find(sup.module, sup.name);
10620
+ owner = decl?.kind === "class" ? decl : void 0;
10621
+ module = sup.module;
10622
+ }
10623
+ return {
10624
+ kind: "create",
10625
+ reason: `${cls.name} has no initWithFrame: or init to make it with: say how, create={() => new ${cls.name}(…)}`
10626
+ };
10627
+ }
10628
+ function viewTag(cls, schema, moduleOf) {
10629
+ const find = (module, name) => moduleOf(module)?.types.find((t) => t.name === name);
10630
+ const props = /* @__PURE__ */ new Map();
10631
+ const events = /* @__PURE__ */ new Map();
10632
+ const refused = /* @__PURE__ */ new Map();
10633
+ let children;
10634
+ let owner = {
10635
+ cls,
10636
+ schema
10637
+ };
10638
+ for (let depth = 0; owner && depth < 64; depth++) {
10639
+ const rules = viewRules(owner.cls, owner.schema, find);
10640
+ for (const prop of rules.props) if (!props.has(prop.name)) props.set(prop.name, {
10641
+ prop,
10642
+ owner
10643
+ });
10644
+ for (const event of rules.events) if (!events.has(event.name)) events.set(event.name, {
10645
+ event,
10646
+ owner
10647
+ });
10648
+ if (rules.children && !children) children = {
10649
+ rule: rules.children,
10650
+ owner
10651
+ };
10652
+ for (const r of rules.refused) if (!refused.has(r.name)) refused.set(r.name, r.reason);
10653
+ const root = ROOT_VIEW[schema.platform];
10654
+ if (owner.schema.module === root.module && owner.cls.name === root.name) break;
10655
+ if (!owner.cls.extends) break;
10656
+ const sup = parseSdkType(owner.cls.extends, owner.schema.module);
10657
+ const next = sup.k === "ref" ? moduleOf(sup.module) : void 0;
10658
+ const decl = sup.k === "ref" ? next?.types.find((t) => t.name === sup.name) : void 0;
10659
+ owner = next && decl?.kind === "class" ? {
10660
+ cls: decl,
10661
+ schema: next
10662
+ } : void 0;
10663
+ }
10664
+ return {
10665
+ props,
10666
+ events,
10667
+ ...children ? { children } : {},
10668
+ refused,
10669
+ construction: viewConstruction(cls, schema, find)
10670
+ };
10671
+ }
9967
10672
  //#endregion
9968
10673
  //#region ../compiler/src/sdk/dts.ts
9969
- function sdkDts(schema) {
9970
- const plain = emitDts(schema, /* @__PURE__ */ new Map());
10674
+ function sdkDts(schema, options = {}) {
10675
+ const plain = emitDts(schema, /* @__PURE__ */ new Map(), options);
9971
10676
  const aliases = importAliases(schema, plain.imports);
9972
- return aliases.size ? emitDts(schema, aliases).text : plain.text;
10677
+ return aliases.size ? emitDts(schema, aliases, options).text : plain.text;
9973
10678
  }
9974
10679
  function importAliases(schema, imports) {
9975
10680
  const local = new Set(schema.types.map((t) => t.name));
@@ -9980,7 +10685,7 @@ function importAliases(schema, imports) {
9980
10685
  return aliases;
9981
10686
  }
9982
10687
  const moduleIdent = (module) => module.replace(/^lucent:/, "").replace(/^(ios|android)\//, "").replace(/\W/g, "_");
9983
- function emitDts(schema, aliases) {
10688
+ function emitDts(schema, aliases, options) {
9984
10689
  const imports = /* @__PURE__ */ new Map();
9985
10690
  const use = (module, name) => {
9986
10691
  const names = imports.get(module) ?? /* @__PURE__ */ new Set();
@@ -10005,6 +10710,10 @@ function emitDts(schema, aliases) {
10005
10710
  use("lucent:ios", "Out");
10006
10711
  return ref("Out", tsType(t.of, true));
10007
10712
  case "set": return ref("Set", tsType(t.of, out));
10713
+ case "tuple": return tuple(t.of.map((x, i) => ({
10714
+ type: tsType(x, out),
10715
+ ...t.labels ? { name: t.labels[i] } : {}
10716
+ })));
10008
10717
  case "array":
10009
10718
  if (t.of.k === "prim" && t.of.name === "byte" && !t.list) return ref("Uint8Array");
10010
10719
  return array(tsType(t.of, out));
@@ -10052,7 +10761,7 @@ function emitDts(schema, aliases) {
10052
10761
  type: tsType(parseSdkType(f.type, schema.module))
10053
10762
  })))
10054
10763
  }, blank);
10055
- else body.push(...classDts(schema, type, tsType, use), blank);
10764
+ else body.push(...classDts(schema, type, tsType, use, options), blank);
10056
10765
  const refused = refusalDoc(schema);
10057
10766
  for (const f of schema.functions ?? []) {
10058
10767
  const tps = f.typeParams ?? [];
@@ -10223,7 +10932,7 @@ const RESERVED$3 = /* @__PURE__ */ new Set([
10223
10932
  function safeName(n) {
10224
10933
  return RESERVED$3.has(n) ? `${n}_` : n;
10225
10934
  }
10226
- function classDts(schema, cls, tsType, use) {
10935
+ function classDts(schema, cls, tsType, use, options) {
10227
10936
  const parse = (s, tps = []) => parseSdkType(s, schema.module, tps);
10228
10937
  const oneOf = (refs, type, out) => {
10229
10938
  if (!refs) return tsType(type, out);
@@ -10316,10 +11025,12 @@ function classDts(schema, cls, tsType, use) {
10316
11025
  const methodNames = new Set((cls.methods ?? []).map((m) => `${!!m.static}:${m.name}`));
10317
11026
  for (const p of (cls.properties ?? []).filter((x) => !methodNames.has(`${!!x.static}:${x.name}`))) {
10318
11027
  const type = p.value !== void 0 && p.static && p.readonly ? literal$3(constantValue$1(parse(p.type), p.value)) : settled(p, oneOf(p.oneOf, result(parse(p.type)), true));
11028
+ const set = p.readonly || schema.platform !== "android" ? void 0 : oneOf(p.oneOf, parse(p.type), false);
10319
11029
  members.push({
10320
11030
  k: "property",
10321
11031
  name: p.name,
10322
11032
  type,
11033
+ ...set && printType(set) !== printType(type) ? { set } : {},
10323
11034
  ...p.static ? { static: true } : {},
10324
11035
  ...p.readonly ? { readonly: true } : {},
10325
11036
  ...memberDoc(p)
@@ -10384,6 +11095,23 @@ function classDts(schema, cls, tsType, use) {
10384
11095
  params: [],
10385
11096
  ret: keyword$1("void")
10386
11097
  });
11098
+ const jsx = options.jsx ? jsxAttributes(schema, cls, tsType, parse) : void 0;
11099
+ if (jsx?.root) members.push({
11100
+ k: "property",
11101
+ name: "~jsx",
11102
+ type: ref(use("lucent:ui", "NativeAttributes"), ref("this")),
11103
+ readonly: true,
11104
+ optional: true,
11105
+ doc: "The JSX attributes of this view's tag: its classes' `~jsx:` keys, together."
11106
+ });
11107
+ if (jsx?.decl) members.push({
11108
+ k: "property",
11109
+ name: `~jsx:${schema.module}.${cls.name}`,
11110
+ type: ref(jsx.name, ref("this"), ...typeParams.map((t) => ref(t.name))),
11111
+ readonly: true,
11112
+ optional: true,
11113
+ doc: "The JSX attributes this class gives its tag, derived by rule from its declarations."
11114
+ });
10387
11115
  const out = [{
10388
11116
  k: "class",
10389
11117
  name: cls.name,
@@ -10401,8 +11129,63 @@ function classDts(schema, cls, tsType, use) {
10401
11129
  extends: supers,
10402
11130
  members: []
10403
11131
  });
11132
+ if (jsx?.decl) out.push(jsx.decl);
10404
11133
  return out;
10405
11134
  }
11135
+ function jsxAttributes(schema, cls, tsType, parse) {
11136
+ const find = (module, name) => findSdkType(schema.platform, module, name);
11137
+ if (cls.interface || !isViewClass(cls, schema, find)) return void 0;
11138
+ const view = ROOT_VIEW[schema.platform];
11139
+ const root = schema.module === view.module && cls.name === view.name;
11140
+ const rules = viewRules(cls, schema, find);
11141
+ const childrenMember = (c) => {
11142
+ const child = tsType(parseSdkType(`${view.module}.${view.name}`), false);
11143
+ return {
11144
+ k: "property",
11145
+ name: "children",
11146
+ type: union$1([child, readonlyArray(child)]),
11147
+ optional: true,
11148
+ doc: c.explanation
11149
+ };
11150
+ };
11151
+ const name = `__jsx_${cls.name}`;
11152
+ if (!rules.props.length && !rules.events.length && !rules.children) return root ? {
11153
+ name,
11154
+ root
11155
+ } : void 0;
11156
+ const props = rules.props.map((p) => ({
11157
+ k: "property",
11158
+ name: p.name,
11159
+ type: p.kind === "property" ? tsType(parse(p.member.type), false) : union$1(p.overloads.map((m) => tsType(parse(m.params[0].type), false))),
11160
+ optional: true,
11161
+ doc: p.explanation
11162
+ }));
11163
+ const events = rules.events.map((e) => ({
11164
+ k: "property",
11165
+ name: e.name,
11166
+ type: e.kind === "listener" ? fn$3(e.method.params.map((x, i) => param$2(`arg${i}`, tsType(parseSdkType(x.type, e.listener.module), true))), tsType(parseSdkType(e.method.returns, e.listener.module), false)) : fn$3([param$2("control", ref("Self"))], keyword$1("void")),
11167
+ optional: true,
11168
+ doc: e.explanation
11169
+ }));
11170
+ return {
11171
+ name,
11172
+ root,
11173
+ decl: {
11174
+ k: "interface",
11175
+ name,
11176
+ local: true,
11177
+ typeParams: [{ name: "Self" }, ...distinctTypeParams(cls.typeParams ?? []).map((name) => ({
11178
+ name,
11179
+ default: keyword$1("unknown")
11180
+ }))],
11181
+ members: [
11182
+ ...props,
11183
+ ...events,
11184
+ ...rules.children ? [childrenMember(rules.children)] : []
11185
+ ]
11186
+ }
11187
+ };
11188
+ }
10406
11189
  function namedLikeAncestor(schema, cls) {
10407
11190
  let ext = cls.extends ? parseSdkType(cls.extends, schema.module) : void 0;
10408
11191
  for (let depth = 0; ext?.k === "ref" && depth < 32; depth++) {
@@ -10731,96 +11514,165 @@ function constantValue$1(t, value) {
10731
11514
  return isBigIntType(t) ? BigInt(value) : value;
10732
11515
  }
10733
11516
  //#endregion
10734
- //#region ../compiler/src/package-versions.ts
10735
- function compare$1(a, b) {
10736
- for (let i = 0; i < Math.max(a.length, b.length); i++) {
10737
- const d = (a[i] ?? 0) - (b[i] ?? 0);
10738
- if (d) return d;
10739
- }
10740
- return 0;
11517
+ //#region ../compiler/src/sdk/declaration-cache.ts
11518
+ let version$1;
11519
+ function declarationsVersion() {
11520
+ if (version$1) return version$1;
11521
+ return version$1 = "df570a79";
11522
+ }
11523
+ function cachedDeclarations(cacheDir, identity, key, make) {
11524
+ const name = crypto.createHash("sha256").update([
11525
+ declarationsVersion(),
11526
+ identity,
11527
+ ...key
11528
+ ].join("\n")).digest("hex").slice(0, 24);
11529
+ const file = path.join(cacheRoot(cacheDir), "declarations", `${name}.d.ts`);
11530
+ try {
11531
+ return fs.readFileSync(file, "utf8");
11532
+ } catch {}
11533
+ const text = make();
11534
+ const tmp = `${file}.${process.pid}.${crypto.randomUUID()}.tmp`;
11535
+ fs.mkdirSync(path.dirname(file), { recursive: true });
11536
+ fs.writeFileSync(tmp, text);
11537
+ fs.renameSync(tmp, file);
11538
+ return text;
10741
11539
  }
10742
- function pessimisticUpper(v) {
10743
- const head = v.length > 1 ? v.slice(0, -1) : [...v];
10744
- head[head.length - 1] += 1;
10745
- return head;
11540
+ //#endregion
11541
+ //#region ../compiler/src/sdk/native-jsx-dts.ts
11542
+ const NATIVE_JSX_UI = ["NativeViewTag"];
11543
+ function rootViews(platforms) {
11544
+ const alias = (p) => `${p}_${ROOT_VIEW[p].name}`;
11545
+ return {
11546
+ imports: platforms.map((p) => ({
11547
+ k: "importType",
11548
+ names: [`${ROOT_VIEW[p].name} as ${alias(p)}`],
11549
+ from: `lucent:${p}/${ROOT_VIEW[p].module}`
11550
+ })),
11551
+ types: platforms.map((p) => ref(alias(p)))
11552
+ };
10746
11553
  }
10747
- const POD_OPERATORS = {
10748
- "=": (v) => ({
10749
- lo: {
10750
- v,
10751
- inclusive: true
10752
- },
10753
- hi: {
10754
- v,
10755
- inclusive: true
10756
- }
10757
- }),
10758
- ">=": (v) => ({ lo: {
10759
- v,
10760
- inclusive: true
10761
- } }),
10762
- ">": (v) => ({ lo: {
10763
- v,
10764
- inclusive: false
10765
- } }),
10766
- "<=": (v) => ({ hi: {
10767
- v,
10768
- inclusive: true
10769
- } }),
10770
- "<": (v) => ({ hi: {
10771
- v,
10772
- inclusive: false
10773
- } }),
10774
- "~>": (v) => ({
10775
- lo: {
10776
- v,
10777
- inclusive: true
10778
- },
10779
- hi: {
10780
- v: pessimisticUpper(v),
10781
- inclusive: false
11554
+ const nativeTags = (roots) => roots.map((r) => ref("NativeViewTag", r));
11555
+ function nativeJsxDecls() {
11556
+ return [{
11557
+ k: "interface",
11558
+ name: "ElementAttributesProperty",
11559
+ members: [{
11560
+ k: "property",
11561
+ name: "~jsx",
11562
+ type: object([])
11563
+ }]
11564
+ }, {
11565
+ k: "interface",
11566
+ name: "IntrinsicClassAttributes",
11567
+ typeParams: [{ name: "T" }],
11568
+ members: [{
11569
+ k: "property",
11570
+ name: "create",
11571
+ type: fn$3([], ref("T")),
11572
+ optional: true,
11573
+ doc: "Makes the view, where its class has no frame or Context constructor to make it with."
11574
+ }]
11575
+ }];
11576
+ }
11577
+ //#endregion
11578
+ //#region ../compiler/src/sdk/declarations.ts
11579
+ function classOfDecl(decl) {
11580
+ const sdk = sdkModuleOf(decl.getSourceFile());
11581
+ if (!sdk) return void 0;
11582
+ const owner = ts.isClassDeclaration(decl) ? decl : decl.parent;
11583
+ if (!owner || !ts.isClassDeclaration(owner) || !owner.name) return void 0;
11584
+ const cls = findSdkType(sdk.platform, sdk.module, owner.name.text);
11585
+ return cls?.kind === "class" ? {
11586
+ ...sdk,
11587
+ cls
11588
+ } : void 0;
11589
+ }
11590
+ function sdkInterfacesOf(checker, decl) {
11591
+ const out = [];
11592
+ for (const h of decl.heritageClauses ?? []) {
11593
+ if (h.token !== ts.SyntaxKind.ImplementsKeyword) continue;
11594
+ for (const t of h.types) {
11595
+ const d = checker.getTypeAtLocation(t).getSymbol()?.declarations?.find(ts.isClassDeclaration);
11596
+ const ref = d ? classOfDecl(d) : void 0;
11597
+ if (ref?.cls.interface) out.push(ref);
10782
11598
  }
10783
- })
10784
- };
10785
- function intersect(a, b) {
10786
- const pick = (x, y, sign) => {
10787
- if (!x) return y;
10788
- if (!y) return x;
10789
- const d = compare$1(x.v, y.v) * sign;
10790
- if (d !== 0) return d > 0 ? x : y;
10791
- return {
10792
- v: x.v,
10793
- inclusive: x.inclusive && y.inclusive
11599
+ }
11600
+ return out;
11601
+ }
11602
+ function requirementOf(checker, m) {
11603
+ const cls = m.parent;
11604
+ if (!ts.isClassLike(cls) || !ts.isIdentifier(m.name)) return void 0;
11605
+ for (const protocol of sdkInterfacesOf(checker, cls)) {
11606
+ const method = protocol.cls.methods?.find((x) => !x.static && x.name === m.name.text);
11607
+ if (method) return {
11608
+ protocol,
11609
+ method,
11610
+ main: !!(protocol.cls.mainActor || method.mainActor)
10794
11611
  };
11612
+ }
11613
+ }
11614
+ function schemaMethod(ref, decl) {
11615
+ const inherited = inheritedFrom(ref, decl);
11616
+ if (inherited) return {
11617
+ ref: inherited.ref,
11618
+ method: inherited.ref.cls.methods[inherited.index],
11619
+ promise: false
10795
11620
  };
10796
- return {
10797
- lo: pick(a.lo, b.lo, 1),
10798
- hi: pick(a.hi, b.hi, -1)
10799
- };
11621
+ const name = decl.name.text;
11622
+ const index = decl.parent.members.filter((m) => ts.isMethodDeclaration(m) && m.name.text === name).indexOf(decl);
11623
+ return (ref.cls.methods ?? []).flatMap((m) => [...m.name === name ? [{
11624
+ ref,
11625
+ method: m,
11626
+ promise: false
11627
+ }] : [], ...m.async && declaresPromise(ref.cls, m) && (m.async.name ?? m.name) === name ? [{
11628
+ ref,
11629
+ method: m,
11630
+ promise: true
11631
+ }] : []])[index];
10800
11632
  }
10801
- function isEmpty(r) {
10802
- if (!r.lo || !r.hi) return false;
10803
- const d = compare$1(r.lo.v, r.hi.v);
10804
- return d > 0 || d === 0 && !(r.lo.inclusive && r.hi.inclusive);
11633
+ function schemaProperty(ref, decl) {
11634
+ const inherited = inheritedFrom(ref, decl);
11635
+ if (inherited) return {
11636
+ ref: inherited.ref,
11637
+ property: inherited.ref.cls.properties[inherited.index]
11638
+ };
11639
+ const name = decl.name.text;
11640
+ const isStatic = !!ts.getModifiers(decl)?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword);
11641
+ const property = ref.cls.properties?.find((p) => p.name === name && !!p.static === isStatic);
11642
+ return property ? {
11643
+ ref,
11644
+ property
11645
+ } : void 0;
10805
11646
  }
10806
- function podRange(requirement) {
10807
- let range = {};
10808
- for (const part of requirement.split(",")) {
10809
- const m = /^\s*(~>|>=|<=|>|<|=)?\s*(\d+(?:\.\d+)*)\s*$/.exec(part);
10810
- if (!m) return void 0;
10811
- range = intersect(range, POD_OPERATORS[m[1] ?? "="](m[2].split(".").map(Number)));
10812
- }
10813
- return range;
11647
+ const isSdkPropertyDecl = (d) => ts.isPropertyDeclaration(d) || ts.isGetAccessorDeclaration(d) || ts.isSetAccessorDeclaration(d);
11648
+ function inheritedFrom(ref, decl) {
11649
+ const tag = ts.getJSDocTags(decl).find((t) => `@${t.tagName.text}` === INHERITED_TAG);
11650
+ if (!tag) return void 0;
11651
+ const [owner, index] = (ts.getTextOfJSDocComment(tag.comment) ?? "").split(" ");
11652
+ const dot = owner.lastIndexOf(".");
11653
+ const module = owner.slice(0, dot);
11654
+ const cls = findSdkType(ref.platform, module, owner.slice(dot + 1));
11655
+ if (cls?.kind !== "class") throw new Error(`${owner}: no class for an inherited member`);
11656
+ return {
11657
+ ref: {
11658
+ ...ref,
11659
+ module,
11660
+ cls
11661
+ },
11662
+ index: Number(index)
11663
+ };
10814
11664
  }
10815
- function podsCompatible(a, b) {
10816
- const ra = podRange(a);
10817
- const rb = podRange(b);
10818
- return !ra || !rb || !isEmpty(intersect(ra, rb));
11665
+ function schemaConstructor(ref, decl) {
11666
+ return ref.cls.constructors[decl.parent.members.filter(ts.isConstructorDeclaration).indexOf(decl)];
10819
11667
  }
10820
- function compareVersions(a, b) {
10821
- return compare$1(a.split(".").map(Number), b.split(".").map(Number));
11668
+ function promiseForm(m) {
11669
+ const { throws: _, ...rest } = m;
11670
+ return {
11671
+ ...rest,
11672
+ params: m.params.slice(0, -1),
11673
+ returns: m.async.returns
11674
+ };
10822
11675
  }
10823
- const gradleCompatible = (a, b) => !a.endsWith("!!") && !b.endsWith("!!");
10824
11676
  //#endregion
10825
11677
  //#region ../compiler/src/sdk/toolkit-forms.ts
10826
11678
  const FORMS = { SwiftUI: [{
@@ -10945,7 +11797,7 @@ function toolkitDts(toolkit, schema) {
10945
11797
  const overloads = (owner, m, name) => {
10946
11798
  const refused = unsupportedReason(planBinding(owner, m, schema, ownTypes(schema)));
10947
11799
  const since = String(m.since ?? owner?.since ?? "0");
10948
- const newer = compareVersions(since, MIN_IOS) > 0;
11800
+ const newer = compareVersions(since, oldestIos()) > 0;
10949
11801
  const doc = (form) => [
10950
11802
  ...refused ? [`Lucent cannot write this in a body yet: ${refused}.`] : [],
10951
11803
  ...m.deprecated ? ["@deprecated"] : [],
@@ -11172,11 +12024,12 @@ function toolkitDts(toolkit, schema) {
11172
12024
  return printUnit({
11173
12025
  banner: `Generated by Lucent from ${schema.provenance?.artifact ?? schema.module} (${schema.module}, written as source). Do not edit.`,
11174
12026
  decls: [
11175
- ...forms.size ? [{
12027
+ {
11176
12028
  k: "importType",
11177
- names: [...forms].sort(),
12029
+ names: [.../* @__PURE__ */ new Set([...forms, ...NATIVE_JSX_UI])].sort(),
11178
12030
  from: "lucent:ui"
11179
- }] : [],
12031
+ },
12032
+ ...rootViews([toolkit.platform]).imports,
11180
12033
  ...decls,
11181
12034
  ...modifierDecls,
11182
12035
  ...namespaces,
@@ -11318,6 +12171,7 @@ const method = (o) => ({
11318
12171
  });
11319
12172
  function fixedDecls(toolkit) {
11320
12173
  const view = ref(toolkit.source.view);
12174
+ const [root] = rootViews([toolkit.platform]).types;
11321
12175
  const shown = union$1([
11322
12176
  view,
11323
12177
  literal$3(false),
@@ -11353,8 +12207,14 @@ function fixedDecls(toolkit) {
11353
12207
  {
11354
12208
  k: "typeAlias",
11355
12209
  name: "Element",
11356
- type: view
12210
+ type: intersection([view, root])
12211
+ },
12212
+ {
12213
+ k: "typeAlias",
12214
+ name: "ElementType",
12215
+ type: union$1([fn$3([param$2("props", keyword$1("never"))], view), ...nativeTags([root])])
11357
12216
  },
12217
+ ...nativeJsxDecls(),
11358
12218
  {
11359
12219
  k: "interface",
11360
12220
  name: "ElementChildrenAttribute",
@@ -11555,164 +12415,6 @@ function toolkit(name) {
11555
12415
  return TOOLKITS[name];
11556
12416
  }
11557
12417
  //#endregion
11558
- //#region ../compiler/src/ui/roots.ts
11559
- const ROOT_VIEWS = {
11560
- ios: {
11561
- module: "UIKit",
11562
- name: "UIView"
11563
- },
11564
- android: {
11565
- module: "android.view",
11566
- name: "View"
11567
- }
11568
- };
11569
- const SLOT_VIEWS = {
11570
- ios: {
11571
- module: "UIKit",
11572
- name: "UIView"
11573
- },
11574
- android: {
11575
- module: "android.view",
11576
- name: "ViewGroup"
11577
- }
11578
- };
11579
- const sdkClassOf = (classes) => (decl) => {
11580
- const sdk = sdkModuleOf(decl.getSourceFile());
11581
- const found = sdk && classes[sdk.platform];
11582
- return found && found.module === sdk.module && decl.name?.text === found.name ? sdk.platform : void 0;
11583
- };
11584
- function toolkitOf(root) {
11585
- const toolkit = toolkitOfModule(root.module);
11586
- return toolkit && TOOLKITS[toolkit].root === root.name ? toolkit : void 0;
11587
- }
11588
- const sdkRootView = sdkClassOf(ROOT_VIEWS);
11589
- const sdkRoot = (decl) => {
11590
- const builtin = builtinSdkModuleOf(decl.getSourceFile());
11591
- const toolkit = builtin && toolkitOf({
11592
- module: builtin,
11593
- name: decl.name?.text ?? ""
11594
- });
11595
- return toolkit ? TOOLKITS[toolkit].platform : sdkRootView(decl);
11596
- };
11597
- const sdkSlot = sdkClassOf(SLOT_VIEWS);
11598
- function returnShape(checker, fn, platform, rootOf) {
11599
- const signature = checker.getSignatureFromDeclaration(fn);
11600
- const declared = signature ? checker.getReturnTypeOfSignature(signature) : void 0;
11601
- const promised = declared && promisedType(checker, declared);
11602
- const viewOf = (t) => viewClass(checker, t, rootOf);
11603
- const isView = (t) => {
11604
- const found = viewOf(t);
11605
- return found && (!platform || found.platform === platform) ? found.decl : void 0;
11606
- };
11607
- if (promised) return members(promised).some(isView) ? { kind: "promised" } : { kind: "value" };
11608
- const returned = returnedExpressions(checker, fn, platform).map((e) => checker.getTypeAtLocation(e));
11609
- const types = (fn.body ? returned : declared ? [declared] : []).flatMap(members);
11610
- const views = [];
11611
- let other;
11612
- let viewName = "";
11613
- for (const t of types) {
11614
- if (t.flags & ts.TypeFlags.Any || viewOf(t) && !isView(t)) continue;
11615
- const cls = isView(t);
11616
- if (cls) {
11617
- views.push(cls);
11618
- viewName ||= checker.typeToString(t);
11619
- } else other ??= checker.typeToString(t);
11620
- }
11621
- if (!views.length) return { kind: "value" };
11622
- if (other !== void 0) return {
11623
- kind: "ambiguous",
11624
- view: viewName,
11625
- other
11626
- };
11627
- return {
11628
- kind: "view",
11629
- root: commonClass(checker, views)
11630
- };
11631
- }
11632
- function classIdentity(checker, returned) {
11633
- const decl = ancestors(checker, returned).find((c) => c.getSourceFile().isDeclarationFile) ?? returned;
11634
- const sf = decl.getSourceFile();
11635
- return {
11636
- module: sdkModuleOf(sf)?.module ?? builtinSdkModuleOf(sf) ?? path.basename(sf.fileName, ".d.ts"),
11637
- name: decl.name?.text ?? ""
11638
- };
11639
- }
11640
- function members(t) {
11641
- return t.isUnion() ? t.types.flatMap(members) : elementsOf(t) ?? [t];
11642
- }
11643
- function elementsOf(t) {
11644
- if (!t.isIntersection()) return void 0;
11645
- return t.types.every((m) => {
11646
- const decl = m.getSymbol()?.declarations?.[0];
11647
- return !!decl && ts.isInterfaceDeclaration(decl) && !!toolkitElement(decl);
11648
- }) ? t.types : void 0;
11649
- }
11650
- function promisedType(checker, t) {
11651
- const name = t.getSymbol()?.getName();
11652
- if (name !== "Promise" && name !== "PromiseLike") return void 0;
11653
- return checker.getTypeArguments(t)[0];
11654
- }
11655
- function viewClass(checker, t, rootOf) {
11656
- const decl = t.getSymbol()?.declarations?.[0];
11657
- if (decl && ts.isInterfaceDeclaration(decl)) return toolkitElement(decl);
11658
- if (!decl || !ts.isClassDeclaration(decl)) return void 0;
11659
- for (const c of ancestors(checker, decl)) {
11660
- const platform = rootOf(c);
11661
- if (platform) return {
11662
- decl,
11663
- platform
11664
- };
11665
- }
11666
- }
11667
- function toolkitElement(decl) {
11668
- const sf = decl.getSourceFile();
11669
- const name = toolkitOfModule(builtinSdkModuleOf(sf));
11670
- const found = name && toolkit(name);
11671
- if (!found || found.element !== decl.name.text) return void 0;
11672
- const root = sf.statements.find((s) => ts.isClassDeclaration(s) && s.name?.text === found.root);
11673
- return root && {
11674
- decl: root,
11675
- platform: found.platform
11676
- };
11677
- }
11678
- function toolkitRootType(checker, t) {
11679
- const [first] = elementsOf(t) ?? [t];
11680
- const decl = first?.getSymbol()?.declarations?.[0];
11681
- const root = decl && ts.isInterfaceDeclaration(decl) ? toolkitElement(decl) : void 0;
11682
- return root?.decl.name && checker.getTypeAtLocation(root.decl.name);
11683
- }
11684
- function ancestors(checker, decl) {
11685
- const out = [];
11686
- for (let c = decl; c && !out.includes(c); c = baseClass(checker, c)) out.push(c);
11687
- return out;
11688
- }
11689
- function baseClass(checker, c) {
11690
- const symbol = c.name && checker.getSymbolAtLocation(c.name);
11691
- if (!symbol) return void 0;
11692
- const type = checker.getDeclaredTypeOfSymbol(symbol);
11693
- const base = checker.getBaseTypes(type)[0]?.getSymbol()?.declarations?.[0];
11694
- return base && ts.isClassDeclaration(base) ? base : void 0;
11695
- }
11696
- function commonClass(checker, classes) {
11697
- const [first, ...rest] = classes;
11698
- const others = rest.map((c) => ancestors(checker, c));
11699
- return ancestors(checker, first).find((c) => others.every((a) => a.includes(c))) ?? first;
11700
- }
11701
- function returnedExpressions(checker, fn, platform) {
11702
- if (!fn.body) return [];
11703
- if (!ts.isBlock(fn.body)) return [fn.body];
11704
- const out = [];
11705
- const visit = (n) => {
11706
- if (ts.isFunctionLike(n)) return;
11707
- const branch = platform && branchPlatform(checker, n);
11708
- if (branch && branch !== platform) return;
11709
- if (ts.isReturnStatement(n) && n.expression) out.push(n.expression);
11710
- ts.forEachChild(n, visit);
11711
- };
11712
- ts.forEachChild(fn.body, visit);
11713
- return out;
11714
- }
11715
- //#endregion
11716
12418
  //#region ../compiler/src/types.ts
11717
12419
  const T = {
11718
12420
  number: { k: "number" },
@@ -13599,6 +14301,11 @@ function toolkitTypesPath(name) {
13599
14301
  return toolkitSource(name) ? path.join(SDK_ROOT, "toolkit", `${name}.d.ts`) : sdkLibPath(name);
13600
14302
  }
13601
14303
  const toolkitTexts = /* @__PURE__ */ new WeakMap();
14304
+ const sdkTexts = {
14305
+ plain: /* @__PURE__ */ new WeakMap(),
14306
+ jsx: /* @__PURE__ */ new WeakMap()
14307
+ };
14308
+ const stubTexts = /* @__PURE__ */ new WeakMap();
13602
14309
  function toolkitDeclarations(name) {
13603
14310
  const toolkit = TOOLKITS[name];
13604
14311
  const source = toolkitSource(name);
@@ -13636,11 +14343,26 @@ function virtualSdkText(file, direct) {
13636
14343
  const module = m[2];
13637
14344
  if (platform === "ios" && !direct.has(`${platform}/${module}`)) {
13638
14345
  const names = sdkNamesOf(platform, module);
13639
- return names ? stubDts(platform, module, names) : void 0;
14346
+ if (!names) return void 0;
14347
+ let stub = stubTexts.get(names);
14348
+ if (stub === void 0) stubTexts.set(names, stub = cachedDeclarations(sdkCacheDir(), currentSdkIdentity(), [
14349
+ "names",
14350
+ platform,
14351
+ module
14352
+ ], () => stubDts(platform, module, names)));
14353
+ return stub;
13640
14354
  }
13641
14355
  const schema = findSdkModule(platform, module);
13642
14356
  if (!schema) return void 0;
13643
- const text = sdkDts(schema);
14357
+ const jsx = fabricRequested();
14358
+ const texts = sdkTexts[jsx ? "jsx" : "plain"];
14359
+ let text = texts.get(schema);
14360
+ if (text === void 0) texts.set(schema, text = cachedDeclarations(sdkCacheDir(), currentSdkIdentity(), [
14361
+ "full",
14362
+ platform,
14363
+ module,
14364
+ ...jsx ? ["jsx"] : []
14365
+ ], () => sdkDts(schema, { jsx })));
13644
14366
  for (const r of text.matchAll(/^export \* from "lucent:(ios\/_\w+)";$/gm)) direct.add(r[1]);
13645
14367
  return text;
13646
14368
  }
@@ -13774,6 +14496,7 @@ function jsxRuntimeOf(specifier, file) {
13774
14496
  function jsxRuntimeText() {
13775
14497
  const typed = Object.keys(TOOLKITS).filter((t) => platformSdkTyped(TOOLKITS[t].platform));
13776
14498
  const elements = typed.map((t) => TOOLKITS[t].element);
14499
+ const { imports: rootImports, types: roots } = rootViews(PLATFORMS.filter((p) => platformSdkTyped(p)));
13777
14500
  return printUnit({
13778
14501
  banner: "The JSX of a shared Lucent file: each platform's toolkit's, in its code.",
13779
14502
  decls: [
@@ -13782,6 +14505,12 @@ function jsxRuntimeText() {
13782
14505
  names: [TOOLKITS[t].element],
13783
14506
  from: `lucent:${t}`
13784
14507
  })),
14508
+ {
14509
+ k: "importType",
14510
+ names: NATIVE_JSX_UI,
14511
+ from: "lucent:ui"
14512
+ },
14513
+ ...rootImports,
13785
14514
  {
13786
14515
  k: "namespace",
13787
14516
  name: "JSX",
@@ -13789,13 +14518,18 @@ function jsxRuntimeText() {
13789
14518
  {
13790
14519
  k: "typeAlias",
13791
14520
  name: "Element",
13792
- type: elements.length ? intersection(elements.map((e) => ref(e))) : keyword$1("unknown")
14521
+ type: elements.length || roots.length ? intersection([...elements.map((e) => ref(e)), ...roots]) : keyword$1("unknown")
13793
14522
  },
13794
14523
  {
13795
14524
  k: "typeAlias",
13796
14525
  name: "ElementType",
13797
- type: union$1([...elements.map((e) => fn$3([param$2("props", keyword$1("never"))], ref(e))), ...typed.length < Object.keys(TOOLKITS).length ? [fn$3([param$2("props", keyword$1("never"))], keyword$1("unknown"))] : []])
14526
+ type: union$1([
14527
+ ...elements.map((e) => fn$3([param$2("props", keyword$1("never"))], ref(e))),
14528
+ ...typed.length < Object.keys(TOOLKITS).length ? [fn$3([param$2("props", keyword$1("never"))], keyword$1("unknown"))] : [],
14529
+ ...nativeTags(roots)
14530
+ ])
13798
14531
  },
14532
+ ...nativeJsxDecls(),
13799
14533
  {
13800
14534
  k: "interface",
13801
14535
  name: "ElementChildrenAttribute",
@@ -13823,7 +14557,8 @@ function createLucentProgram(files, readSource, platform, extra = {}) {
13823
14557
  ...compilerOptions(),
13824
14558
  skipLibCheck: !extra.libCheck
13825
14559
  };
13826
- const host = compilerHost(options, readSource, directSdkImports(files, readSource));
14560
+ const direct = directSdkImports(files, readSource);
14561
+ const host = compilerHost(options, readSource, direct);
13827
14562
  const program = ts.createProgram([
13828
14563
  ...files.map((f) => path.resolve(f)),
13829
14564
  ...references.map((f) => path.resolve(f)),
@@ -13864,7 +14599,13 @@ function createLucentProgram(files, readSource, platform, extra = {}) {
13864
14599
  diagnostics.push(...bad);
13865
14600
  for (const d of [...program.getSyntacticDiagnostics(sf), ...program.getSemanticDiagnostics(sf)]) {
13866
14601
  if (d.code === 2307 && bad.some((b) => b.start !== void 0 && d.start !== void 0 && d.start >= b.start && d.start < b.start + (b.length ?? 0))) continue;
13867
- diagnostics.push(fromTs(d));
14602
+ const hint = nativeMemberHint(d, checker, direct) ?? nativeAttributeHint(d, checker) ?? initializerFactoryHint(d, checker) ?? inheritedInitializerHint(d, checker, direct);
14603
+ const diagnostic = fromTs(d);
14604
+ diagnostics.push(hint ? {
14605
+ ...diagnostic,
14606
+ message: `${diagnostic.message} ${hint.message}`,
14607
+ fix: hint.fix
14608
+ } : diagnostic);
13868
14609
  }
13869
14610
  }
13870
14611
  return {
@@ -13875,6 +14616,129 @@ function createLucentProgram(files, readSource, platform, extra = {}) {
13875
14616
  diagnostics
13876
14617
  };
13877
14618
  }
14619
+ const MISSING_MEMBER = /* @__PURE__ */ new Set([2339, 2551]);
14620
+ function nativeMemberHint(d, checker, direct) {
14621
+ if (!MISSING_MEMBER.has(d.code) || !d.file || d.start === void 0) return void 0;
14622
+ const name = nodeAt(d.file, d.start);
14623
+ const access = name.parent;
14624
+ if (!ts.isIdentifier(name) || !access || !ts.isPropertyAccessExpression(access)) return void 0;
14625
+ const type = checker.getTypeAtLocation(access.expression);
14626
+ const symbol = type.getSymbol() ?? type.aliasSymbol;
14627
+ const declared = symbol?.declarations?.[0]?.getSourceFile();
14628
+ const sdk = declared && sdkModuleOf(declared);
14629
+ if (!symbol || !sdk) return void 0;
14630
+ const spec = `lucent:${sdk.platform}/${sdk.module}`;
14631
+ if (sdk.platform === "ios" && !direct.has(`${sdk.platform}/${sdk.module}`)) return {
14632
+ message: `${symbol.name} is ${spec}'s, which no file imports: only its name is known.`,
14633
+ fix: `import from ${spec} (a type import is enough) to use ${symbol.name}'s members`
14634
+ };
14635
+ const found = sdkLookup(sdk.platform, sdk.module);
14636
+ const schema = "schema" in found ? found.schema : void 0;
14637
+ const provenance = schema?.provenance;
14638
+ if (!schema || !provenance) return void 0;
14639
+ const skipped = skippedMember(schema, symbol.name, name.text);
14640
+ if (skipped) return {
14641
+ message: `${skipped.api} is in ${provenance.artifact}, but Lucent does not bind it: ${skipped.reason}.`,
14642
+ fix: WRAP_UNBOUND[sdk.platform]
14643
+ };
14644
+ if (provenance.kind === "sdk") return void 0;
14645
+ return {
14646
+ message: `${symbol.name} is ${spec}'s, from ${provenance.artifact} as installed, which has no ${name.text}.`,
14647
+ fix: `use what ${symbol.name} declares in this version of ${sdk.module}, or install a version that has ${name.text}`
14648
+ };
14649
+ }
14650
+ const PROTECTED_CONSTRUCTOR = 2674;
14651
+ function inheritedInitializerHint(d, checker, direct) {
14652
+ if (d.code !== PROTECTED_CONSTRUCTOR && !NO_OVERLOAD.has(d.code)) return void 0;
14653
+ if (!d.file || d.start === void 0) return void 0;
14654
+ let at = nodeAt(d.file, d.start);
14655
+ while (at && !ts.isNewExpression(at)) at = at.parent;
14656
+ if (!at || !ts.isNewExpression(at)) return void 0;
14657
+ const named = checker.getSymbolAtLocation(at.expression);
14658
+ const symbol = named && named.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(named) : named;
14659
+ const declared = symbol?.declarations?.[0]?.getSourceFile();
14660
+ const sdk = declared && sdkModuleOf(declared);
14661
+ if (!symbol || !sdk) return void 0;
14662
+ let module = sdk.module;
14663
+ let name = symbol.name;
14664
+ for (let depth = 0; depth < 32; depth++) {
14665
+ const found = sdkLookup(sdk.platform, module);
14666
+ const cls = "schema" in found ? found.schema.types.find((t) => t.kind === "class" && t.name === name) : void 0;
14667
+ if (cls?.kind !== "class" || cls.constructors?.length || !cls.inheritsInit || !cls.extends) break;
14668
+ const up = parseSdkType(cls.extends, module);
14669
+ if (up.k !== "ref") break;
14670
+ [module, name] = [up.module, up.name];
14671
+ const spec = `lucent:${sdk.platform}/${module}`;
14672
+ if (module !== sdk.module && !direct.has(`${sdk.platform}/${module}`)) return {
14673
+ message: `${symbol.name}'s initializers are ${name}'s, inherited from ${spec}, which no file imports: only its name is known.`,
14674
+ fix: `import "${spec}" (a bare import is enough) to make a ${symbol.name} with ${name}'s initializers`
14675
+ };
14676
+ }
14677
+ }
14678
+ const NO_OVERLOAD = /* @__PURE__ */ new Set([
14679
+ 2554,
14680
+ 2769,
14681
+ 2345
14682
+ ]);
14683
+ function initializerFactoryHint(d, checker) {
14684
+ if (!NO_OVERLOAD.has(d.code) || !d.file || d.start === void 0) return void 0;
14685
+ let at = nodeAt(d.file, d.start);
14686
+ while (at && !ts.isNewExpression(at)) at = at.parent;
14687
+ if (!at || !ts.isNewExpression(at)) return void 0;
14688
+ const named = checker.getSymbolAtLocation(at.expression);
14689
+ const symbol = named && named.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(named) : named;
14690
+ const declared = symbol?.declarations?.[0]?.getSourceFile();
14691
+ const sdk = declared && sdkModuleOf(declared);
14692
+ if (!symbol || !sdk) return void 0;
14693
+ const found = sdkLookup(sdk.platform, sdk.module);
14694
+ const cls = "schema" in found ? found.schema.types.find((t) => t.kind === "class" && t.name === symbol.name) : void 0;
14695
+ const factories = cls?.kind === "class" ? (cls.methods ?? []).filter((m) => m.static && m.swift?.name.startsWith("init(")) : [];
14696
+ if (!factories.length) return void 0;
14697
+ const listed = factories.map((f) => `${symbol.name}.${f.name}(…) for ${f.swift.name}`);
14698
+ return {
14699
+ message: `${symbol.name}'s initializers that take the same types are its static factories, which TypeScript tells apart: ${listed.join(", ")}.`,
14700
+ fix: `call the one you mean: ${symbol.name}.${factories[0].name}(…)`
14701
+ };
14702
+ }
14703
+ function skippedMember(schema, owner, member) {
14704
+ for (const entry of schema.skipped ?? []) {
14705
+ const at = entry.indexOf(": ");
14706
+ const api = entry.slice(0, at);
14707
+ const [type, name] = api.split("(")[0].split(/\.(?=[^.]*$)/);
14708
+ if (name === member && (type === owner || type?.endsWith(`.${owner}`))) return {
14709
+ api,
14710
+ reason: entry.slice(at + 2)
14711
+ };
14712
+ }
14713
+ }
14714
+ function nativeAttributeHint(d, checker) {
14715
+ if (!MISSING_ATTRIBUTE.has(d.code) || !d.file || d.start === void 0) return void 0;
14716
+ let element = nodeAt(d.file, d.start);
14717
+ while (element && !ts.isJsxOpeningElement(element) && !ts.isJsxSelfClosingElement(element)) element = element.parent;
14718
+ if (!element) return void 0;
14719
+ const decl = nativeTagType(checker, ts.isJsxOpeningElement(element) ? element.parent : element)?.getSymbol()?.declarations?.[0];
14720
+ const ref = decl && classOfDecl(decl);
14721
+ const schema = ref && findSdkModule(ref.platform, ref.module);
14722
+ if (!ref || !schema) return void 0;
14723
+ const tag = viewTag(ref.cls, schema, (m) => findSdkModule(ref.platform, m));
14724
+ for (const a of element.attributes.properties) {
14725
+ const name = ts.isJsxAttribute(a) ? a.name.getText() : void 0;
14726
+ const reason = name && tag.refused.get(name);
14727
+ if (reason) return {
14728
+ message: `<${ref.cls.name}> does not take ${name}: ${reason}.`,
14729
+ fix: `call it in setup code, on the view made with create={() => new ${ref.cls.name}(…)}`
14730
+ };
14731
+ }
14732
+ }
14733
+ const MISSING_ATTRIBUTE = /* @__PURE__ */ new Set([2322, 2769]);
14734
+ function nodeAt(sf, pos) {
14735
+ let node = sf;
14736
+ for (let inner = sf; inner;) {
14737
+ node = inner;
14738
+ inner = ts.forEachChild(node, (c) => c.getStart(sf) <= pos && pos < c.getEnd() ? c : void 0);
14739
+ }
14740
+ return node;
14741
+ }
13878
14742
  function importDiagnostics(sf, platform) {
13879
14743
  const shared = !platformOf(sf.fileName);
13880
14744
  const out = [];
@@ -14026,6 +14890,12 @@ function conformsByRoot(checker, impl, declared) {
14026
14890
  const typeOf = (p) => checker.getTypeOfSymbolAtLocation(p, p.valueDeclaration ?? p.declarations[0]);
14027
14891
  return checker.isTypeAssignableTo(root, checker.getReturnTypeOfSignature(d)) && i.parameters.every((p, k) => checker.isTypeAssignableTo(typeOf(d.parameters[k]), typeOf(p)));
14028
14892
  }
14893
+ function described(checker, t) {
14894
+ const [sig, ...more] = t.getCallSignatures();
14895
+ const elements = sig && !more.length ? elementsOf(sig.getReturnType()) : void 0;
14896
+ if (!sig || !elements) return checker.typeToString(t);
14897
+ return `(${sig.parameters.map((p) => `${p.name}: ${checker.typeToString(checker.getTypeOfSymbol(p))}`).join(", ")}) => ${elements.map((e) => checker.typeToString(e)).join(" & ")}`;
14898
+ }
14029
14899
  function conformanceErrors(lp) {
14030
14900
  const checker = lp.checker;
14031
14901
  const out = [];
@@ -14056,7 +14926,7 @@ function conformanceErrors(lp) {
14056
14926
  if (!decl || !declared) continue;
14057
14927
  const implType = checker.getTypeOfSymbolAtLocation(i, decl);
14058
14928
  const declType = checker.getTypeOfSymbolAtLocation(d, declared);
14059
- if (!checker.isTypeAssignableTo(implType, declType) && !conformsByRoot(checker, implType, declType)) out.push(at$2(decl, `${d.name} in ${implName} has type ${checker.typeToString(implType)}, which does not match ${checker.typeToString(declType)} declared in ${declName}`));
14929
+ if (!checker.isTypeAssignableTo(implType, declType) && !conformsByRoot(checker, implType, declType)) out.push(at$2(decl, `${d.name} in ${implName} has type ${described(checker, implType)}, which does not match ${checker.typeToString(declType)} declared in ${declName}`));
14060
14930
  }
14061
14931
  for (const extra of impl.values()) {
14062
14932
  const decl = extra.valueDeclaration ?? extra.declarations?.[0];
@@ -14320,11 +15190,7 @@ function inUntypedPlatformCode(lp, d, untyped) {
14320
15190
  if (d.code !== Codes.TypeScript || !d.file || d.start === void 0 || !untyped.length || platformOf(d.file)) return false;
14321
15191
  const sf = lp.program.getSourceFile(path.resolve(d.file));
14322
15192
  if (!sf) return false;
14323
- let node = sf;
14324
- for (let inner = sf; inner;) {
14325
- node = inner;
14326
- inner = ts.forEachChild(node, (c) => c.getStart(sf) <= d.start && d.start < c.getEnd() ? c : void 0);
14327
- }
15193
+ const node = nodeAt(sf, d.start);
14328
15194
  const stmt = sf.statements.find((s) => s.getStart(sf) <= d.start && d.start < s.getEnd());
14329
15195
  const p = (ts.isIdentifier(node) ? importedFrom(sf, node.text) : void 0) ?? branchPlatform(lp.checker, node) ?? (stmt ? platformScopes(lp.checker, sf).platforms.get(stmt) : void 0);
14330
15196
  return !!p && untyped.includes(p);
@@ -14342,6 +15208,179 @@ function importedFrom(sf, name) {
14342
15208
  }
14343
15209
  }
14344
15210
  //#endregion
15211
+ //#region ../compiler/src/ui/roots.ts
15212
+ const ROOT_VIEWS = {
15213
+ ios: {
15214
+ module: "UIKit",
15215
+ name: "UIView"
15216
+ },
15217
+ android: {
15218
+ module: "android.view",
15219
+ name: "View"
15220
+ }
15221
+ };
15222
+ const SLOT_VIEWS = {
15223
+ ios: {
15224
+ module: "UIKit",
15225
+ name: "UIView"
15226
+ },
15227
+ android: {
15228
+ module: "android.view",
15229
+ name: "ViewGroup"
15230
+ }
15231
+ };
15232
+ const sdkClassOf = (classes) => (decl) => {
15233
+ const sdk = sdkModuleOf(decl.getSourceFile());
15234
+ const found = sdk && classes[sdk.platform];
15235
+ return found && found.module === sdk.module && decl.name?.text === found.name ? sdk.platform : void 0;
15236
+ };
15237
+ function toolkitOf(root) {
15238
+ const toolkit = toolkitOfModule(root.module);
15239
+ return toolkit && TOOLKITS[toolkit].root === root.name ? toolkit : void 0;
15240
+ }
15241
+ const sdkRootView = sdkClassOf(ROOT_VIEWS);
15242
+ const sdkRoot = (decl) => {
15243
+ const builtin = builtinSdkModuleOf(decl.getSourceFile());
15244
+ const toolkit = builtin && toolkitOf({
15245
+ module: builtin,
15246
+ name: decl.name?.text ?? ""
15247
+ });
15248
+ return toolkit ? TOOLKITS[toolkit].platform : sdkRootView(decl);
15249
+ };
15250
+ const sdkSlot = sdkClassOf(SLOT_VIEWS);
15251
+ function returnShape(checker, fn, platform, rootOf) {
15252
+ const signature = checker.getSignatureFromDeclaration(fn);
15253
+ const declared = signature ? checker.getReturnTypeOfSignature(signature) : void 0;
15254
+ const promised = declared && promisedType(checker, declared);
15255
+ const viewOf = (t) => viewClass(checker, t, rootOf);
15256
+ const isView = (t) => {
15257
+ const found = viewOf(t);
15258
+ return found && (!platform || found.platform === platform) ? found.decl : void 0;
15259
+ };
15260
+ if (promised) return members(promised).some(isView) ? { kind: "promised" } : { kind: "value" };
15261
+ const returned = returnedExpressions(checker, fn, platform).map((e) => nativeTagType(checker, e) ?? checker.getTypeAtLocation(e));
15262
+ const types = (fn.body ? returned : declared ? [declared] : []).flatMap(members);
15263
+ const views = [];
15264
+ let other;
15265
+ let viewName = "";
15266
+ for (const t of types) {
15267
+ if (t.flags & ts.TypeFlags.Any || viewOf(t) && !isView(t)) continue;
15268
+ const cls = isView(t);
15269
+ if (cls) {
15270
+ views.push(cls);
15271
+ viewName ||= checker.typeToString(t);
15272
+ } else other ??= checker.typeToString(t);
15273
+ }
15274
+ if (!views.length) return { kind: "value" };
15275
+ if (other !== void 0) return {
15276
+ kind: "ambiguous",
15277
+ view: viewName,
15278
+ other
15279
+ };
15280
+ return {
15281
+ kind: "view",
15282
+ root: commonClass(checker, views)
15283
+ };
15284
+ }
15285
+ function classIdentity(checker, returned) {
15286
+ const decl = ancestors(checker, returned).find((c) => c.getSourceFile().isDeclarationFile) ?? returned;
15287
+ const sf = decl.getSourceFile();
15288
+ return {
15289
+ module: sdkModuleOf(sf)?.module ?? builtinSdkModuleOf(sf) ?? path.basename(sf.fileName, ".d.ts"),
15290
+ name: decl.name?.text ?? ""
15291
+ };
15292
+ }
15293
+ function members(t) {
15294
+ return t.isUnion() ? t.types.flatMap(members) : elementsOf(t) ?? [t];
15295
+ }
15296
+ function elementsOf(t) {
15297
+ if (!t.isIntersection()) return void 0;
15298
+ const declOf = (m) => m.getSymbol()?.declarations?.[0];
15299
+ const elements = t.types.filter((m) => {
15300
+ const decl = declOf(m);
15301
+ return !!decl && ts.isInterfaceDeclaration(decl) && !!toolkitElement(decl);
15302
+ });
15303
+ const views = t.types.filter((m) => !elements.includes(m)).every((m) => {
15304
+ const decl = declOf(m);
15305
+ return !!decl && ts.isClassDeclaration(decl) && !!sdkRootView(decl);
15306
+ });
15307
+ return elements.length && views ? elements : void 0;
15308
+ }
15309
+ function nativeTagType(checker, e) {
15310
+ let jsx = e;
15311
+ while (ts.isParenthesizedExpression(jsx)) jsx = jsx.expression;
15312
+ const tag = ts.isJsxElement(jsx) ? jsx.openingElement.tagName : ts.isJsxSelfClosingElement(jsx) ? jsx.tagName : void 0;
15313
+ const symbol = tag && checker.getSymbolAtLocation(tag);
15314
+ const target = symbol && symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
15315
+ const decl = target?.declarations?.[0];
15316
+ return decl && ts.isClassDeclaration(decl) ? checker.getDeclaredTypeOfSymbol(target) : void 0;
15317
+ }
15318
+ function promisedType(checker, t) {
15319
+ const name = t.getSymbol()?.getName();
15320
+ if (name !== "Promise" && name !== "PromiseLike") return void 0;
15321
+ return checker.getTypeArguments(t)[0];
15322
+ }
15323
+ function viewClass(checker, t, rootOf) {
15324
+ const decl = t.getSymbol()?.declarations?.[0];
15325
+ if (decl && ts.isInterfaceDeclaration(decl)) return toolkitElement(decl);
15326
+ if (!decl || !ts.isClassDeclaration(decl)) return void 0;
15327
+ for (const c of ancestors(checker, decl)) {
15328
+ const platform = rootOf(c);
15329
+ if (platform) return {
15330
+ decl,
15331
+ platform
15332
+ };
15333
+ }
15334
+ }
15335
+ function toolkitElement(decl) {
15336
+ const sf = decl.getSourceFile();
15337
+ const name = toolkitOfModule(builtinSdkModuleOf(sf));
15338
+ const found = name && toolkit(name);
15339
+ if (!found || found.element !== decl.name.text) return void 0;
15340
+ const root = sf.statements.find((s) => ts.isClassDeclaration(s) && s.name?.text === found.root);
15341
+ return root && {
15342
+ decl: root,
15343
+ platform: found.platform
15344
+ };
15345
+ }
15346
+ function toolkitRootType(checker, t) {
15347
+ const [first] = elementsOf(t) ?? [t];
15348
+ const decl = first?.getSymbol()?.declarations?.[0];
15349
+ const root = decl && ts.isInterfaceDeclaration(decl) ? toolkitElement(decl) : void 0;
15350
+ return root?.decl.name && checker.getTypeAtLocation(root.decl.name);
15351
+ }
15352
+ function ancestors(checker, decl) {
15353
+ const out = [];
15354
+ for (let c = decl; c && !out.includes(c); c = baseClass(checker, c)) out.push(c);
15355
+ return out;
15356
+ }
15357
+ function baseClass(checker, c) {
15358
+ const symbol = c.name && checker.getSymbolAtLocation(c.name);
15359
+ if (!symbol) return void 0;
15360
+ const type = checker.getDeclaredTypeOfSymbol(symbol);
15361
+ const base = checker.getBaseTypes(type)[0]?.getSymbol()?.declarations?.[0];
15362
+ return base && ts.isClassDeclaration(base) ? base : void 0;
15363
+ }
15364
+ function commonClass(checker, classes) {
15365
+ const [first, ...rest] = classes;
15366
+ const others = rest.map((c) => ancestors(checker, c));
15367
+ return ancestors(checker, first).find((c) => others.every((a) => a.includes(c))) ?? first;
15368
+ }
15369
+ function returnedExpressions(checker, fn, platform) {
15370
+ if (!fn.body) return [];
15371
+ if (!ts.isBlock(fn.body)) return [fn.body];
15372
+ const out = [];
15373
+ const visit = (n) => {
15374
+ if (ts.isFunctionLike(n)) return;
15375
+ const branch = platform && branchPlatform(checker, n);
15376
+ if (branch && branch !== platform) return;
15377
+ if (ts.isReturnStatement(n) && n.expression) out.push(n.expression);
15378
+ ts.forEachChild(n, visit);
15379
+ };
15380
+ ts.forEachChild(fn.body, visit);
15381
+ return out;
15382
+ }
15383
+ //#endregion
14345
15384
  //#region ../compiler/src/ui/compose-api.ts
14346
15385
  const KINDS = {
14347
15386
  double: "Double",
@@ -14723,6 +15762,8 @@ function shownToolkit(node, checker, seen = /* @__PURE__ */ new Set()) {
14723
15762
  function bodyOf(fn, name, checker) {
14724
15763
  const { title, platform } = TOOLKITS[name];
14725
15764
  const refused = `a ${title} component returns its body: JSX of ${title}'s views, which the setup's last statement returns`;
15765
+ const native = nativeJsxIn(fn, checker);
15766
+ if (native) fail$2(native, Codes.NativeViewJsx, "JSX of native views is what a component returns: return it, as the last statement of the component");
14726
15767
  if (fn.body && !ts.isBlock(fn.body)) {
14727
15768
  if (jsxRoot(fn.body)) return fn.body;
14728
15769
  bodyFail(fn.body, refused);
@@ -14757,6 +15798,19 @@ function isUiForm(checker, call, name) {
14757
15798
  const decl = ts.isIdentifier(callee) ? symbolOf$1(checker, callee)?.declarations?.[0] : void 0;
14758
15799
  return !!decl && ts.isFunctionDeclaration(decl) && decl.name?.text === name && builtinSdkModuleOf(decl.getSourceFile()) === "lucent:ui";
14759
15800
  }
15801
+ function nativeJsxIn(fn, checker) {
15802
+ let found;
15803
+ const visit = (n) => {
15804
+ if (found || n !== fn && ts.isFunctionLike(n)) return;
15805
+ if ((ts.isJsxElement(n) || ts.isJsxSelfClosingElement(n)) && nativeTagType(checker, n)) {
15806
+ found = n;
15807
+ return;
15808
+ }
15809
+ ts.forEachChild(n, visit);
15810
+ };
15811
+ if (fn.body) visit(fn.body);
15812
+ return found;
15813
+ }
14760
15814
  const isBind = (checker, call) => isUiForm(checker, call, "bind");
14761
15815
  function inSetupCode(node, setup) {
14762
15816
  for (let n = node.parent; n; n = n.parent) if (ts.isFunctionLike(n)) return n === setup;
@@ -15661,6 +16715,7 @@ const LIBRARY = {
15661
16715
  },
15662
16716
  "lucent:android.appContext": NONE,
15663
16717
  "lucent:android.available": NONE,
16718
+ "lucent:android.errorOf": ALLOCATES,
15664
16719
  "lucent:ios.available": NONE,
15665
16720
  "lucent:ui.effect": {
15666
16721
  allocates: true,
@@ -16531,6 +17586,17 @@ var Collector = class Collector {
16531
17586
  return !!(decl && this.p.units.byNode.get(decl))?.generator;
16532
17587
  }
16533
17588
  jsx(e) {
17589
+ if (!ts.isJsxFragment(e) && nativeTagType(this.checker, e)) {
17590
+ const opening = ts.isJsxElement(e) ? e.openingElement : e;
17591
+ for (const a of opening.attributes.properties) {
17592
+ const value = ts.isJsxAttribute(a) ? a.initializer && ts.isJsxExpression(a.initializer) ? a.initializer.expression : void 0 : a.expression;
17593
+ if (value) this.expr(value);
17594
+ }
17595
+ for (const c of ts.isJsxElement(e) ? e.children : []) if (ts.isJsxExpression(c) && c.expression) this.expr(c.expression);
17596
+ else if (!ts.isJsxText(c)) this.expr(c);
17597
+ this.own("allocates", "yes", e, "makes native views");
17598
+ return this.made(e, "fresh");
17599
+ }
16534
17600
  if (!jsxToolkitOf(e, this.checker)) return this.unmodeled(e, ts.isJsxFragment(e) ? "a JSX fragment" : "a JSX element");
16535
17601
  this.own("allocates", "yes", e, "makes a toolkit's body");
16536
17602
  return this.made(e, "fresh");
@@ -17158,104 +18224,6 @@ function useOf$1(f, decl) {
17158
18224
  };
17159
18225
  }
17160
18226
  //#endregion
17161
- //#region ../compiler/src/sdk/declarations.ts
17162
- function classOfDecl(decl) {
17163
- const sdk = sdkModuleOf(decl.getSourceFile());
17164
- if (!sdk) return void 0;
17165
- const owner = ts.isClassDeclaration(decl) ? decl : decl.parent;
17166
- if (!owner || !ts.isClassDeclaration(owner) || !owner.name) return void 0;
17167
- const cls = findSdkType(sdk.platform, sdk.module, owner.name.text);
17168
- return cls?.kind === "class" ? {
17169
- ...sdk,
17170
- cls
17171
- } : void 0;
17172
- }
17173
- function sdkInterfacesOf(checker, decl) {
17174
- const out = [];
17175
- for (const h of decl.heritageClauses ?? []) {
17176
- if (h.token !== ts.SyntaxKind.ImplementsKeyword) continue;
17177
- for (const t of h.types) {
17178
- const d = checker.getTypeAtLocation(t).getSymbol()?.declarations?.find(ts.isClassDeclaration);
17179
- const ref = d ? classOfDecl(d) : void 0;
17180
- if (ref?.cls.interface) out.push(ref);
17181
- }
17182
- }
17183
- return out;
17184
- }
17185
- function requirementOf(checker, m) {
17186
- const cls = m.parent;
17187
- if (!ts.isClassLike(cls) || !ts.isIdentifier(m.name)) return void 0;
17188
- for (const protocol of sdkInterfacesOf(checker, cls)) {
17189
- const method = protocol.cls.methods?.find((x) => !x.static && x.name === m.name.text);
17190
- if (method) return {
17191
- protocol,
17192
- method,
17193
- main: !!(protocol.cls.mainActor || method.mainActor)
17194
- };
17195
- }
17196
- }
17197
- function schemaMethod(ref, decl) {
17198
- const inherited = inheritedFrom(ref, decl);
17199
- if (inherited) return {
17200
- ref: inherited.ref,
17201
- method: inherited.ref.cls.methods[inherited.index],
17202
- promise: false
17203
- };
17204
- const name = decl.name.text;
17205
- const index = decl.parent.members.filter((m) => ts.isMethodDeclaration(m) && m.name.text === name).indexOf(decl);
17206
- return (ref.cls.methods ?? []).flatMap((m) => [...m.name === name ? [{
17207
- ref,
17208
- method: m,
17209
- promise: false
17210
- }] : [], ...m.async && declaresPromise(ref.cls, m) && (m.async.name ?? m.name) === name ? [{
17211
- ref,
17212
- method: m,
17213
- promise: true
17214
- }] : []])[index];
17215
- }
17216
- function schemaProperty(ref, decl) {
17217
- const inherited = inheritedFrom(ref, decl);
17218
- if (inherited) return {
17219
- ref: inherited.ref,
17220
- property: inherited.ref.cls.properties[inherited.index]
17221
- };
17222
- const name = decl.name.text;
17223
- const isStatic = !!ts.getModifiers(decl)?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword);
17224
- const property = ref.cls.properties?.find((p) => p.name === name && !!p.static === isStatic);
17225
- return property ? {
17226
- ref,
17227
- property
17228
- } : void 0;
17229
- }
17230
- function inheritedFrom(ref, decl) {
17231
- const tag = ts.getJSDocTags(decl).find((t) => `@${t.tagName.text}` === INHERITED_TAG);
17232
- if (!tag) return void 0;
17233
- const [owner, index] = (ts.getTextOfJSDocComment(tag.comment) ?? "").split(" ");
17234
- const dot = owner.lastIndexOf(".");
17235
- const module = owner.slice(0, dot);
17236
- const cls = findSdkType(ref.platform, module, owner.slice(dot + 1));
17237
- if (cls?.kind !== "class") throw new Error(`${owner}: no class for an inherited member`);
17238
- return {
17239
- ref: {
17240
- ...ref,
17241
- module,
17242
- cls
17243
- },
17244
- index: Number(index)
17245
- };
17246
- }
17247
- function schemaConstructor(ref, decl) {
17248
- return ref.cls.constructors[decl.parent.members.filter(ts.isConstructorDeclaration).indexOf(decl)];
17249
- }
17250
- function promiseForm(m) {
17251
- const { throws: _, ...rest } = m;
17252
- return {
17253
- ...rest,
17254
- params: m.params.slice(0, -1),
17255
- returns: m.async.returns
17256
- };
17257
- }
17258
- //#endregion
17259
18227
  //#region ../compiler/src/analysis/native.ts
17260
18228
  const NO_NATIVE = {
17261
18229
  use: () => void 0,
@@ -17280,6 +18248,7 @@ const COPIED$1 = /* @__PURE__ */ new Set([
17280
18248
  "copy-array",
17281
18249
  "copy-record",
17282
18250
  "copy-set",
18251
+ "copy-tuple",
17283
18252
  "copy-date"
17284
18253
  ]);
17285
18254
  function callbackOf$1(plan) {
@@ -17376,7 +18345,7 @@ function classMemberPlan(ref, decl, role) {
17376
18345
  return memberPlan(owner.platform, owner.module, owner.cls, promise ? promiseForm(method) : method, "call");
17377
18346
  }
17378
18347
  if (ts.isConstructorDeclaration(decl)) return memberPlan(ref.platform, ref.module, ref.cls, schemaConstructor(ref, decl), "new");
17379
- if (!ts.isPropertyDeclaration(decl) || !ts.isIdentifier(decl.name)) return void 0;
18348
+ if (!isSdkPropertyDecl(decl) || !ts.isIdentifier(decl.name)) return void 0;
17380
18349
  const found = schemaProperty(ref, decl);
17381
18350
  if (!found) return void 0;
17382
18351
  const { ref: owner, property } = found;
@@ -20044,10 +21013,12 @@ var Lowerer = class Lowerer {
20044
21013
  if (node.flags & ts.NodeFlags.OptionalChain) this.unsupported(node, "optional chains");
20045
21014
  const { operands, args } = this.operands();
20046
21015
  const place = host.place(node, operands);
21016
+ const assign = place.assign;
20047
21017
  return {
20048
21018
  type: place.type,
20049
21019
  read: () => this.planOf(place.get, args, spanOf(node)),
20050
- write: (v, span) => void this.planOf(place.set(v), [...args, v], span)
21020
+ write: (v, span) => void this.planOf(place.set(v), [...args, v], span),
21021
+ ...assign ? { assign: (v, span) => void this.planOf(assign(v, this.b.typeOf(v)), [...args, v], span) } : {}
20051
21022
  };
20052
21023
  }
20053
21024
  asserted(node) {
@@ -20703,6 +21674,11 @@ const BINARY_FORMS = {
20703
21674
  return value;
20704
21675
  }
20705
21676
  const target = lw.target(n.left);
21677
+ if (target.assign) {
21678
+ const value = lw.expr(n.right);
21679
+ target.assign(value, spanOf(n));
21680
+ return value;
21681
+ }
20706
21682
  const value = lw.expr(n.right, target.type);
20707
21683
  target.write(lw.coerce(value, target.type, n.right), spanOf(n));
20708
21684
  return value;
@@ -22168,6 +23144,7 @@ var Ctx = class {
22168
23144
  platform;
22169
23145
  frameworks = /* @__PURE__ */ new Set();
22170
23146
  pods = /* @__PURE__ */ new Set();
23147
+ swiftPackages = /* @__PURE__ */ new Set();
22171
23148
  javaClasses = /* @__PURE__ */ new Set();
22172
23149
  androidPermissions = /* @__PURE__ */ new Set();
22173
23150
  nativeUnits = /* @__PURE__ */ new Map();
@@ -22771,6 +23748,38 @@ function suspending(p, module) {
22771
23748
  function anyFor(name, bounds) {
22772
23749
  return bounds?.[name] === "non-null" ? type$3("Any") : nullable$1(type$3("Any"));
22773
23750
  }
23751
+ function boundType(ref) {
23752
+ const named = type$3(ref.name, ...(ref.args ?? []).map((a) => a === "*" ? star : boundType(a)));
23753
+ return ref.nullable ? nullable$1(named) : named;
23754
+ }
23755
+ function declaredTypeParams(use) {
23756
+ const classFacts = use.cls.kotlin;
23757
+ const memberFacts = use.member.kotlin;
23758
+ const classParams = use.cls.typeParams ?? [];
23759
+ const memberParams = "typeParams" in use.member ? use.member.typeParams ?? [] : [];
23760
+ const other = (f) => Object.keys(f?.upperBounds ?? {}).length > 0;
23761
+ if (!other(classFacts) && !other(memberFacts)) return {
23762
+ names: [],
23763
+ bounds: {}
23764
+ };
23765
+ const fromClass = use.instance || use.role === "new" ? classParams : [];
23766
+ const clash = memberParams.find((n) => fromClass.includes(n));
23767
+ if (clash) fail$2(use.node, Codes.UnsupportedCall, `${use.what}: its type parameter ${clash} shadows its class's, which a shim cannot declare twice`);
23768
+ const bounds = {};
23769
+ const bind = (names, f) => {
23770
+ for (const n of names) {
23771
+ const upper = f?.upperBounds?.[n];
23772
+ if (upper) bounds[n] = upper.map(boundType);
23773
+ else if (f?.bounds?.[n] === "non-null") bounds[n] = [type$3("Any")];
23774
+ }
23775
+ };
23776
+ bind(fromClass, classFacts);
23777
+ bind(memberParams, memberFacts);
23778
+ return {
23779
+ names: [...fromClass, ...memberParams],
23780
+ bounds
23781
+ };
23782
+ }
22774
23783
  function boundary(t) {
22775
23784
  const prim = primOf(t);
22776
23785
  return prim ? {
@@ -22796,6 +23805,7 @@ function kotlinType$1(use, t) {
22796
23805
  return of ? type$3(`kotlin.${of.kotlin}Array`) : type$3("kotlin.Array", kotlinType$1(use, t.of));
22797
23806
  }
22798
23807
  case "tparam": {
23808
+ if (declaredTypeParams(use).names.includes(t.name)) return type$3(t.name);
22799
23809
  const own = "typeParams" in use.member && use.member.typeParams?.includes(t.name);
22800
23810
  return anyFor(t.name, own ? use.member.kotlin?.bounds : use.cls.kotlin?.bounds);
22801
23811
  }
@@ -22831,7 +23841,8 @@ function kotlinShim(ctx, use) {
22831
23841
  memberName,
22832
23842
  use.given.map((g, i) => g ? use.wrapped[i] ? "f" : 1 : 0).join("")
22833
23843
  ].join("|");
22834
- const name = `${use.cls.name}_${use.role === "get" ? `get_${memberName}` : memberName}_${hashOf(key)}`;
23844
+ const accessor = use.role === "get" || use.role === "set" ? `${use.role}_` : "";
23845
+ const name = `${use.cls.name}_${accessor}${memberName}_${hashOf(key)}`;
22835
23846
  const shims = ctx.kotlinShims.get(use.module) ?? /* @__PURE__ */ new Map();
22836
23847
  ctx.kotlinShims.set(use.module, shims);
22837
23848
  const made = shims.get(name);
@@ -22850,6 +23861,7 @@ function kotlinShim(ctx, use) {
22850
23861
  const receiverType = (extension ? params[0] : void 0)?.type;
22851
23862
  if (use.instance) take("receiver", "receiver");
22852
23863
  else if (receiverType) take("receiver", primOf(receiverType) ? receiverType : "receiver");
23864
+ if (use.role === "set" && "type" in use.member) take("value", use.member.type);
22853
23865
  const sourceParams = extension ? params.slice(1) : params;
22854
23866
  const given = extension ? use.given.slice(1) : use.given;
22855
23867
  const wrapped = extension ? use.wrapped.slice(1) : use.wrapped;
@@ -22864,8 +23876,10 @@ function kotlinShim(ctx, use) {
22864
23876
  value: runs ? suspendingLambda(a, runs) : primOf(p.type) ? name$2(a) : call$3(name$2("cast"), [{ value: name$2(a) }])
22865
23877
  });
22866
23878
  });
22867
- const classArgs = (use.cls.typeParams ?? []).map((n) => anyFor(n, use.cls.kotlin?.bounds));
22868
- const memberArgs = ("typeParams" in use.member ? use.member.typeParams ?? [] : []).map((n) => anyFor(n, use.member.kotlin?.bounds));
23879
+ const declared = declaredTypeParams(use);
23880
+ const typeArg = (n, bounds) => declared.names.includes(n) ? type$3(n) : anyFor(n, bounds);
23881
+ const classArgs = (use.cls.typeParams ?? []).map((n) => typeArg(n, use.cls.kotlin?.bounds));
23882
+ const memberArgs = ("typeParams" in use.member ? use.member.typeParams ?? [] : []).map((n) => typeArg(n, use.member.kotlin?.bounds));
22869
23883
  const typeArgs = (list) => list.length ? list : void 0;
22870
23884
  const cast = (t) => call$3(name$2("cast"), [{ value: name$2("receiver") }], void 0, [t]);
22871
23885
  const pkg = use.module;
@@ -22880,7 +23894,7 @@ function kotlinShim(ctx, use) {
22880
23894
  const n = identifier(use, memberName);
22881
23895
  if (extension) imports.push(`${pkg}.${n}`);
22882
23896
  const reached = target ? member$5(target, n) : qualified(`${topLevel ? pkg : kotlinName(use.cls.native)}.${n}`);
22883
- return use.role === "get" ? reached : call$3(reached, args, void 0, typeArgs(memberArgs));
23897
+ return use.role === "get" || use.role === "set" ? reached : call$3(reached, args, void 0, typeArgs(memberArgs));
22884
23898
  })();
22885
23899
  let body;
22886
23900
  let ret;
@@ -22891,6 +23905,10 @@ function kotlinShim(ctx, use) {
22891
23905
  ret = type$3("AutoCloseable");
22892
23906
  retDescriptor = "Ljava/lang/AutoCloseable;";
22893
23907
  body = [ret$1(call$3(name$2("start"), [{ value: name$2("done") }], lambda$1([], [exprStmt$2(call)])))];
23908
+ } else if (use.role === "set") {
23909
+ const value = "type" in use.member && primOf(use.member.type);
23910
+ retDescriptor = "V";
23911
+ body = [assign$2(call, value ? name$2("value") : call$3(name$2("cast"), [{ value: name$2("value") }]))];
22894
23912
  } else if (isVoid$1(use.returns)) {
22895
23913
  retDescriptor = "V";
22896
23914
  body = [exprStmt$2(call)];
@@ -22908,6 +23926,10 @@ function kotlinShim(ctx, use) {
22908
23926
  k: "fun",
22909
23927
  annotations: ["JvmStatic"],
22910
23928
  modifiers: [],
23929
+ ...declared.names.length ? {
23930
+ typeParams: declared.names,
23931
+ bounds: declared.bounds
23932
+ } : {},
22911
23933
  name,
22912
23934
  params: shimParams,
22913
23935
  ...ret ? { ret } : {},
@@ -23621,7 +24643,7 @@ function toLucent(ctx, vt, lt, r) {
23621
24643
  case "string": return call$5(views("lucentString"), [r]);
23622
24644
  case "enum": return call$5(views("lucentString"), [dot(r, "value")]);
23623
24645
  case "array": {
23624
- const e = element(lt);
24646
+ const e = element$1(lt);
23625
24647
  return call$5(views("lucentArray"), [r, each(toLucent(ctx, vt.element, e, value))], [ctx.reg.cppType(e)]);
23626
24648
  }
23627
24649
  case "nullable": {
@@ -23657,7 +24679,7 @@ function assignRepr(ctx, target, vt, lt, src) {
23657
24679
  case "array": return [exprStmt$4(call$5(views("assignArray"), [
23658
24680
  target,
23659
24681
  src,
23660
- each((t, e) => assignRepr(ctx, t, vt.element, element(lt), e))
24682
+ each((t, e) => assignRepr(ctx, t, vt.element, element$1(lt), e))
23661
24683
  ]))];
23662
24684
  case "nullable": return [exprStmt$4(call$5(views("assignOpt"), [
23663
24685
  target,
@@ -23689,7 +24711,7 @@ function unwrapped(lt) {
23689
24711
  if (lt.k !== "opt") throw new Error(`expected an optional type (got ${lt.k})`);
23690
24712
  return lt.inner;
23691
24713
  }
23692
- function element(lt) {
24714
+ function element$1(lt) {
23693
24715
  if (lt.k !== "array") throw new Error(`expected an array type (got ${lt.k})`);
23694
24716
  return lt.e;
23695
24717
  }
@@ -24742,6 +25764,153 @@ const composeEmitter = {
24742
25764
  }
24743
25765
  };
24744
25766
  //#endregion
25767
+ //#region ../compiler/src/emit/native-jsx.ts
25768
+ function nativeJsx(em, node) {
25769
+ const setup = setupOf(em.ctx, node);
25770
+ if (!setup || !returnedBy(node, setup.fn)) fail$2(node, Codes.NativeViewJsx, "JSX of native views is what a component returns: return it, as the last statement of the component");
25771
+ const made = {
25772
+ statements: [],
25773
+ cleanup: [],
25774
+ captures: []
25775
+ };
25776
+ const root = element(em, node, made);
25777
+ made.statements.push(exprStmt$4(call$5(arrow$1(call$5("lucent::ui::mainGraph"), "onCleanup"), [lambda$2(made.captures, [], made.cleanup)])));
25778
+ return {
25779
+ c: statementExpr(made.statements, id(root)),
25780
+ t: setup.root
25781
+ };
25782
+ }
25783
+ const discarded = (c) => exprStmt$4(c.k === "call" ? c : cast$3("c", voidType, c));
25784
+ function returnedBy(node, fn) {
25785
+ let at = node;
25786
+ while (ts.isParenthesizedExpression(at.parent)) at = at.parent;
25787
+ const body = fn.body;
25788
+ const last = body && ts.isBlock(body) ? body.statements.at(-1) : void 0;
25789
+ return body === at || !!last && ts.isReturnStatement(last) && last.expression === at;
25790
+ }
25791
+ function refuseCopies(em, fn, value) {
25792
+ const props = fn.parameters[0] && em.checker.getSymbolAtLocation(fn.parameters[0].name);
25793
+ const body = fn.body && ts.isBlock(fn.body) ? fn.body : void 0;
25794
+ if (!props || !body) return;
25795
+ const visit = (n) => {
25796
+ if (ts.isFunctionLike(n)) return;
25797
+ const decl = (ts.isIdentifier(n) ? em.checker.getSymbolAtLocation(n) : void 0)?.valueDeclaration;
25798
+ const statement = decl?.parent?.parent;
25799
+ let read = decl && ts.isVariableDeclaration(decl) ? decl.initializer : void 0;
25800
+ while (read && ts.isParenthesizedExpression(read)) read = read.expression;
25801
+ let root = read;
25802
+ while (root && ts.isPropertyAccessExpression(root)) root = root.expression;
25803
+ if (read && read !== root && root && ts.isIdentifier(root) && em.checker.getSymbolAtLocation(root) === props && statement && ts.isVariableStatement(statement) && statement.parent === body) fail$2(n, Codes.NativeViewJsx, `\`${n.getText()}\` is ${read.getText()} as setup first read it: the attribute would never change`, `read ${read.getText()} in the attribute, which keeps it up to date`);
25804
+ ts.forEachChild(n, visit);
25805
+ };
25806
+ visit(value);
25807
+ }
25808
+ function element(em, node, made) {
25809
+ const setup = setupOf(em.ctx, node);
25810
+ let jsx = node;
25811
+ while (ts.isParenthesizedExpression(jsx)) jsx = jsx.expression;
25812
+ if (!ts.isJsxElement(jsx) && !ts.isJsxSelfClosingElement(jsx)) fail$2(node, Codes.NativeViewJsx, "a native view's children are elements of native views");
25813
+ const opening = ts.isJsxElement(jsx) ? jsx.openingElement : jsx;
25814
+ const tag = opening.tagName;
25815
+ const ref = sdkTagClass(em, tag);
25816
+ if (!ref) fail$2(tag, Codes.NativeViewJsx, `<${tag.getText()}> is no SDK view class: a native view's JSX is UIKit's or Android's views`);
25817
+ const at = tag;
25818
+ const schema = findSdkModule(ref.platform, ref.module);
25819
+ if (!schema) throw new Error(`${ref.module}: no schema for a class it declares`);
25820
+ const rules = viewTag(ref.cls, schema, (m) => findSdkModule(ref.platform, m));
25821
+ const owned = (o) => ({
25822
+ platform: ref.platform,
25823
+ module: o.schema.module,
25824
+ cls: o.cls
25825
+ });
25826
+ const lt = em.reg.lower(nativeTagType(em.checker, node), node);
25827
+ const view = em.ctx.fresh(`view_${ref.cls.name}`);
25828
+ const attributes = opening.attributes.properties;
25829
+ for (const a of attributes) if (!ts.isJsxAttribute(a)) fail$2(a, Codes.NativeViewJsx, "a native view's attributes are written one by one, not spread");
25830
+ const named = (name) => attributes.find((a) => ts.isJsxAttribute(a) && a.name.getText() === name);
25831
+ const valueOf = (a) => a.initializer && ts.isJsxExpression(a.initializer) ? a.initializer.expression : a.initializer;
25832
+ const create = named("create");
25833
+ const createdBy = create && valueOf(create);
25834
+ if (createdBy) {
25835
+ const f = em.ctx.fresh("create");
25836
+ made.statements.push(varDecl(auto$1, f, em.expr(createdBy).c), varDecl(auto$1, view, call$5(id(f), [])));
25837
+ } else {
25838
+ if (rules.construction.kind === "create") fail$2(tag, Codes.NativeViewJsx, rules.construction.reason);
25839
+ made.statements.push(varDecl(auto$1, view, viewNew(em, at, ref, rules.construction, lt).c));
25840
+ }
25841
+ const self = {
25842
+ c: id(view),
25843
+ t: lt
25844
+ };
25845
+ made.captures.push(view);
25846
+ for (const a of attributes) {
25847
+ const name = a.name.getText();
25848
+ if (name === "create") continue;
25849
+ const value = valueOf(a);
25850
+ const prop = rules.props.get(name);
25851
+ const event = rules.events.get(name);
25852
+ if (event) {
25853
+ if (!value) fail$2(a, Codes.NativeViewJsx, `${name} takes a function`);
25854
+ const owner = owned(event.owner);
25855
+ const handler = em.expr(value);
25856
+ if (event.event.kind === "listener") {
25857
+ const listened = listenerEvent(em, value, owner, event.event.setter, self, handler);
25858
+ made.statements.push(exprStmt$4(listened.add));
25859
+ made.cleanup.push(exprStmt$4(listened.remove));
25860
+ } else {
25861
+ const action = em.ctx.fresh("action");
25862
+ const control = controlEvent(em, value, owner, ref, event.event.register, event.event.value, self, handler);
25863
+ made.statements.push(varDecl(auto$1, action, control.add));
25864
+ made.cleanup.push(exprStmt$4(control.remove(id(action))));
25865
+ made.captures.push(action);
25866
+ }
25867
+ continue;
25868
+ }
25869
+ if (!prop) fail$2(a, Codes.NativeViewJsx, `<${ref.cls.name}> has no ${name}: what its declarations give is a writable property, a setter, an event, or children`);
25870
+ const owner = owned(prop.owner);
25871
+ const type = em.lt(a.name);
25872
+ const set = (v) => prop.prop.kind === "property" ? propertySetter(em, value ?? at, owner, prop.prop.member, self, type)(v.c) : setterCall(em, value ?? at, owner, prop.prop.overloads, self, v);
25873
+ if (!value) {
25874
+ made.statements.push(discarded(set({
25875
+ c: id("true"),
25876
+ t: T.boolean
25877
+ })));
25878
+ continue;
25879
+ }
25880
+ refuseCopies(em, setup.fn, value);
25881
+ const property = prop.prop.kind === "property";
25882
+ const get = em.thunk(value, {
25883
+ site: value,
25884
+ ...property ? { type } : {}
25885
+ });
25886
+ const got = !property && get.t.k === "fn" ? get.t.ret : type;
25887
+ const keep = lambda$2([view, {
25888
+ name: "lucent_get",
25889
+ init: get.c
25890
+ }], [], [varDecl(auto$1, "lucent_value", call$5(id("lucent_get"))), discarded(set({
25891
+ c: id("lucent_value"),
25892
+ t: got
25893
+ }))], { mutable: true });
25894
+ made.statements.push(exprStmt$4(call$5("lucent::ui::effect", [
25895
+ call$5("lucent::ui::mainGraph"),
25896
+ enterMount(em, value, keep),
25897
+ str$5(site(value))
25898
+ ])));
25899
+ }
25900
+ const children = ts.isJsxElement(jsx) ? jsx.children.filter((c) => !(ts.isJsxText(c) && c.containsOnlyTriviaWhiteSpaces)) : [];
25901
+ if (children.length && !rules.children) fail$2(children[0], Codes.NativeViewJsx, `<${ref.cls.name}> takes no children: its class declares no method inserting a view at an index`);
25902
+ children.forEach((c, index) => {
25903
+ if (!ts.isJsxElement(c) && !ts.isJsxSelfClosingElement(c)) fail$2(c, Codes.NativeViewJsx, "a native view's children are elements of native views");
25904
+ const child = element(em, c, made);
25905
+ const { rule, owner } = rules.children;
25906
+ made.statements.push(exprStmt$4(insertChild(em, c, owned(owner), rule.insert, self, {
25907
+ c: id(child),
25908
+ t: lt
25909
+ }, index)));
25910
+ });
25911
+ return view;
25912
+ }
25913
+ //#endregion
24745
25914
  //#region ../compiler/src/ui/source-members.ts
24746
25915
  const indexes = /* @__PURE__ */ new WeakMap();
24747
25916
  function indexOf$1(schema) {
@@ -25744,7 +26913,7 @@ function writable(node, found) {
25744
26913
  const refused = unsupportedReason(found.plan);
25745
26914
  if (refused) bodyFail(node, `\`${found.display}\` cannot be written in a SwiftUI body yet: ${refused}`);
25746
26915
  const since = found.plan.availability?.since;
25747
- if (typeof since === "string" && compareVersions(since, "15.1") > 0) bodyFail(node, `\`${found.display}\` needs iOS ${since} (apps run from iOS ${MIN_IOS}): a SwiftUI body writes what every supported iOS has, for now`);
26916
+ if (typeof since === "string" && compareVersions(since, oldestIos()) > 0) bodyFail(node, `\`${found.display}\` needs iOS ${since} (apps run from iOS ${oldestIos()}): a SwiftUI body writes what every supported iOS has, for now`);
25748
26917
  }
25749
26918
  function isNothing(e) {
25750
26919
  return e.kind === ts.SyntaxKind.NullKeyword || e.kind === ts.SyntaxKind.FalseKeyword || ts.isIdentifier(e) && e.text === "undefined";
@@ -26345,6 +27514,7 @@ function toolkitMember(em, node) {
26345
27514
  }
26346
27515
  const BODY_PLACE = "the body a component returns";
26347
27516
  function toolkitJsx(em, node) {
27517
+ if (nativeTagType(em.checker, node)) return nativeJsx(em, node);
26348
27518
  const toolkit = jsxToolkitOf(node, em.checker);
26349
27519
  const setup = setupOf(em.ctx, node);
26350
27520
  if (!toolkit) throw new Error("JSX in a file of no toolkit (the program refuses it)");
@@ -26870,10 +28040,10 @@ function mountUnit(ctx, s) {
26870
28040
  };
26871
28041
  const ns = `lucent_app::${s.module.ns}`;
26872
28042
  const where = str$5(`${path.basename(c.source.file)}:${c.source.line}`);
26873
- const id$10 = str$5(c.id);
28043
+ const id$14 = str$5(c.id);
26874
28044
  const view = (e, what) => exprStmt$4(call$5("lucent::ui::reportViewError", [
26875
28045
  e,
26876
- id$10,
28046
+ id$14,
26877
28047
  str$5(what),
26878
28048
  where
26879
28049
  ]));
@@ -27660,6 +28830,7 @@ function bareSwiftType(t) {
27660
28830
  case "id": return type$2("Any");
27661
28831
  case "array": return array$1(swiftType(t.of));
27662
28832
  case "record": return dictionary(type$2("String"), swiftType(t.of));
28833
+ case "fn": return blockFunction(t.params.map(swiftType), t.ret.k === "prim" && t.ret.name === "void" ? type$2("Void") : swiftType(t.ret));
27663
28834
  case "ref": {
27664
28835
  const info = sdkTypeInfo("ios", t.module, t.name);
27665
28836
  if (info?.kind === "struct") return type$2(info.native);
@@ -27704,6 +28875,14 @@ function fromObject(t, o) {
27704
28875
  case "record":
27705
28876
  if (bridges(t.of)) return cast$4(swiftType(t));
27706
28877
  return each(cast$4(dictionary(type$2("String"), type$2("AnyObject"))), "mapValues", fromObject(t.of, n("$0")));
28878
+ case "fn": return call$2(n("unsafeBitCast"), [{ value: o }, {
28879
+ label: "to",
28880
+ value: n(`(${printType$1(swiftType(t))}).self`)
28881
+ }]);
28882
+ case "tuple": {
28883
+ const items = cast$4(array$1(type$2("AnyObject")));
28884
+ return tupleLiteral(t.of.map((x, i) => fromObject(x, index(items, num$3(i)))));
28885
+ }
27707
28886
  case "ref": {
27708
28887
  const e = swiftEnum(t);
27709
28888
  if (e) return index(casesOf(e), member$4(cast$4(type$2("NSNumber")), "intValue"));
@@ -27732,6 +28911,11 @@ function toObject(t, v) {
27732
28911
  case "id": return as(v, "AnyObject");
27733
28912
  case "array": return as(bridges(t.of) ? v : each(v, "map", toObject(t.of, n("$0"))), "NSArray");
27734
28913
  case "record": return as(bridges(t.of) ? v : each(v, "mapValues", toObject(t.of, n("$0"))), "NSDictionary");
28914
+ case "fn": return call$2(n("unsafeBitCast"), [{ value: cast(v, "as", swiftType(t)) }, {
28915
+ label: "to",
28916
+ value: n("AnyObject.self")
28917
+ }]);
28918
+ case "tuple": return as(arrayLiteral(t.of.map((x, i) => as(toObject(x, member$4(v, String(i))), "AnyObject"))), "NSArray");
27735
28919
  case "ref": {
27736
28920
  const e = swiftEnum(t);
27737
28921
  if (e) return call$2(n("NSNumber"), [{
@@ -28179,7 +29363,10 @@ const REFUSAL_CODES = {
28179
29363
  function requirePlan(node, of, member, role, declared = member) {
28180
29364
  const plan = memberPlan(of.platform, of.module, of.cls, member, role);
28181
29365
  const why = explainRefusal(plan);
28182
- if (why) fail$2(node, plan.refused ? REFUSAL_CODES[plan.refused.rule] ?? Codes.UnsupportedCall : Codes.UnsupportedType, why);
29366
+ if (why) {
29367
+ if (plan.refused) fail$2(node, REFUSAL_CODES[plan.refused.rule] ?? Codes.UnsupportedCall, why);
29368
+ fail$2(node, Codes.UnsupportedType, why, WRAP_UNBOUND[of.platform]);
29369
+ }
28183
29370
  noteSdkUse(of.platform, of.module, of.cls, declared, plan);
28184
29371
  return plan;
28185
29372
  }
@@ -28427,6 +29614,10 @@ function toObjcExpr(t, c, owned, what = "a value") {
28427
29614
  return t.cf ? bridgeTo("CFArrayRef", arr) : arr;
28428
29615
  }
28429
29616
  case "set": return objc("toNSSet", eachElement(t.of));
29617
+ case "tuple": {
29618
+ const v = id("t_");
29619
+ return statementExpr([varDecl(auto$1, "t_", c)], call$5("lucent::objc::toNSArrayOf", t.of.map((x, i) => boxed(x, call$5("std::get", [v], [num$5(i)])))));
29620
+ }
28430
29621
  case "record": {
28431
29622
  const dict = objc("toNSDictionary", eachElement(t.of));
28432
29623
  return t.cf ? bridgeTo("CFDictionaryRef", dict) : dict;
@@ -28480,7 +29671,7 @@ function toObjc(em, arg, t, use, owned = false) {
28480
29671
  if (t.k === "id" || t.k === "tparam") return toObjcExpr(t, em.expr(arg).c, owned);
28481
29672
  if (t.k === "out") return outArg(em, arg, t, owned);
28482
29673
  const what = argumentWhat(em, arg);
28483
- if (sdkStruct(t)) {
29674
+ if (sdkStruct(t) || t.k === "tuple") {
28484
29675
  const declared = em.checker.getContextualType(arg);
28485
29676
  const lt = declared ? em.reg.lower(declared, arg) : em.lt(arg);
28486
29677
  return toObjcExpr(t, em.exprAs(arg, lt), owned, what);
@@ -28627,6 +29818,18 @@ function fromObjc(em, code, t, lt, what, owned = false) {
28627
29818
  c: objc("fromNSError", code, w),
28628
29819
  t: lt
28629
29820
  };
29821
+ case "tuple": {
29822
+ const tuple = elem(lt);
29823
+ if (tuple.k !== "tuple") throw new Error(`${what}: a tuple read as ${tuple.k}`);
29824
+ const items = t.of.map((x, i) => {
29825
+ const read = lambda$2(["&"], [param$5(type$5("id"), "e_")], [ret$3(fromObjcItem(em, x, tuple.es[i], what))], { ret: em.reg.cppType(tuple.es[i]) });
29826
+ return call$5(read, [send$1(id("a_"), "objectAtIndex:", [num$5(i)])]);
29827
+ });
29828
+ return {
29829
+ c: statementExpr([varDecl(objcPointer("NSArray"), "a_", cast$3("c", objcPointer("NSArray"), code))], construct(em.reg.cppType(tuple), items)),
29830
+ t: tuple
29831
+ };
29832
+ }
28630
29833
  default: throw new Error(`${what}: an Objective-C ${t.k} value its plan refuses`);
28631
29834
  }
28632
29835
  }
@@ -28799,7 +30002,8 @@ function jniArgument(em, ref, arg, t) {
28799
30002
  t: typed
28800
30003
  };
28801
30004
  }
28802
- case "tparam": return em.expr(arg);
30005
+ case "tparam":
30006
+ case "fn": return em.expr(arg);
28803
30007
  default: throw new Error(`${t.k} values, which plans refuse over JNI`);
28804
30008
  }
28805
30009
  }
@@ -28836,8 +30040,10 @@ function jniOf(em, arg, t, value) {
28836
30040
  }
28837
30041
  case "ref":
28838
30042
  if (value.t.k === "fn") return javaProxy(em, arg, value, t);
30043
+ if (eitherMembers(value.t)) return jniEither(em, arg, t, value);
28839
30044
  return jni("unwrap", value.c);
28840
30045
  case "tparam": return toJavaObject(arg, value);
30046
+ case "fn": return toKotlinFunction(em, arg, t, value);
28841
30047
  default: throw new Error(`${t.k} values, which plans refuse over JNI`);
28842
30048
  }
28843
30049
  }
@@ -28912,38 +30118,84 @@ function javaProxy(em, arg, f, t) {
28912
30118
  function proxyEntry(em, node, module, owner, m, fn, capture, call) {
28913
30119
  const params = m.params.map((p) => parseSdkType(p.type, module, m.typeParams ?? []));
28914
30120
  const n = Math.min(fn.params.length, params.length);
28915
- const what = `${owner}.${m.name}`;
28916
30121
  const cls = findSdkType("android", module, owner);
28917
- if (cls?.kind !== "class") throw new Error(`${what}: no class`);
30122
+ if (cls?.kind !== "class") throw new Error(`${owner}.${m.name}: no class`);
28918
30123
  const plan = requirePlan(node, {
28919
30124
  platform: "android",
28920
30125
  module,
28921
30126
  cls
28922
30127
  }, m, "implement");
28923
30128
  requireTaken(node, plan, plan.inputs, n);
28924
- const args = proxyArguments(em, node, params.slice(0, n), fn, what);
30129
+ const descriptor = m.descriptor ?? jniDescriptor(m.params.map((p) => p.type), m.returns, m.typeParams);
30130
+ const ret = parseSdkType(m.returns, module, m.typeParams ?? []);
30131
+ const what = `${owner}.${m.name}`;
30132
+ const suspend = !!m.kotlin?.suspend;
30133
+ const slots = descriptorSlots(descriptor);
30134
+ const result = unboxedSlot(ret, suspend ? void 0 : slots.ret);
30135
+ const valueLt = suspend && fn.ret.k === "promise" ? fn.ret.inner : fn.ret;
30136
+ const box = (r) => result ? jni("unboxValueClass", env, str$5(result.native), str$5(result.underlying), jni("unwrap", r)) : suspend && ret.k === "prim" && ret.name === "void" ? jni("unit", env) : boxJava(em, node, ret, r, what, valueLt);
30137
+ return proxyMethod(em, node, {
30138
+ key: `${m.java ?? m.name}${descriptor.slice(0, descriptor.indexOf(")") + 1)}`,
30139
+ params: params.slice(0, n),
30140
+ unboxed: params.slice(0, n).map((p, i) => unboxedSlot(p, slots.params[i])),
30141
+ box,
30142
+ queued: plan.delivery === "queued",
30143
+ ...suspend ? { continuation: params.length } : {},
30144
+ what,
30145
+ fn,
30146
+ capture,
30147
+ call
30148
+ });
30149
+ }
30150
+ function descriptorSlots(descriptor) {
30151
+ const slots = descriptor.match(/\[*(?:[ZBCSIJFDV]|L[^;]+;)/g) ?? [];
30152
+ return {
30153
+ params: slots.slice(0, -1),
30154
+ ret: slots.at(-1) ?? "V"
30155
+ };
30156
+ }
30157
+ function unboxedSlot(t, slot) {
30158
+ if (t.k !== "ref" || !slot) return void 0;
30159
+ const cls = findSdkType("android", t.module, t.name);
30160
+ if (cls?.kind !== "class" || !cls.kotlin?.value) return void 0;
30161
+ return slot === `L${cls.native};` ? void 0 : {
30162
+ native: cls.native,
30163
+ underlying: slot
30164
+ };
30165
+ }
30166
+ function proxyMethod(em, node, m) {
30167
+ const args = proxyArguments(em, node, m.params, m.fn, m.what, m.unboxed);
28925
30168
  const names = args.map((_, i) => `a${i}_`);
28926
30169
  const convert = args.map((a, i) => varDecl(auto$1, names[i], a));
28927
- const ret = parseSdkType(m.returns, module, m.typeParams ?? []);
28928
- const holder = typeof capture === "string" ? capture : capture.name;
28929
- const made = call(names.map(id));
30170
+ const holder = typeof m.capture === "string" ? m.capture : m.capture.name;
30171
+ const made = m.call(names.map(id));
28930
30172
  const jobject = type$5("jobject");
28931
30173
  const entry = callbackEntry(em, node);
28932
- const body = plan.delivery === "queued" ? [
30174
+ const resumed = (k) => {
30175
+ const resume = id("resume_");
30176
+ const boxValue = lambda$2([], [param$5(pointer(type$5("JNIEnv")), "env"), param$5(reference(constType(auto$1)), "v_")], [ret$3(m.box(id("v_")))], { ret: jobject });
30177
+ const run = lambda$2([
30178
+ holder,
30179
+ ...names,
30180
+ "resume_"
30181
+ ], [], [exprStmt$4(jni("resumeWithResult", resume, lambda$2(["&"], [], [ret$3(made)]), boxValue))]);
30182
+ const start = lambda$2([holder, ...names], [param$5(type$5("lucent::jni::Resume"), "resume_")], [exprStmt$4(entry.later(run))]);
30183
+ return [...convert, ret$3(jni("suspendedCall", env, jni("arg", env, id("args_"), num$5(k)), start))];
30184
+ };
30185
+ const body = m.continuation !== void 0 ? resumed(m.continuation) : m.queued ? [
28933
30186
  ...convert,
28934
30187
  exprStmt$4(entry.later(lambda$2([holder, ...names], [], [exprStmt$4(cast$3("c", voidType, made))]))),
28935
30188
  ret$3(nullptr)
28936
- ] : [...convert, ret$3(entry.now(lambda$2(["&"], [], [varDecl(auto$1, "r_", made), ret$3(boxJava(node, ret, id("r_"), what, fn.ret))], { ret: jobject })))];
28937
- const descriptor = m.descriptor ?? jniDescriptor(m.params.map((p) => p.type), m.returns, m.typeParams);
28938
- const key = `${m.java ?? m.name}${descriptor.slice(0, descriptor.indexOf(")") + 1)}`;
28939
- const method = lambda$2([capture], [param$5(pointer(type$5("JNIEnv")), "env"), param$5(type$5("jobjectArray"), "args_")], body, { ret: jobject });
28940
- return initList([str$5(key), method]);
30189
+ ] : [...convert, ret$3(entry.now(lambda$2(["&"], [], [varDecl(auto$1, "r_", made), ret$3(m.box(id("r_")))], { ret: jobject })))];
30190
+ const method = lambda$2([m.capture], [param$5(pointer(type$5("JNIEnv")), "env"), param$5(type$5("jobjectArray"), "args_")], body, { ret: jobject });
30191
+ return initList([str$5(m.key), method]);
28941
30192
  }
28942
- function proxyArguments(em, node, params, fn, what) {
30193
+ function proxyArguments(em, node, params, fn, what, unboxed = []) {
28943
30194
  return params.map((p, i) => {
28944
- const a = jni("arg", env, id("args_"), num$5(i));
28945
- if (p.k === "prim") return unboxedPrim(p, a);
28946
- return fromJni(em, a, p, fn.params[i], what, node).c;
30195
+ const arg = jni("arg", env, id("args_"), num$5(i));
30196
+ if (p.k === "prim") return unboxedPrim(p, arg);
30197
+ const v = unboxed[i];
30198
+ return fromJni(em, v ? jni("boxValueClass", env, str$5(v.native), str$5(v.underlying), arg) : arg, p, fn.params[i], what, node).c;
28947
30199
  });
28948
30200
  }
28949
30201
  function kotlinFunction(em, arg, f, runs, what, site) {
@@ -28957,7 +30209,7 @@ function kotlinFunction(em, arg, f, runs, what, site) {
28957
30209
  const ret = runs.returns;
28958
30210
  const result = () => {
28959
30211
  const r = id("r_");
28960
- if (ret.k === "tparam") return boxJava(arg, ret, r, what, fn.ret);
30212
+ if (ret.k === "tparam") return boxJava(em, arg, ret, r, what, fn.ret);
28961
30213
  if (ret.k === "ref") return envCall("NewLocalRef", toJavaObjectOf(em, ret, r, fn.ret, what));
28962
30214
  return toJavaObjectOf(em, ret, r, fn.ret, what);
28963
30215
  };
@@ -28967,6 +30219,94 @@ function kotlinFunction(em, arg, f, runs, what, site) {
28967
30219
  const key = `invoke(${"Ljava/lang/Object;".repeat(arity)})`;
28968
30220
  return statementExpr([varDecl(auto$1, "f_", f.c)], jni("proxyFor", env, javaClass(em, `kotlin/jvm/functions/Function${arity}`), call$5(dot(id("f_"), "identity")), initList([initList([str$5(key), method])]), str$5(site)));
28969
30221
  }
30222
+ function eitherMembers(t) {
30223
+ const inner = stripOpt(t);
30224
+ return inner.k === "union" && inner.ms.some((m) => m.k === "fn") ? inner.ms : void 0;
30225
+ }
30226
+ function jniEither(em, arg, t, value) {
30227
+ const jobject = type$5("jobject");
30228
+ const present = (v) => {
30229
+ const u = id("u_");
30230
+ const each = eitherMembers(v.t).map((m, i) => {
30231
+ const got = {
30232
+ c: call$5("std::get", [u], [num$5(i)]),
30233
+ t: m
30234
+ };
30235
+ return {
30236
+ test: binary$2(call$5(dot(u, "index")), "==", num$5(i)),
30237
+ c: staticCast(jobject, m.k === "fn" ? javaProxy(em, arg, got, t) : jni("unwrap", got.c))
30238
+ };
30239
+ });
30240
+ const chain = each.slice(0, -1).reduceRight((rest, e) => conditional$1(e.test, e.c, rest), each.at(-1).c);
30241
+ return statementExpr([varDecl(auto$1, "u_", v.c)], chain);
30242
+ };
30243
+ return value.t.k === "opt" ? whenPresent(value, present) : present(value);
30244
+ }
30245
+ function whenPresent(value, present) {
30246
+ if (value.t.k !== "opt") throw new Error(`an optional value that is a ${value.t.k}`);
30247
+ const jobject = type$5("jobject");
30248
+ const o = id("o_");
30249
+ return statementExpr([varDecl(auto$1, "o_", value.c)], conditional$1(call$5(dot(o, "has")), staticCast(jobject, present({
30250
+ c: call$5(dot(o, "get")),
30251
+ t: value.t.inner
30252
+ })), staticCast(jobject, nullptr)));
30253
+ }
30254
+ function toKotlinFunction(em, arg, t, value) {
30255
+ if (value.t.k === "null" || value.t.k === "undefined") return nullptr;
30256
+ if (value.t.k === "opt") return whenPresent(value, (v) => toKotlinFunction(em, arg, t, v));
30257
+ const fn = value.t;
30258
+ if (fn.k !== "fn") fail$2(arg, Codes.UnsupportedType, "pass a function");
30259
+ const what = argumentWhat(em, arg);
30260
+ const plan = kotlinFunctionConversion(t);
30261
+ if (plan.op !== "callback") throw new Error(`${what}: a Kotlin function its plan refuses`);
30262
+ const n = Math.min(fn.params.length, t.params.length);
30263
+ requireTaken(arg, { display: what }, plan.of.slice(0, -1), n);
30264
+ const ret = t.ret;
30265
+ const box = (r) => {
30266
+ if (ret.k === "tparam") return boxJava(em, arg, ret, r, what, fn.ret);
30267
+ if (ret.k === "ref") return envCall("NewLocalRef", toJavaObjectOf(em, ret, r, fn.ret, what));
30268
+ return toJavaObjectOf(em, ret, r, fn.ret, what);
30269
+ };
30270
+ const entry = proxyMethod(em, arg, {
30271
+ key: `invoke(${"Ljava/lang/Object;".repeat(t.params.length)})`,
30272
+ params: t.params.slice(0, n),
30273
+ box,
30274
+ queued: plan.delivery === "queued",
30275
+ what,
30276
+ fn,
30277
+ capture: "f_",
30278
+ call: (a) => call$5(id("f_"), a)
30279
+ });
30280
+ return statementExpr([varDecl(auto$1, "f_", value.c)], jni("proxyFor", env, javaClass(em, `kotlin/jvm/functions/Function${t.params.length}`), call$5(dot(id("f_"), "identity")), initList([entry])));
30281
+ }
30282
+ function fromKotlinFunction(em, code, t, lt, what, node) {
30283
+ const fn = stripOpt(lt);
30284
+ if (fn.k !== "fn") throw new Error(`${what}: a Kotlin function read as ${fn.k}`);
30285
+ const arity = t.params.length;
30286
+ const params = fn.params.map((p, i) => param$5(em.reg.cppType(p), `v${i}_`));
30287
+ const args = t.params.map((p, i) => i < params.length ? toJavaObjectOf(em, p, id(`v${i}_`), fn.params[i], what) : nullptr);
30288
+ const isVoid = t.ret.k === "prim" && t.ret.name === "void";
30289
+ const r = id("r_");
30290
+ const result = isVoid ? void 0 : t.ret.k === "prim" ? unboxedPrim(t.ret, r) : fromJni(em, r, t.ret, fn.ret, `${what}'s result`, node).c;
30291
+ const call = envCall("CallObjectMethod", jni("unwrap", id("f_")), id("id_"), ...args);
30292
+ const body = [
30293
+ varDecl(pointer(type$5("JNIEnv")), "env", jni("env")),
30294
+ varDecl(type$5("lucent::jni::LocalFrame"), "frame_", env, { style: "construct" }),
30295
+ varDecl(type$5("jclass"), "cls_", jni("findClass", javaClass(em, `kotlin/jvm/functions/Function${arity}`)), { static: true }),
30296
+ varDecl(auto$1, "id_", jni("method", id("cls_"), str$5("invoke"), javaDescriptor(em, `(${"Ljava/lang/Object;".repeat(arity)})Ljava/lang/Object;`)), { static: true }),
30297
+ varDecl(auto$1, "r_", call),
30298
+ exprStmt$4(jni("check", env)),
30299
+ ...result ? [ret$3(result)] : []
30300
+ ];
30301
+ const lambda = lambda$2([{
30302
+ name: "f_",
30303
+ init: jni("wrap", env, code, str$5(what))
30304
+ }], params, body, { ret: em.reg.cppRetType(fn.ret) });
30305
+ const value = construct(em.reg.cppType(fn), [lambda]);
30306
+ if (lt.k !== "opt") return value;
30307
+ const optional = em.reg.cppType(lt);
30308
+ return conditional$1(code, construct(optional, [value]), construct(optional, [id("lucent::null")]));
30309
+ }
28970
30310
  function extendsSdk(base, to) {
28971
30311
  for (let t = base; t;) {
28972
30312
  if (t.module === to.module && t.name === to.name) return true;
@@ -29013,7 +30353,7 @@ function javaObjectOfClass(em, e, to, node) {
29013
30353
  const o = id("o_");
29014
30354
  return statementExpr([varDecl(auto$1, "o_", e.c)], jni("proxyFor", jni("env"), javaClass(em, iface.native), call$5(dot(o, "get")), initList(entries)));
29015
30355
  }
29016
- function boxJava(node, t, c, what, lt) {
30356
+ function boxJava(em, node, t, c, what, lt) {
29017
30357
  if (t.k === "string") return jni("toJString", env, c);
29018
30358
  if (t.k === "tparam") {
29019
30359
  const inner = lt ? stripOpt(lt) : void 0;
@@ -29022,6 +30362,7 @@ function boxJava(node, t, c, what, lt) {
29022
30362
  if (inner?.k === "boolean" && lt.k !== "opt") return jni("boxBoolean", env, c);
29023
30363
  fail$2(node, Codes.UnsupportedType, `${what} returns a type parameter's value: Lucent functions return an SDK object, a string or a boolean there`);
29024
30364
  }
30365
+ if (t.k === "ref") return envCall("NewLocalRef", toJavaObjectOf(em, t, c, lt, what));
29025
30366
  if (t.k !== "prim") throw new Error(`${what}: a ${t.k} result its plan refuses`);
29026
30367
  return boxedForJava(t, c, `${what}'s result`);
29027
30368
  }
@@ -29293,6 +30634,10 @@ function fromJni(em, code, t, lt, what, node) {
29293
30634
  t: lt
29294
30635
  };
29295
30636
  case "tparam": return fromJavaObject(code, lt, what, node);
30637
+ case "fn": return {
30638
+ c: fromKotlinFunction(em, code, t, lt, what, node),
30639
+ t: lt
30640
+ };
29296
30641
  default: throw new Error(`unsupported Java result type ${t.k}`);
29297
30642
  }
29298
30643
  }
@@ -29319,14 +30664,14 @@ function fromJniList(em, code, t, lt, what, node) {
29319
30664
  function jniCall(em, opts) {
29320
30665
  const result = opts.ret.k === "prim" && opts.ret.name === "void";
29321
30666
  const out = fromJni(em, id("r_"), opts.ret, opts.lt, opts.what, opts.node);
29322
- const id$6 = id("id_");
30667
+ const id$7 = id("id_");
29323
30668
  const body = [
29324
30669
  varDecl(pointer(type$5("JNIEnv")), "env", jni("env")),
29325
30670
  ...opts.pre ?? [],
29326
30671
  varDecl(type$5("lucent::jni::LocalFrame"), "frame_", env, { style: "construct" }),
29327
30672
  varDecl(type$5("jclass"), "cls_", jni("findClass", javaClass(em, opts.cls.native)), { static: true }),
29328
30673
  varDecl(auto$1, "id_", jni(opts.lookup, id("cls_"), str$5(opts.name), javaDescriptor(em, opts.desc)), { static: true }),
29329
- result ? exprStmt$4(opts.access(id$6)) : varDecl(auto$1, "r_", opts.access(id$6)),
30674
+ result ? exprStmt$4(opts.access(id$7)) : varDecl(auto$1, "r_", opts.access(id$7)),
29330
30675
  exprStmt$4(jni("check", env)),
29331
30676
  ret$3(result ? id("lucent::undefined") : out.c)
29332
30677
  ];
@@ -29344,7 +30689,7 @@ function argsOf(node) {
29344
30689
  function needOf(platform, since) {
29345
30690
  if (typeof since !== (platform === "android" ? "number" : "string")) return void 0;
29346
30691
  const version = String(since);
29347
- return compareVersions(version, platform === "ios" ? "15.1" : String(24)) > 0 ? {
30692
+ return compareVersions(version, platform === "ios" ? oldestIos() : String(24)) > 0 ? {
29348
30693
  platform,
29349
30694
  version
29350
30695
  } : void 0;
@@ -29356,7 +30701,7 @@ function availableArgs(need) {
29356
30701
  function requireAvailable(em, node, ref, since, what) {
29357
30702
  const need = needOf(ref.platform, since);
29358
30703
  if (!need || guarded(em, node, need)) return;
29359
- fail$2(node, Codes.Unavailable, need.platform === "ios" ? `${what} needs iOS ${need.version} (apps run from iOS ${MIN_IOS}): use it under if (available("ios", ${availableArgs(need)}))` : `${what} needs API ${need.version} (apps run from API 24): use it under if (available("android", ${need.version})) or Build_VERSION.SDK_INT >= ${need.version}`);
30704
+ fail$2(node, Codes.Unavailable, need.platform === "ios" ? `${what} needs iOS ${need.version} (apps run from iOS ${oldestIos()}): use it under if (available("ios", ${availableArgs(need)}))` : `${what} needs API ${need.version} (apps run from API 24): use it under if (available("android", ${need.version})) or Build_VERSION.SDK_INT >= ${need.version}`);
29360
30705
  }
29361
30706
  const API_LEVEL = "jvm:android/os/Build$VERSION#SDK_INT:I";
29362
30707
  function apiLevelRead(em, e) {
@@ -29497,6 +30842,7 @@ function iosSuperInit(em, node, base, subclass) {
29497
30842
  if (!ref || !decl || !ts.isConstructorDeclaration(decl)) fail$2(node, Codes.UnsupportedCall, `${base.name} cannot be constructed`);
29498
30843
  const ctor = schemaConstructor(ref, decl);
29499
30844
  if (ctor.swift) fail$2(node, Codes.UnsupportedClassFeature, `${base.name}: Swift initializers cannot be inherited`);
30845
+ if (ctor.factory) fail$2(node, Codes.UnsupportedClassFeature, `${base.name}: ${ctor.selector} makes its own object (a class method Swift imports as an initializer), so a subclass cannot call it as super(…): call another of ${base.name}'s initializers`);
29500
30846
  const plan = requirePlan(node, ref, ctor, "new");
29501
30847
  requireAvailable(em, node, ref, ctor.since, `new ${base.name}(…)`);
29502
30848
  noteIncludes(em, ref);
@@ -29541,7 +30887,14 @@ function nativeNew(em, node, t) {
29541
30887
  noteIncludes(em, ref);
29542
30888
  if (ref.platform === "ios") {
29543
30889
  const a = args.map((x, i) => toObjc(em, x, params[i], plan));
29544
- const created = send(send$1(ref.cls.native, "alloc"), ctor.selector ?? "init", a);
30890
+ if (ctor.cFunction) {
30891
+ const made = cast$3("bridge_transfer", type$5("id"), call$5(ctor.cFunction.name, a));
30892
+ return {
30893
+ c: call$5("lucent::objc::wrap", [made, str$5(`new ${t.name}`)]),
30894
+ t
30895
+ };
30896
+ }
30897
+ const created = send(ctor.factory ? id(ref.cls.native) : send$1(ref.cls.native, "alloc"), ctor.selector ?? "init", a);
29545
30898
  return {
29546
30899
  c: call$5("lucent::objc::wrap", [created, str$5(`new ${t.name}`)]),
29547
30900
  t
@@ -29602,7 +30955,7 @@ function nativeStaticProperty(em, node) {
29602
30955
  }
29603
30956
  return;
29604
30957
  }
29605
- if (!ts.isPropertyDeclaration(decl)) return void 0;
30958
+ if (!isSdkPropertyDecl(decl)) return void 0;
29606
30959
  const ref = classOfDecl(decl);
29607
30960
  if (!ref || !ts.getModifiers(decl)?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) return void 0;
29608
30961
  const found = schemaProperty(ref, decl);
@@ -29655,7 +31008,7 @@ function nativeMember(em, obj, node) {
29655
31008
  if (obj.t.k === "native" && obj.t.module === "lucent:ios" && obj.t.name === "Out" && ts.isIdentifier(name) && name.text === "value") return outValue(em, obj, name.parent);
29656
31009
  const decl = resolved(em, name)?.valueDeclaration;
29657
31010
  const ref = decl ? classOfDecl(decl) : void 0;
29658
- if (!ref || !decl || !ts.isPropertyDeclaration(decl)) fail$2(node, Codes.UnsupportedSyntax, "methods of platform objects must be called directly");
31011
+ if (!ref || !decl || !isSdkPropertyDecl(decl)) fail$2(node, Codes.UnsupportedSyntax, "methods of platform objects must be called directly");
29659
31012
  const found = schemaProperty(ref, decl);
29660
31013
  return property$1(em, node, found.ref, found.property, obj);
29661
31014
  }
@@ -29688,6 +31041,7 @@ function property$1(em, node, ref, prop, obj) {
29688
31041
  const lt = declaredLt(em, ref.platform, t, node);
29689
31042
  if (ref.platform === "ios") {
29690
31043
  if (prop.global) return fromObjc(em, id(prop.global), t, lt, what);
31044
+ if (prop.cFunctions) return fromObjc(em, call$5(prop.cFunctions.getter, obj ? [cfReceiver(ref, obj)] : []), t, lt, what);
29691
31045
  return fromObjc(em, send(objcReceiver(ref, obj), prop.selector ?? prop.name, []), t, lt, what);
29692
31046
  }
29693
31047
  if (plan.backend === "kotlin-shim") return kotlinCall(em, {
@@ -29725,7 +31079,7 @@ function property$1(em, node, ref, prop, obj) {
29725
31079
  lookup: obj ? "field" : "staticField",
29726
31080
  name: prop.name,
29727
31081
  desc: sig,
29728
- access: (id$7) => obj ? envCall(`Get${kind}Field`, jni("unwrap", id("recv_")), id$7) : envCall(`GetStatic${kind}Field`, id("cls_"), id$7),
31082
+ access: (id$12) => obj ? envCall(`Get${kind}Field`, jni("unwrap", id("recv_")), id$12) : envCall(`GetStatic${kind}Field`, id("cls_"), id$12),
29729
31083
  ret: t,
29730
31084
  lt,
29731
31085
  what,
@@ -29793,7 +31147,13 @@ function iosCall(em, node, ref, m, obj, plan, superOf) {
29793
31147
  const a = argsOf(node).map((x, i) => toObjc(em, x, parseSdkType(m.params[i].type, ref.module, tps), plan));
29794
31148
  const throws = plan.error?.detail === "nserror-out";
29795
31149
  const selector = m.selector ?? m.name;
29796
- const code = superOf ? send(cast$3("c", objcPointer(superOf), call$5("lucent::objc::unwrap", [obj.c])), superSelector(selector), a, throws) : send(objcReceiver(ref, obj), selector, a, throws);
31150
+ const c = m.cFunction;
31151
+ const cArgs = c && obj && c.self !== void 0 ? [
31152
+ ...a.slice(0, c.self),
31153
+ cfReceiver(ref, obj),
31154
+ ...a.slice(c.self)
31155
+ ] : a;
31156
+ const code = c ? call$5(c.name, cArgs) : superOf ? send(cast$3("c", objcPointer(superOf), call$5("lucent::objc::unwrap", [obj.c])), superSelector(selector), a, throws) : send(objcReceiver(ref, obj), selector, a, throws);
29797
31157
  const ret = parseSdkType(m.returns, ref.module, tps);
29798
31158
  const what = `${ref.cls.name}.${m.name}()`;
29799
31159
  const lt = declaredLt(em, "ios", ret, node);
@@ -29802,6 +31162,9 @@ function iosCall(em, node, ref, m, obj, plan, superOf) {
29802
31162
  return fromObjc(em, code, ret, lt, what, owned);
29803
31163
  }
29804
31164
  const superSelector = (selector) => `lucentSuper_${selector}`;
31165
+ function cfReceiver(ref, obj) {
31166
+ return cast$3("bridge", type$5(ref.cls.native), call$5("lucent::objc::unwrap", [obj.c]));
31167
+ }
29805
31168
  function objcReceiver(ref, obj) {
29806
31169
  if (!obj) return id(ref.cls.native);
29807
31170
  const type = ref.cls.interface ? protocol(ref.cls.native) : objcPointer(ref.cls.native);
@@ -29818,32 +31181,44 @@ function nativeLvalue(em, target, obj) {
29818
31181
  }
29819
31182
  const decl = resolved(em, target.name)?.valueDeclaration;
29820
31183
  const declaring = decl ? classOfDecl(decl) : void 0;
29821
- if (!declaring || !decl || !ts.isPropertyDeclaration(decl)) return void 0;
31184
+ if (!declaring || !decl || !isSdkPropertyDecl(decl)) return void 0;
29822
31185
  const found = schemaProperty(declaring, decl);
29823
31186
  if (!found || !!found.property.static !== !obj) return void 0;
29824
31187
  const { ref, property: prop } = found;
29825
- const plan = requirePlan(target, ref, prop, "set");
31188
+ const type = em.lt(target);
31189
+ const set = propertySetter(em, target, ref, prop, obj, type);
29826
31190
  const get = property$1(em, target, ref, prop, obj);
31191
+ if (ref.platform !== "android" || !prop.setter) return {
31192
+ get: get.c,
31193
+ set,
31194
+ type
31195
+ };
31196
+ const assign = (v) => propertySetter(em, target, ref, prop, obj, v.t)(v.c);
31197
+ return {
31198
+ get: get.c,
31199
+ set,
31200
+ assign,
31201
+ type
31202
+ };
31203
+ }
31204
+ function propertySetter(em, site, ref, prop, obj, type) {
31205
+ const plan = requirePlan(site, ref, prop, "set");
29827
31206
  const t = parseSdkType(prop.type, ref.module);
29828
- const type = em.lt(target);
29829
31207
  if (prop.swift) {
29830
31208
  const what = `${ref.cls.name}.${prop.name}`;
29831
- const use = swiftUse(target, ref, prop, "set", [t], VOID, what, !obj);
29832
- return {
29833
- get: get.c,
29834
- set: (v) => swiftSet(em, use, obj, v),
29835
- type
29836
- };
31209
+ const use = swiftUse(site, ref, prop, "set", [t], VOID, what, !obj);
31210
+ return (v) => swiftSet(em, use, obj, v);
29837
31211
  }
29838
31212
  if (ref.platform === "ios") {
29839
31213
  const set = (value) => {
29840
31214
  const v = id("v_");
29841
- const one = (x) => t.k === "fn" ? objcBlock(em, target, x, type, t, plan) : toObjcExpr({
31215
+ const one = (x) => t.k === "fn" ? objcBlock(em, site, x, type, t, plan) : toObjcExpr({
29842
31216
  ...t,
29843
31217
  nullable: false
29844
31218
  }, x, false, `${ref.cls.name}.${prop.name}`);
29845
31219
  const conv = t.nullable ? ifPresent(v, one) : one(v);
29846
31220
  const held = varDecl(auto$1, "v_", value);
31221
+ if (prop.cFunctions?.setter) return statementExpr([held, exprStmt$4(call$5(prop.cFunctions.setter, [...obj ? [cfReceiver(ref, obj)] : [], conv]))], v);
29847
31222
  if (!prop.weak) return statementExpr([held, exprStmt$4(send(objcReceiver(ref, obj), prop.setter, [conv]))], v);
29848
31223
  const [r, o] = [id("r_"), id("o_")];
29849
31224
  const keep = call$5("objc_setAssociatedObject", [
@@ -29860,40 +31235,50 @@ function nativeLvalue(em, target, obj) {
29860
31235
  exprStmt$4(send(r, prop.setter, [o]))
29861
31236
  ], v);
29862
31237
  };
29863
- return {
29864
- get: get.c,
29865
- set,
29866
- type
29867
- };
31238
+ return set;
29868
31239
  }
29869
31240
  if (!prop.setter) throw new Error(`${plan.display}: a Java field write its plan refuses`);
29870
- const desc = ref.cls.methods?.find((m) => (m.java ?? m.name) === prop.setter && m.params.length === 1)?.descriptor ?? jniDescriptor([prop.type], "void");
31241
+ const what = `${ref.cls.name}.${prop.name}`;
31242
+ const shim = plan.backend === "kotlin-shim" ? kotlinShim(em.ctx, {
31243
+ node: site,
31244
+ module: ref.module,
31245
+ cls: ref.cls,
31246
+ role: "set",
31247
+ member: prop,
31248
+ instance: !!obj,
31249
+ given: [],
31250
+ wrapped: [],
31251
+ returns: VOID,
31252
+ what
31253
+ }) : void 0;
31254
+ const desc = shim?.descriptor ?? ref.cls.methods?.find((m) => (m.java ?? m.name) === prop.setter && m.params.length === 1)?.descriptor ?? jniDescriptor([prop.type], "void");
31255
+ const recv = obj ? [jni("unwrap", id("recv_"))] : [];
29871
31256
  const set = (value) => {
29872
31257
  const v = id("v_");
29873
- const converted = jniOf(em, target, t, {
31258
+ const converted = jniOf(em, site, t, jniValue(em, ref, site, t, {
29874
31259
  c: v,
29875
31260
  t: type
29876
- });
31261
+ }));
29877
31262
  const call = jniCall(em, {
29878
- node: target,
29879
- cls: ref.cls,
29880
- lookup: obj ? "method" : "staticMethod",
29881
- name: prop.setter,
31263
+ node: site,
31264
+ cls: shim ? {
31265
+ kind: "class",
31266
+ name: shim.name,
31267
+ native: shim.owner
31268
+ } : ref.cls,
31269
+ lookup: obj && !shim ? "method" : "staticMethod",
31270
+ name: shim?.name ?? prop.setter,
29882
31271
  desc,
29883
- access: (id$5) => envCall(`Call${obj ? "" : "Static"}VoidMethod`, obj ? jni("unwrap", id("recv_")) : id("cls_"), id$5, converted),
31272
+ access: (id$4) => shim ? envCall("CallStaticVoidMethod", id("cls_"), id$4, ...recv, converted) : envCall(`Call${obj ? "" : "Static"}VoidMethod`, recv[0] ?? id("cls_"), id$4, converted),
29884
31273
  ret: VOID,
29885
31274
  lt: T.undefined,
29886
- what: `${ref.cls.name}.${prop.name}`,
31275
+ what,
29887
31276
  pre: obj ? [varDecl(auto$1, "recv_", obj.c)] : []
29888
31277
  });
29889
31278
  return statementExpr([varDecl(auto$1, "v_", value), exprStmt$4(call.c)], v);
29890
31279
  };
29891
31280
  noteIncludes(em, ref);
29892
- return {
29893
- get: get.c,
29894
- set,
29895
- type
29896
- };
31281
+ return set;
29897
31282
  }
29898
31283
  function nativeFunctionCall(em, node) {
29899
31284
  if (!ts.isIdentifier(node.expression)) return void 0;
@@ -29912,17 +31297,17 @@ function nativeFunctionCall(em, node) {
29912
31297
  const ret = parseSdkType(f.returns, sdk.module);
29913
31298
  return fromObjc(em, call$5(name, a), ret, declaredLt(em, "ios", ret, node), `${name}()`, owned);
29914
31299
  }
29915
- function nativeConstant(em, id$8) {
29916
- const decl = resolved(em, id$8)?.valueDeclaration;
31300
+ function nativeConstant(em, id$13) {
31301
+ const decl = resolved(em, id$13)?.valueDeclaration;
29917
31302
  const sdk = decl && ts.isVariableDeclaration(decl) ? sdkModuleOf(decl.getSourceFile()) : void 0;
29918
31303
  if (!sdk) return void 0;
29919
- const c = findSdkModule(sdk.platform, sdk.module).constants?.find((x) => x.name === id$8.text);
29920
- if (!c) fail$2(id$8, Codes.UnsupportedSyntax, `${id$8.text} has no binding`);
29921
- requirePlan(id$8, sdk, c, "get");
31304
+ const c = findSdkModule(sdk.platform, sdk.module).constants?.find((x) => x.name === id$13.text);
31305
+ if (!c) fail$2(id$13, Codes.UnsupportedSyntax, `${id$13.text} has no binding`);
31306
+ requirePlan(id$13, sdk, c, "get");
29922
31307
  const ct = parseSdkType(c.type, sdk.module);
29923
- if (c.swift) return swiftCall(em, swiftUse(id$8, sdk, c, "get", [], ct, c.name, true), void 0, []);
31308
+ if (c.swift) return swiftCall(em, swiftUse(id$13, sdk, c, "get", [], ct, c.name, true), void 0, []);
29924
31309
  noteFramework(em, sdk.module);
29925
- return fromObjc(em, id(c.name), ct, declaredLt(em, "ios", ct, id$8), c.name);
31310
+ return fromObjc(em, id(c.name), ct, declaredLt(em, "ios", ct, id$13), c.name);
29926
31311
  }
29927
31312
  function noteFramework(em, module) {
29928
31313
  const schema = loadSdkModule("ios", module);
@@ -29936,6 +31321,7 @@ function linkModule(em, schema) {
29936
31321
  for (const f of schema.frameworks ?? []) em.ctx.frameworks.add(f);
29937
31322
  const artifact = schema.provenance?.artifact;
29938
31323
  if (artifact?.startsWith("pod:")) em.ctx.pods.add(artifact.slice(4).split("@")[0]);
31324
+ if (artifact?.startsWith("spm:")) em.ctx.swiftPackages.add(artifact.slice(4));
29939
31325
  }
29940
31326
  function androidCall(em, node, ref, m, obj, plan) {
29941
31327
  const tps = m.typeParams ?? [];
@@ -30109,6 +31495,12 @@ function nativeBuiltinCall(em, node) {
30109
31495
  c: call$5("lucent::jni::currentActivity"),
30110
31496
  t: em.lt(node)
30111
31497
  };
31498
+ case "lucent:android.errorOf":
31499
+ unit.include("lucent/platform/android.h");
31500
+ return {
31501
+ c: call$5("lucent::jni::errorOf", [em.exprAs(args[0], declaredArg(em, args[0]))]),
31502
+ t: T.error
31503
+ };
30112
31504
  case "lucent:android.startActivityForResult":
30113
31505
  case "lucent:android.requestPermissions": {
30114
31506
  unit.include("lucent/platform/android.h");
@@ -30185,7 +31577,7 @@ function kotlinCall(em, call) {
30185
31577
  lookup: "staticMethod",
30186
31578
  name: shim.name,
30187
31579
  desc: shim.descriptor,
30188
- access: (id$4) => envCall(`CallStatic${kind}Method`, id("cls_"), id$4, ...recv, ...a),
31580
+ access: (id$6) => envCall(`CallStatic${kind}Method`, id("cls_"), id$6, ...recv, ...a),
30189
31581
  ret: returns,
30190
31582
  lt: call.lt ?? declaredLt(em, "android", returns, node),
30191
31583
  what,
@@ -30268,6 +31660,200 @@ function nativeInstanceOf(em, node) {
30268
31660
  t: T.boolean
30269
31661
  };
30270
31662
  }
31663
+ function sdkTagClass(em, tag) {
31664
+ return ts.isIdentifier(tag) || ts.isPropertyAccessExpression(tag) ? sdkClassNamed(em, tag) : void 0;
31665
+ }
31666
+ function viewNew(em, site, ref, construction, lt) {
31667
+ const owner = findSdkType(ref.platform, construction.module, construction.owner);
31668
+ const declaring = owner?.kind === "class" ? {
31669
+ ...ref,
31670
+ module: construction.module,
31671
+ cls: owner
31672
+ } : ref;
31673
+ const what = `<${ref.cls.name}>`;
31674
+ requireMain(em, site, ref);
31675
+ requirePlan(site, declaring, construction.ctor, "new");
31676
+ requireAvailable(em, site, ref, ref.cls.since, ref.cls.name);
31677
+ requireAvailable(em, site, ref, construction.ctor.since, what);
31678
+ if (construction.ctor.swift) fail$2(site, Codes.NativeViewJsx, `${ref.cls.name} is made through Swift: make it with create={() => new ${ref.cls.name}(…)}`);
31679
+ noteIncludes(em, ref);
31680
+ if (ref.platform === "ios") {
31681
+ const alloc = send$1(ref.cls.native, "alloc");
31682
+ const frame = construction.kind === "frame" ? [id("CGRectZero")] : [];
31683
+ const made = send(alloc, construction.ctor.selector ?? "init", frame);
31684
+ return {
31685
+ c: call$5("lucent::objc::wrap", [made, str$5(what)]),
31686
+ t: lt
31687
+ };
31688
+ }
31689
+ const self = {
31690
+ k: "ref",
31691
+ module: ref.module,
31692
+ name: ref.cls.name,
31693
+ nullable: false
31694
+ };
31695
+ const desc = construction.ctor.descriptor ?? jniDescriptor(construction.ctor.params.map((p) => p.type), "void");
31696
+ return jniCall(em, {
31697
+ node: site,
31698
+ cls: ref.cls,
31699
+ lookup: "method",
31700
+ name: "<init>",
31701
+ desc,
31702
+ access: (id$10) => envCall("NewObject", id("cls_"), id$10, jni("unwrap", id("context_"))),
31703
+ ret: self,
31704
+ lt,
31705
+ what,
31706
+ pre: [varDecl(auto$1, "context_", jni("viewContext"))]
31707
+ });
31708
+ }
31709
+ function takes(t, lt) {
31710
+ const v = stripOpt(lt);
31711
+ switch (t.k) {
31712
+ case "string": return v.k === "string";
31713
+ case "prim": return t.name === "boolean" || t.name === "bool" ? v.k === "boolean" : isWideInteger(t.name) ? v.k === "bigint" : v.k === "number";
31714
+ default: return ![
31715
+ "string",
31716
+ "boolean",
31717
+ "number",
31718
+ "bigint"
31719
+ ].includes(v.k);
31720
+ }
31721
+ }
31722
+ function jniValue(em, ref, site, t, value) {
31723
+ const as = (lt) => ({
31724
+ c: em.coerce(value, lt, site),
31725
+ t: lt
31726
+ });
31727
+ switch (t.k) {
31728
+ case "prim": return as(primLt(t));
31729
+ case "string": return as(t.nullable ? unionOf([T.string, T.null]) : T.string);
31730
+ case "array": {
31731
+ const lt = declaredLt(em, ref.platform, {
31732
+ ...t,
31733
+ nullable: false
31734
+ }, site);
31735
+ return as(t.nullable ? unionOf([lt, T.null]) : lt);
31736
+ }
31737
+ case "ref": {
31738
+ if (value.t.k === "fn" || eitherMembers(value.t)) return value;
31739
+ const lt = {
31740
+ k: "native",
31741
+ platform: ref.platform,
31742
+ module: t.module,
31743
+ name: t.name
31744
+ };
31745
+ return as(t.nullable ? unionOf([lt, T.null]) : lt);
31746
+ }
31747
+ default: return value;
31748
+ }
31749
+ }
31750
+ function setterCall(em, site, ref, overloads, obj, value) {
31751
+ const method = overloads.find((m) => takes(parseSdkType(m.params[0].type, ref.module), value.t)) ?? overloads[0];
31752
+ const t = parseSdkType(method.params[0].type, ref.module);
31753
+ const what = `${ref.cls.name}.${method.name}`;
31754
+ requirePlan(site, ref, method, "call");
31755
+ requireMain(em, site, ref, method);
31756
+ requireAvailable(em, site, ref, method.since, what);
31757
+ noteIncludes(em, ref);
31758
+ return jniCall(em, {
31759
+ node: site,
31760
+ cls: ref.cls,
31761
+ lookup: "method",
31762
+ name: method.java ?? method.name,
31763
+ desc: method.descriptor ?? jniDescriptor([method.params[0].type], "void"),
31764
+ access: (id$11) => envCall("CallVoidMethod", jni("unwrap", id("recv_")), id$11, jniOf(em, site, t, jniValue(em, ref, site, t, value))),
31765
+ ret: VOID,
31766
+ lt: T.undefined,
31767
+ what,
31768
+ pre: [varDecl(auto$1, "recv_", obj.c)]
31769
+ }).c;
31770
+ }
31771
+ function insertChild(em, site, ref, method, parent, child, index) {
31772
+ const what = `${ref.cls.name}.${method.selector ?? method.name}`;
31773
+ const childType = parseSdkType(method.params[0].type, ref.module);
31774
+ requirePlan(site, ref, method, "call");
31775
+ requireMain(em, site, ref, method);
31776
+ requireAvailable(em, site, ref, method.since, what);
31777
+ noteIncludes(em, ref);
31778
+ if (ref.platform === "ios") return send(objcReceiver(ref, parent), method.selector, [toObjcExpr({
31779
+ ...childType,
31780
+ nullable: false
31781
+ }, child.c, false, what), num$5(index)]);
31782
+ return jniCall(em, {
31783
+ node: site,
31784
+ cls: ref.cls,
31785
+ lookup: "method",
31786
+ name: method.java ?? method.name,
31787
+ desc: method.descriptor ?? jniDescriptor(method.params.map((p) => p.type), "void"),
31788
+ access: (id$8) => envCall("CallVoidMethod", jni("unwrap", id("recv_")), id$8, jni("unwrap", id("child_")), staticCast(type$5("jint"), num$5(index))),
31789
+ ret: VOID,
31790
+ lt: T.undefined,
31791
+ what,
31792
+ pre: [varDecl(auto$1, "recv_", parent.c), varDecl(auto$1, "child_", child.c)]
31793
+ }).c;
31794
+ }
31795
+ function listenerEvent(em, site, ref, setter, obj, handler) {
31796
+ const listener = parseSdkType(setter.params[0].type, ref.module);
31797
+ if (listener.k !== "ref") throw new Error(`${setter.name}: its listener is no class`);
31798
+ const what = `${ref.cls.name}.${setter.name}`;
31799
+ requirePlan(site, ref, setter, "call");
31800
+ requireMain(em, site, ref, setter);
31801
+ requireAvailable(em, site, ref, setter.since, what);
31802
+ noteIncludes(em, ref);
31803
+ const call = (given) => jniCall(em, {
31804
+ node: site,
31805
+ cls: ref.cls,
31806
+ lookup: "method",
31807
+ name: setter.java ?? setter.name,
31808
+ desc: setter.descriptor ?? jniDescriptor([setter.params[0].type], "void"),
31809
+ access: (id$5) => envCall("CallVoidMethod", jni("unwrap", id("recv_")), id$5, given),
31810
+ ret: VOID,
31811
+ lt: T.undefined,
31812
+ what,
31813
+ pre: [varDecl(auto$1, "recv_", obj.c)]
31814
+ }).c;
31815
+ return {
31816
+ add: call(javaProxy(em, site, handler, {
31817
+ ...listener,
31818
+ nullable: false
31819
+ })),
31820
+ remove: call(id("nullptr"))
31821
+ };
31822
+ }
31823
+ function controlEvent(em, site, ref, tag, register, value, obj, handler) {
31824
+ const what = `${ref.cls.name}.${register.selector}`;
31825
+ const fn = {
31826
+ k: "fn",
31827
+ params: [{
31828
+ k: "ref",
31829
+ module: tag.module,
31830
+ name: tag.cls.name,
31831
+ nullable: false
31832
+ }],
31833
+ ret: VOID,
31834
+ escaping: true,
31835
+ main: true,
31836
+ nullable: false
31837
+ };
31838
+ requirePlan(site, ref, register, "call");
31839
+ requireAvailable(em, site, ref, register.since, what);
31840
+ noteIncludes(em, ref);
31841
+ em.ctx.nativeUnit(em.opts.module).include("lucent/platform/ios_ui.h");
31842
+ const block = objcBlock(em, site, handler.c, handler.t, fn, { display: what });
31843
+ const control = call$5("lucent::objc::unwrap", [obj.c]);
31844
+ return {
31845
+ add: call$5("lucent::objc::addControlAction", [
31846
+ control,
31847
+ num$5(value),
31848
+ block
31849
+ ]),
31850
+ remove: (action) => call$5("lucent::objc::removeControlAction", [
31851
+ control,
31852
+ action,
31853
+ num$5(value)
31854
+ ])
31855
+ };
31856
+ }
30271
31857
  //#endregion
30272
31858
  //#region ../compiler/src/emit/extensions.ts
30273
31859
  function handleNew(em, node, t) {
@@ -31529,6 +33115,7 @@ var FnEmitter = class {
31529
33115
  const il = this.intLocal(target);
31530
33116
  if (il) return staticCast(type$5("double"), assign$4(id(il.cpp), this.toKind(value, il.int, node)));
31531
33117
  const lv = this.lvalue(target);
33118
+ if (lv.assign) return lv.assign(value);
31532
33119
  const v = this.coerce(value, lv.type, node);
31533
33120
  if (lv.direct) return assign$4(lv.direct, v);
31534
33121
  return lv.set(v);
@@ -31662,7 +33249,8 @@ var FnEmitter = class {
31662
33249
  lvalueType(target) {
31663
33250
  try {
31664
33251
  if (ts.isArrayLiteralExpression(target)) return void 0;
31665
- return this.lvalue(target).type;
33252
+ const lv = this.lvalue(target);
33253
+ return lv.assign ? void 0 : lv.type;
31666
33254
  } catch {
31667
33255
  return;
31668
33256
  }
@@ -33070,7 +34658,7 @@ function leafHost(ctx, opts) {
33070
34658
  place: (target, operands) => {
33071
34659
  const lv = new LeafEmitter(ctx, opts, target, operands).lvalue(target);
33072
34660
  const name = nameOf$2(target);
33073
- const { direct, set } = lv;
34661
+ const { direct, set, assign } = lv;
33074
34662
  if (!direct && !set) throw new IrUnsupported(target, "a place that cannot be written");
33075
34663
  return {
33076
34664
  type: lv.type,
@@ -33083,7 +34671,15 @@ function leafHost(ctx, opts) {
33083
34671
  name: `${name} =`,
33084
34672
  code: direct ? assign$4(direct, operand(v)) : set(operand(v)),
33085
34673
  type: T.void
33086
- })
34674
+ }),
34675
+ ...assign ? { assign: (v, from) => ({
34676
+ name: `${name} =`,
34677
+ code: assign({
34678
+ c: operand(v),
34679
+ t: from
34680
+ }),
34681
+ type: T.void
34682
+ }) } : {}
33087
34683
  };
33088
34684
  }
33089
34685
  };
@@ -38291,7 +39887,7 @@ function emitProgram(lp, target = lp.platform ?? "all", components = /* @__PURE_
38291
39887
  decls: [
38292
39888
  { k: "pragmaOnce" },
38293
39889
  include("lucent/lucent.h", true),
38294
- ...lp.modules.some((m) => /["']lucent:ui["']/.test(m.sourceFile.text)) ? [include("lucent/view.h", true)] : [],
39890
+ ...setups.size || lp.modules.some((m) => /["']lucent:ui["']/.test(m.sourceFile.text)) ? [include("lucent/view.h", true)] : [],
38295
39891
  ...shielded([...readers.decls.length ? [
38296
39892
  app(types),
38297
39893
  namespace("lucent", readers.decls),
@@ -38361,6 +39957,7 @@ function emitProgram(lp, target = lp.platform ?? "all", components = /* @__PURE_
38361
39957
  warnings: ctx.warnings,
38362
39958
  frameworks: [...ctx.frameworks].sort(),
38363
39959
  pods: [...ctx.pods].sort(),
39960
+ swiftPackages: [...ctx.swiftPackages].sort(),
38364
39961
  java,
38365
39962
  javaKeep: [...ctx.javaClasses].sort(),
38366
39963
  kotlin: new Map([...kotlinFiles(ctx), ...toolkitFiles(ctx, "compose")]),
@@ -40432,21 +42029,21 @@ function attributes(from, names) {
40432
42029
  return Object.fromEntries(names.filter((n) => from[n] !== void 0).map((n) => [`android:${n}`, String(from[n])]));
40433
42030
  }
40434
42031
  function componentElement(c) {
40435
- const named = (tag) => (name) => element$1(tag, { "android:name": name });
40436
- const children = [...(c.intentFilters ?? []).map((f) => element$1("intent-filter", {}, [
42032
+ const named = (tag) => (name) => element$2(tag, { "android:name": name });
42033
+ const children = [...(c.intentFilters ?? []).map((f) => element$2("intent-filter", {}, [
40437
42034
  ...f.actions.map(named("action")),
40438
42035
  ...(f.categories ?? []).map(named("category")),
40439
- ...(f.data ?? []).map((d) => element$1("data", attributes(d, DATA_ATTRIBUTES)))
40440
- ])), ...Object.entries(c.metaData ?? {}).map(([name, value]) => element$1("meta-data", {
42036
+ ...(f.data ?? []).map((d) => element$2("data", attributes(d, DATA_ATTRIBUTES)))
42037
+ ])), ...Object.entries(c.metaData ?? {}).map(([name, value]) => element$2("meta-data", {
40441
42038
  "android:name": name,
40442
42039
  "android:value": value
40443
42040
  }))];
40444
- return element$1(c.kind, attributes(c, COMPONENT_ATTRIBUTES), children.length ? children : void 0);
42041
+ return element$2(c.kind, attributes(c, COMPONENT_ATTRIBUTES), children.length ? children : void 0);
40445
42042
  }
40446
42043
  function androidManifest(permissions, components = []) {
40447
42044
  return printDocument({
40448
42045
  comment: "Generated by Lucent. Do not edit.",
40449
- root: element$1("manifest", { "xmlns:android": "http://schemas.android.com/apk/res/android" }, [...permissions.map((p) => element$1("uses-permission", { "android:name": p })), element$1("application", {}, [...RUNTIME_COMPONENTS, ...components].map(componentElement))])
42046
+ root: element$2("manifest", { "xmlns:android": "http://schemas.android.com/apk/res/android" }, [...permissions.map((p) => element$2("uses-permission", { "android:name": p })), element$2("application", {}, [...RUNTIME_COMPONENTS, ...components].map(componentElement))])
40450
42047
  });
40451
42048
  }
40452
42049
  function consumerRules(classes) {
@@ -40462,6 +42059,27 @@ function jsxToolkits() {
40462
42059
  return Object.fromEntries(Object.keys(TOOLKITS).map((name) => [TOOLKITS[name].platform, name]));
40463
42060
  }
40464
42061
  //#endregion
42062
+ //#region ../compiler/src/ui/view-coverage.ts
42063
+ function viewCoverage(schema, moduleOf) {
42064
+ if (!fabricRequested()) return void 0;
42065
+ const find = (module, name) => module === schema.module ? schema.types.find((t) => t.name === name) : moduleOf(module)?.types.find((t) => t.name === name);
42066
+ return schema.types.filter((t) => t.kind === "class" && !t.interface && isViewClass(t, schema, find)).map((cls) => {
42067
+ const rules = viewRules(cls, schema, find);
42068
+ const explained = (x) => ({
42069
+ name: x.name,
42070
+ explanation: x.explanation
42071
+ });
42072
+ return {
42073
+ view: cls.name,
42074
+ made: viewConstruction(cls, schema, find).kind,
42075
+ props: rules.props.map(explained),
42076
+ events: rules.events.map(explained),
42077
+ ...rules.children ? { children: rules.children.explanation } : {},
42078
+ leftOut: rules.refused
42079
+ };
42080
+ });
42081
+ }
42082
+ //#endregion
40465
42083
  //#region ../compiler/src/ui/android.ts
40466
42084
  const JAVA = "android/src/main/java/dev/lucent";
40467
42085
  const DESCRIPTORS_HEADER = "android/include/react/renderer/components/lucentnative/ComponentDescriptors.h";
@@ -40609,8 +42227,8 @@ function writeNativePackage(result, outDir, options = {}) {
40609
42227
  resources: inPackage(native?.ios.resources ?? []),
40610
42228
  resourceBundles: Object.entries(native?.ios.resourceBundles ?? {}).map(([name, paths]) => [name, inPackage(paths)]),
40611
42229
  vendoredFrameworks: inPackage(native?.ios.vendoredFrameworks ?? []),
40612
- swiftPackages: Object.entries(native?.ios.swiftPackages ?? {}),
40613
- deploymentTarget: native?.ios.deploymentTarget?.value
42230
+ swiftPackages: [...Object.entries(native?.ios.swiftPackages ?? {}), ...appSwiftPackages(result.swiftPackages ?? [], options.app?.swiftPackages ?? [])],
42231
+ deploymentTarget: highestVersion([native?.ios.deploymentTarget?.value, options.app?.deploymentTarget])
40614
42232
  }));
40615
42233
  const gradle = path.join(outDir, "android/build.gradle");
40616
42234
  want.set(gradle, options.androidDeferred ? deferredLibraryGradle(options.native) : libraryBuildGradle(want.get(gradle).toString(), options.native, !!result.kotlin?.size, result.compose ? [...result.kotlin].filter(([f]) => f.startsWith("dev/lucent/compose/")).map(([, t]) => t) : []));
@@ -40680,6 +42298,21 @@ function writeWhole(file, content) {
40680
42298
  fs.writeFileSync(tmp, content);
40681
42299
  fs.renameSync(tmp, file);
40682
42300
  }
42301
+ function appSwiftPackages(used, pins) {
42302
+ return pins.filter((p) => used.some((u) => u.slice(0, u.lastIndexOf("@")) === p.identity)).map((p) => [p.location, {
42303
+ requirement: p.version ? {
42304
+ kind: "exactVersion",
42305
+ version: p.version
42306
+ } : {
42307
+ kind: "revision",
42308
+ revision: p.revision
42309
+ },
42310
+ products: p.products
42311
+ }]);
42312
+ }
42313
+ function highestVersion(versions) {
42314
+ return versions.filter((v) => !!v).sort(compareVersions).at(-1);
42315
+ }
40683
42316
  //#endregion
40684
42317
  //#region ../compiler/src/sdk/modules.ts
40685
42318
  const composing = (platform) => platform === "android" && fabricRequested();
@@ -40768,6 +42401,7 @@ function compileWith(files, options) {
40768
42401
  if (target === "ios") {
40769
42402
  out.frameworks = result.frameworks;
40770
42403
  out.pods = result.pods;
42404
+ out.swiftPackages = result.swiftPackages;
40771
42405
  }
40772
42406
  if (target === "android") {
40773
42407
  out.java = result.java;
@@ -40877,4 +42511,4 @@ function report(diagnostics) {
40877
42511
  return diagnostics.map(formatDiagnostic).join("\n");
40878
42512
  }
40879
42513
  //#endregion
40880
- export { sdkSchemaEntry as $, findLucentFiles as A, diffModule as B, bindExtensions as C, LUCENT_EXTENSION as D, identityScript as E, moduleNamespace as F, cachedModules as G, displayName as H, extensionDts as I, forgetLoadedSdks as J, cachedSchema as K, sdkDts as L, platformOf as M, projectFiles as N, coreJsPath as O, usesPlatforms as P, sdkNames as Q, coverage as R, inNativePackage as S, RUNTIME_ABI as T, symbolKey as U, diffSymbols as V, podsSearchPaths as W, sdkAvailable as X, prefetch as Y, sdkModuleArtifacts as Z, VIEW_CONTRACT_VERSION as _, report as a, PACKAGE_FIELDS as b, sdkModules as c, isUpToDate as d, sdkSourceModule as et, runtimeDir as f, libraryBuildGradle as g, toolkitsFrom as h, projectExtensions as i, moduleNameOf as j, coreTypesPath as k, deferredLibraryGradle as l, jsxToolkits as m, compile as n, sdkDeclarations as o, writeNativePackage as p, extractionCount as q, compileDirectory as r, sdkModule as s, checkSources as t, formatDiagnostic as tt, inputsKey as u, resolveNative as v, forgetExtensionHeaders as w, fileHashes as x, EXTENSION_FIELDS as y, compareArtifacts as z };
42514
+ export { sdkNames as $, coreTypesPath as A, compareArtifacts as B, inNativePackage as C, identityScript as D, RUNTIME_ABI as E, usesPlatforms as F, podsSearchPaths as G, diffSymbols as H, moduleNamespace as I, extractionCount as J, cachedModules as K, extensionDts as L, moduleNameOf as M, platformOf as N, LUCENT_EXTENSION as O, projectFiles as P, sdkModuleArtifacts as Q, sdkDts as R, fileHashes as S, forgetExtensionHeaders as T, displayName as U, diffModule as V, symbolKey as W, prefetch as X, forgetLoadedSdks as Y, sdkAvailable as Z, libraryBuildGradle as _, report as a, EXTENSION_FIELDS as b, sdkModules as c, isUpToDate as d, sdkSchemaEntry as et, runtimeDir as f, toolkitsFrom as g, jsxToolkits as h, projectExtensions as i, formatDiagnostic as it, findLucentFiles as j, coreJsPath as k, deferredLibraryGradle as l, viewCoverage as m, compile as n, cacheRoot as nt, sdkDeclarations as o, writeNativePackage as p, cachedSchema as q, compileDirectory as r, hash$2 as rt, sdkModule as s, checkSources as t, sdkSourceModule as tt, inputsKey as u, VIEW_CONTRACT_VERSION as v, bindExtensions as w, PACKAGE_FIELDS as x, resolveNative as y, coverage as z };