@idlizer/arktscgen 2.1.10-arktscgen-6 → 2.1.10-arktscgen-9

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 (41) hide show
  1. package/build/libarkts-copy/generator/options.json5 +88 -97
  2. package/build/libarkts-copy/native/meson.build +60 -7
  3. package/build/libarkts-copy/native/mingw.cross +2 -5
  4. package/build/libarkts-copy/native/src/bridges.cpp +175 -0
  5. package/build/libarkts-copy/native/src/{common.cc → common.cpp} +176 -139
  6. package/build/libarkts-copy/native/src/common.h +22 -37
  7. package/build/libarkts-copy/native/src/{memoryTracker.cc → memoryTracker.cpp} +9 -3
  8. package/build/libarkts-copy/package.json +5 -9
  9. package/build/libarkts-copy/src/Es2pandaNativeModule.ts +0 -56
  10. package/build/libarkts-copy/src/arkts-api/ImportStorage.ts +8 -3
  11. package/build/libarkts-copy/src/arkts-api/factory/nodeFactory.ts +4 -0
  12. package/build/libarkts-copy/src/arkts-api/index.ts +0 -2
  13. package/build/libarkts-copy/src/arkts-api/node-utilities/OpaqueTypeNode.ts +1 -1
  14. package/build/libarkts-copy/src/arkts-api/node-utilities/OverloadDeclaration.ts +29 -0
  15. package/build/libarkts-copy/src/arkts-api/peers/Context.ts +25 -59
  16. package/build/libarkts-copy/src/arkts-api/peers/ExternalSource.ts +8 -13
  17. package/build/libarkts-copy/src/arkts-api/plugins.ts +5 -12
  18. package/build/libarkts-copy/src/arkts-api/static/global.ts +8 -4
  19. package/build/libarkts-copy/src/arkts-api/static/profiler.ts +4 -4
  20. package/build/libarkts-copy/src/arkts-api/utilities/extensions.ts +9 -12
  21. package/build/libarkts-copy/src/arkts-api/utilities/private.ts +10 -34
  22. package/build/libarkts-copy/src/arkts-api/utilities/public.ts +8 -5
  23. package/build/libarkts-copy/src/index.ts +0 -2
  24. package/build/libarkts-copy/src/plugin-utils.ts +60 -34
  25. package/build/libarkts-copy/src/reexport-for-generated.ts +3 -2
  26. package/build/libarkts-copy/tsconfig.json +0 -3
  27. package/lib/index.js +505 -216
  28. package/package.json +3 -4
  29. package/templates/Es2pandaNativeModule.ts +1 -0
  30. package/templates/{bridges.cc → bridges.cpp} +1 -1
  31. package/templates/peer.ts +1 -0
  32. package/build/libarkts-copy/native/src/bridges.cc +0 -443
  33. package/build/libarkts-copy/src/arkts-api/node-utilities/Program.ts +0 -45
  34. package/build/libarkts-copy/src/ts-api/factory/nodeFactory.ts +0 -1250
  35. package/build/libarkts-copy/src/ts-api/factory/nodeTests.ts +0 -125
  36. package/build/libarkts-copy/src/ts-api/index.ts +0 -27
  37. package/build/libarkts-copy/src/ts-api/static/enums.ts +0 -18
  38. package/build/libarkts-copy/src/ts-api/types.ts +0 -1075
  39. package/build/libarkts-copy/src/ts-api/utilities/private.ts +0 -292
  40. package/build/libarkts-copy/src/ts-api/utilities/public.ts +0 -55
  41. package/build/libarkts-copy/src/ts-api/visitor/visitor.ts +0 -139
package/lib/index.js CHANGED
@@ -261,6 +261,9 @@ function isReferenceType(type) {
261
261
  function isEnum(type) {
262
262
  return type.kind == IDLKind.Enum;
263
263
  }
264
+ function isEnumMember(type) {
265
+ return type.kind == IDLKind.EnumMember;
266
+ }
264
267
  function isUnionType(type) {
265
268
  return type.kind == IDLKind.UnionType;
266
269
  }
@@ -775,8 +778,9 @@ class IDLWriter {
775
778
  printProperty(idl) {
776
779
  const staticMod = idl.isStatic ? "static " : "";
777
780
  const readonlyMod = idl.isReadonly ? "readonly " : "";
781
+ const optional = idl.isOptional ? "optional " : "";
778
782
  return this.printExtendedAttributes(idl)
779
- .print(`${staticMod}${readonlyMod}attribute ${nameWithType(idl)};`);
783
+ .print(`${staticMod}${readonlyMod}${optional}attribute ${nameWithType(idl)};`);
780
784
  }
781
785
  printExtendedAttributes(idl) {
782
786
  var _a;
@@ -1566,11 +1570,144 @@ function convertType(convertor, type) {
1566
1570
  return convertor.convertPrimitiveType(type);
1567
1571
  throw new Error(`Unknown type ${IDLKind[type.kind]}`);
1568
1572
  }
1573
+ function convertDeclaration(convertor, decl) {
1574
+ if (isImport(decl))
1575
+ return convertor.convertImport(decl);
1576
+ if (isNamespace(decl))
1577
+ return convertor.convertNamespace(decl);
1578
+ if (isInterface(decl))
1579
+ return convertor.convertInterface(decl);
1580
+ if (isEnum(decl))
1581
+ return convertor.convertEnum(decl);
1582
+ if (isEnumMember(decl))
1583
+ return convertor.convertEnum(decl.parent);
1584
+ if (isTypedef(decl))
1585
+ return convertor.convertTypedef(decl);
1586
+ if (isCallback(decl))
1587
+ return convertor.convertCallback(decl);
1588
+ if (isMethod(decl))
1589
+ return convertor.convertMethod(decl);
1590
+ if (isConstant(decl))
1591
+ return convertor.convertConstant(decl);
1592
+ throw new Error(`Unknown declaration type ${decl.kind ? IDLKind[decl.kind] : "(undefined kind)"}`);
1593
+ }
1569
1594
  function withInsideInstanceof(isInsideInstanceof, op) {
1570
1595
  const result = op();
1571
1596
  return result;
1572
1597
  }
1573
1598
 
1599
+ /*
1600
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
1601
+ * Licensed under the Apache License, Version 2.0 (the "License");
1602
+ * you may not use this file except in compliance with the License.
1603
+ * You may obtain a copy of the License at
1604
+ *
1605
+ * http://www.apache.org/licenses/LICENSE-2.0
1606
+ *
1607
+ * Unless required by applicable law or agreed to in writing, software
1608
+ * distributed under the License is distributed on an "AS IS" BASIS,
1609
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1610
+ * See the License for the specific language governing permissions and
1611
+ * limitations under the License.
1612
+ */
1613
+ class DeclarationNameConvertor {
1614
+ convertImport(decl) {
1615
+ console.warn("Imports are not implemented yet");
1616
+ return decl.name;
1617
+ }
1618
+ convertInterface(decl) {
1619
+ return decl.name;
1620
+ }
1621
+ convertEnum(decl) {
1622
+ return `${getNamespacesPathFor(decl).join('')}${decl.name}`;
1623
+ }
1624
+ convertTypedef(decl) {
1625
+ return decl.name;
1626
+ }
1627
+ convertCallback(decl) {
1628
+ var _a;
1629
+ return (_a = decl.name) !== null && _a !== void 0 ? _a : "MISSING CALLBACK NAME";
1630
+ }
1631
+ convertNamespace(node) {
1632
+ return node.name;
1633
+ }
1634
+ convertMethod(node) {
1635
+ return node.name;
1636
+ }
1637
+ convertConstant(node) {
1638
+ return node.name;
1639
+ }
1640
+ }
1641
+ DeclarationNameConvertor.I = new DeclarationNameConvertor();
1642
+ class TSFeatureNameConvertor extends DeclarationNameConvertor {
1643
+ convertEnum(decl) {
1644
+ const namespace = getNamespacesPathFor(decl).map(it => it.name);
1645
+ if (namespace.length > 0)
1646
+ return namespace[0];
1647
+ return decl.name;
1648
+ }
1649
+ }
1650
+ TSFeatureNameConvertor.I = new TSFeatureNameConvertor();
1651
+ class ETSDeclarationNameConvertor extends DeclarationNameConvertor {
1652
+ convertInterface(decl) {
1653
+ return getQualifiedName(decl, "namespace.name");
1654
+ }
1655
+ convertEnum(decl) {
1656
+ return getQualifiedName(decl, "namespace.name");
1657
+ }
1658
+ }
1659
+ ETSDeclarationNameConvertor.I = new ETSDeclarationNameConvertor();
1660
+ class CJDeclarationNameConvertor extends DeclarationNameConvertor {
1661
+ convertInterface(decl) {
1662
+ return decl.name;
1663
+ }
1664
+ convertEnum(decl) {
1665
+ return decl.name;
1666
+ }
1667
+ }
1668
+ CJDeclarationNameConvertor.I = new CJDeclarationNameConvertor();
1669
+ class KotlinDeclarationNameConvertor extends DeclarationNameConvertor {
1670
+ convertInterface(decl) {
1671
+ return removePoints(getQualifiedName(decl, "namespace.name"));
1672
+ }
1673
+ convertEnum(decl) {
1674
+ return removePoints(getQualifiedName(decl, "namespace.name"));
1675
+ }
1676
+ }
1677
+ KotlinDeclarationNameConvertor.I = new KotlinDeclarationNameConvertor();
1678
+ class ETSFeatureNameConvertor extends DeclarationNameConvertor {
1679
+ convertEnum(decl) {
1680
+ const namespace = getNamespacesPathFor(decl).map(it => it.name);
1681
+ if (namespace.length > 0)
1682
+ return namespace[0];
1683
+ return decl.name;
1684
+ }
1685
+ }
1686
+ ETSFeatureNameConvertor.I = new ETSFeatureNameConvertor();
1687
+ class CJFeatureNameConvertor extends DeclarationNameConvertor {
1688
+ convertEnum(decl) {
1689
+ return decl.name;
1690
+ }
1691
+ }
1692
+ CJFeatureNameConvertor.I = new CJFeatureNameConvertor();
1693
+ class KotlinFeatureNameConvertor extends DeclarationNameConvertor {
1694
+ convertInterface(decl) {
1695
+ return removePoints(getQualifiedName(decl, "namespace.name"));
1696
+ }
1697
+ convertEnum(decl) {
1698
+ return removePoints(getQualifiedName(decl, "namespace.name"));
1699
+ }
1700
+ }
1701
+ KotlinFeatureNameConvertor.I = new KotlinFeatureNameConvertor();
1702
+ function createDeclarationNameConvertor(language) {
1703
+ switch (language) {
1704
+ case Language.ARKTS: return ETSDeclarationNameConvertor.I;
1705
+ case Language.CPP:
1706
+ case Language.TS: return DeclarationNameConvertor.I;
1707
+ case Language.CJ: case Language.KOTLIN: default: throw new Error(`Language ${language.toString()} is not supported`);
1708
+ }
1709
+ }
1710
+
1574
1711
  /*
1575
1712
  * Copyright (c) 2024 Huawei Device Co., Ltd.
1576
1713
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -1796,28 +1933,33 @@ class TsEnumEntityStatement {
1796
1933
  this.options = options;
1797
1934
  }
1798
1935
  write(writer) {
1799
- // writer.print(this.enumEntity.comment)
1800
- writer.print(`${this.options.isExport ? "export " : ""}${this.options.isDeclare ? "declare " : ""}enum ${this.enumEntity.name} {`);
1801
- writer.pushIndent();
1936
+ let enumName = convertDeclaration(createDeclarationNameConvertor(Language.ARKTS), this.enumEntity);
1937
+ enumName = enumName.split('.').at(-1);
1938
+ const correctStyleNames = [];
1939
+ const originalStyleNames = [];
1802
1940
  this.enumEntity.elements.forEach((member, index) => {
1803
- // writer.print(member.comment)
1804
- const initValue = member.initializer
1805
- ? ` = ${this.maybeQuoted(member.initializer)}` : ``;
1806
- writer.print(`${member.name}${initValue},`);
1807
- let originalName = getExtAttribute(member, IDLExtendedAttributes.OriginalEnumMemberName);
1808
- if (originalName) {
1809
- const initValue = ` = ${member.name}`;
1810
- writer.print(`${originalName}${initValue},`);
1811
- }
1941
+ var _a;
1942
+ const initText = (_a = member.initializer) !== null && _a !== void 0 ? _a : index;
1943
+ const isTypeString = typeof initText !== "number";
1944
+ const originalName = getExtAttribute(member, IDLExtendedAttributes.OriginalEnumMemberName);
1945
+ correctStyleNames.push({
1946
+ name: originalName ? member.name : `${member.name}_DUMMY`,
1947
+ alias: undefined,
1948
+ stringId: isTypeString ? initText : undefined,
1949
+ numberId: initText
1950
+ });
1951
+ originalStyleNames.push({
1952
+ name: originalName !== null && originalName !== void 0 ? originalName : member.name,
1953
+ alias: undefined,
1954
+ stringId: isTypeString ? initText : undefined,
1955
+ numberId: initText
1956
+ });
1812
1957
  });
1813
- writer.popIndent();
1814
- writer.print(`}`);
1815
- }
1816
- maybeQuoted(value) {
1817
- if (typeof value == "string")
1818
- return `"${value}"`;
1819
- else
1820
- return `${value}`;
1958
+ let members = originalStyleNames;
1959
+ if (this.enumEntity.elements.some(it => hasExtAttribute(it, IDLExtendedAttributes.OriginalEnumMemberName))) {
1960
+ members = members.concat(correctStyleNames);
1961
+ }
1962
+ writer.writeEnum(enumName, members, { isExport: this.options.isExport, isDeclare: this.options.isDeclare });
1821
1963
  }
1822
1964
  }
1823
1965
  class ReturnStatement {
@@ -1891,6 +2033,7 @@ var MethodModifier;
1891
2033
  MethodModifier[MethodModifier["FREE"] = 9] = "FREE";
1892
2034
  MethodModifier[MethodModifier["FORCE_CONTEXT"] = 10] = "FORCE_CONTEXT";
1893
2035
  MethodModifier[MethodModifier["OVERRIDE"] = 11] = "OVERRIDE";
2036
+ MethodModifier[MethodModifier["OPEN"] = 12] = "OPEN";
1894
2037
  })(MethodModifier || (MethodModifier = {}));
1895
2038
  var ClassModifier;
1896
2039
  (function (ClassModifier) {
@@ -2043,13 +2186,16 @@ class LanguageWriter {
2043
2186
  writeExpressionStatements(...statements) {
2044
2187
  statements.forEach(it => this.writeExpressionStatement(it));
2045
2188
  }
2046
- writeStaticBlock(op) {
2047
- this.print("static {");
2189
+ writePrefixedBlock(prefix, op) {
2190
+ this.print(`${prefix} {`);
2048
2191
  this.pushIndent();
2049
2192
  op(this);
2050
2193
  this.popIndent();
2051
2194
  this.print("}");
2052
2195
  }
2196
+ writeStaticInitBlock(op) {
2197
+ this.writePrefixedBlock("static", op);
2198
+ }
2053
2199
  makeRef(type, _options) {
2054
2200
  return type;
2055
2201
  }
@@ -2230,6 +2376,12 @@ class LanguageWriter {
2230
2376
  makeNot(expr) {
2231
2377
  return this.makeString(`!(${expr.asString()})`);
2232
2378
  }
2379
+ makeAnd(...args) {
2380
+ return this.makeNaryOp("&&", args);
2381
+ }
2382
+ makeOr(...args) {
2383
+ return this.makeNaryOp("||", args);
2384
+ }
2233
2385
  makeSerializedBufferGetter(serializer) {
2234
2386
  return this.makeMethodCall(serializer, `asBuffer`, []);
2235
2387
  }
@@ -2241,7 +2393,7 @@ class LanguageWriter {
2241
2393
  makeCallIsObject(value) {
2242
2394
  return this.makeString(`typeof ${value} === "object"`);
2243
2395
  }
2244
- makeStaticBlock(op) {
2396
+ writeStaticEntitiesBlock(op) {
2245
2397
  op(this);
2246
2398
  }
2247
2399
  instanceOf(value, type) {
@@ -2571,7 +2723,7 @@ const unsupportedDeclarations = new Set(["deleter", "getter", "includes", "inher
2571
2723
  const interfaceContent = new Set([IDLKind.Constructor, IDLKind.Const, IDLKind.Property, IDLKind.Method, IDLKind.Callable]);
2572
2724
  const globalContent = new Set([IDLKind.Namespace, IDLKind.Interface, IDLKind.Enum, IDLKind.Method, IDLKind.Typedef, IDLKind.Callback, IDLKind.Import, IDLKind.Version, IDLKind.Const]);
2573
2725
  const havingBlocks = new Set([IDLKind.Namespace, IDLKind.Interface, IDLKind.Enum]);
2574
- const modifierTokens = new Set(["static", "readonly", "async"]);
2726
+ const modifierTokens = new Set(["static", "readonly", "async", "optional"]);
2575
2727
  class Parser {
2576
2728
  constructor(fileName, content) {
2577
2729
  var _a, _b;
@@ -2885,7 +3037,7 @@ class Parser {
2885
3037
  }
2886
3038
  switch (this.curValue) {
2887
3039
  case "attribute":
2888
- this.assertPossibleModifiers("static", "readonly");
3040
+ this.assertPossibleModifiers("static", "readonly", "optional");
2889
3041
  return this.parseAttribute();
2890
3042
  case "callback":
2891
3043
  return this.parseCallback();
@@ -3206,7 +3358,7 @@ class Parser {
3206
3358
  const ext = this.consumeCurrentExtended();
3207
3359
  const isReadonly = !!this.currentModifiers.readonly;
3208
3360
  const isStatic = !!this.currentModifiers.static;
3209
- const isOptional = extractOptional(ext);
3361
+ let isOptional = !!this.currentModifiers.optional || extractOptional(ext);
3210
3362
  this.skip("attribute");
3211
3363
  const type = this.parseType();
3212
3364
  const name = this.parseSingleIdentifier();
@@ -5024,8 +5176,15 @@ class TSLanguageWriter extends LanguageWriter {
5024
5176
  }
5025
5177
  i32FromEnum(value, enumEntry) {
5026
5178
  const enumName = this.getNodeName(enumEntry);
5027
- if (isEnum(enumEntry) && isStringEnum(enumEntry)) {
5028
- return this.makeString(`Object.values(${enumName}).indexOf(${value.asString()})`);
5179
+ if (isStringEnum(enumEntry)) {
5180
+ let extractorStatement = this.makeString(`Object.values(${enumName}).indexOf(${value.asString()})`);
5181
+ if (enumEntry.elements.some(it => hasExtAttribute(it, IDLExtendedAttributes.OriginalEnumMemberName))) {
5182
+ extractorStatement = this.makeNaryOp('%', [
5183
+ extractorStatement,
5184
+ this.makeString(enumEntry.elements.length.toString())
5185
+ ]);
5186
+ }
5187
+ return extractorStatement;
5029
5188
  }
5030
5189
  return this.makeString(`${value.asString()}.valueOf()`);
5031
5190
  }
@@ -5068,6 +5227,14 @@ function isDefined(value) {
5068
5227
  function capitalize(string) {
5069
5228
  return string.charAt(0).toUpperCase() + string.slice(1);
5070
5229
  }
5230
+ function dropLast(text, chars) {
5231
+ return text.substring(0, text.length - chars);
5232
+ }
5233
+ function dropSuffix(text, suffix) {
5234
+ if (!text.endsWith(suffix))
5235
+ return text;
5236
+ return dropLast(text, suffix.length);
5237
+ }
5071
5238
  function indentedBy(input, indentedBy) {
5072
5239
  if (input.length > 0 || input.endsWith('\n')) {
5073
5240
  let space = "";
@@ -5103,6 +5270,9 @@ function rightmostIndexOf(array, predicate) {
5103
5270
  });
5104
5271
  return result;
5105
5272
  }
5273
+ function removePoints(s) {
5274
+ return s.split(/[\.\-]/g).join('_');
5275
+ }
5106
5276
 
5107
5277
  /*
5108
5278
  * Copyright (c) 2025 Huawei Device Co., Ltd.
@@ -7046,6 +7216,9 @@ class Config {
7046
7216
  static get constPostfix() {
7047
7217
  return `Const`;
7048
7218
  }
7219
+ static get ptrPostfix() {
7220
+ return `Ptr`;
7221
+ }
7049
7222
  static get nodeTypeAttribute() {
7050
7223
  return `Es2pandaAstNodeType`;
7051
7224
  }
@@ -7115,10 +7288,10 @@ class BridgesConstructions {
7115
7288
  return `result`;
7116
7289
  }
7117
7290
  static stringConstructor(name) {
7118
- return `StageArena::strdup(${name})`;
7291
+ return `StageArena::Strdup(${name})`;
7119
7292
  }
7120
7293
  static sequenceConstructor(first, length) {
7121
- return `StageArena::cloneVector(${first}, ${length})`;
7294
+ return `StageArena::CloneVector(${first}, ${length})`;
7122
7295
  }
7123
7296
  static referenceTypeCast(type) {
7124
7297
  return `reinterpret_cast<${type}>`;
@@ -7259,6 +7432,7 @@ function dropPrefix(value, toDrop) {
7259
7432
  */
7260
7433
  function peerMethod(name) {
7261
7434
  name = dropPostfix(name, Config.constPostfix);
7435
+ name = dropPostfix(name, Config.ptrPostfix);
7262
7436
  name = dropPrefix(name, Config.uselessPrefix);
7263
7437
  name = pascalToCamel(name);
7264
7438
  return name;
@@ -7281,7 +7455,7 @@ function splitCreateOrUpdate(fullName) {
7281
7455
  }
7282
7456
  function mangleIfKeyword(name) {
7283
7457
  if (InteropConstructions.keywords.includes(name)) {
7284
- return `_${name}`;
7458
+ return `_${name}_`;
7285
7459
  }
7286
7460
  return name;
7287
7461
  }
@@ -7336,7 +7510,7 @@ function isImplInterface(name) {
7336
7510
  function fixEnumPrefix(name) {
7337
7511
  if (name.startsWith(`es2panda_`)) {
7338
7512
  name = dropPrefix(name, `es2panda_`);
7339
- name = `Es2panda${name}`;
7513
+ name = `Es2panda${capitalize(name)}`;
7340
7514
  }
7341
7515
  return name;
7342
7516
  }
@@ -7391,6 +7565,10 @@ function nodeNamespace(node) {
7391
7565
  var _a;
7392
7566
  return (_a = getNamespacesPathFor(node)[0]) === null || _a === void 0 ? void 0 : _a.name;
7393
7567
  }
7568
+ /**
7569
+ * Returns a fully qualified name for a node with no exceptions.
7570
+ * @note Primarily used to pass a name to Config' options.
7571
+ */
7394
7572
  function fqName(node) {
7395
7573
  return getQualifiedName(node, "namespace.name");
7396
7574
  }
@@ -7469,6 +7647,23 @@ function flatParentsImpl(ref, resolveReference) {
7469
7647
  }
7470
7648
  return result; // with self
7471
7649
  }
7650
+ function makeFullyQualifiedName(node, resolveReference) {
7651
+ if (isReferenceType(node)) {
7652
+ const decl = resolveReference(node);
7653
+ // No throw bc a lot of handwritten code may appear.
7654
+ return decl ? makeFullyQualifiedName(decl) : node.name;
7655
+ }
7656
+ return getNamespacesPathFor(node)
7657
+ .filter(n => n.name !== Config.irNamespace)
7658
+ .map(n => n.name)
7659
+ .concat(dropPrefix(node.name, Config.dataClassPrefix))
7660
+ .join('.');
7661
+ }
7662
+ /**
7663
+ * If namespaces of the reference and resolved declaration
7664
+ * are the same, non-qualified name is returned. Otherwise, a fully qualified.
7665
+ * @note 'ir' namespace is ignored and treated as global namespace.
7666
+ */
7472
7667
  function makeEnoughQualifiedName(ref, resolveReference) {
7473
7668
  const decl = resolveReference(ref);
7474
7669
  if (!decl) {
@@ -7539,6 +7734,12 @@ class Typechecker {
7539
7734
  }
7540
7735
  return entry;
7541
7736
  }
7737
+ resolveRecursive(ref) {
7738
+ const decl = this.resolveReference(ref);
7739
+ return decl && isTypedef(decl) && isReferenceType(decl.type)
7740
+ ? this.resolveRecursive(decl.type)
7741
+ : decl;
7742
+ }
7542
7743
  flatParents(ref) {
7543
7744
  const resolveReference = (ref, pov) =>
7544
7745
  // TODO: idlize/core version, change to ours after testing
@@ -7603,7 +7804,14 @@ class Typechecker {
7603
7804
  return declaration !== undefined && isTarget(declaration);
7604
7805
  }
7605
7806
  isConstReturnValue(node) {
7606
- if (isPrimitiveType(node.returnType) || this.isReferenceTo(node.returnType, isEnum)) {
7807
+ const isPrimitive = (returnType) => {
7808
+ var _a;
7809
+ const type = isReferenceType(returnType)
7810
+ ? (_a = this.resolveReference(returnType)) !== null && _a !== void 0 ? _a : throwException(`Unresolved type ${returnType.name}`)
7811
+ : returnType;
7812
+ return isPrimitiveType(type) || isEnum(type) || (isTypedef(type) && isPrimitive(type.type));
7813
+ };
7814
+ if (isPrimitive(node.returnType)) {
7607
7815
  return false;
7608
7816
  }
7609
7817
  return node.name.endsWith(Config.constPostfix);
@@ -7650,6 +7858,7 @@ class SingleFilePrinter extends AbstractVisitor {
7650
7858
  this.typechecker = new Typechecker(this.idl);
7651
7859
  }
7652
7860
  printEnum(node) { }
7861
+ printTypedef(node) { }
7653
7862
  visit(node) {
7654
7863
  if (isInterface(node) && !this.filterInterface(node)) {
7655
7864
  this.printInterface(node);
@@ -7657,6 +7866,9 @@ class SingleFilePrinter extends AbstractVisitor {
7657
7866
  if (isEnum(node)) {
7658
7867
  this.printEnum(node);
7659
7868
  }
7869
+ if (isTypedef(node)) {
7870
+ this.printTypedef(node);
7871
+ }
7660
7872
  this.visitChildren(node);
7661
7873
  }
7662
7874
  prologue() { }
@@ -7676,6 +7888,89 @@ class SingleFilePrinter extends AbstractVisitor {
7676
7888
  }
7677
7889
  }
7678
7890
 
7891
+ class Filter {
7892
+ static makeMethod(name, returnType, parameters, modifiers, isNullable) {
7893
+ const params = Filter.filterParameters(parameters);
7894
+ return makeMethod(name, params.map(p => ({
7895
+ name: p.name,
7896
+ type: this.makeOptionalType(p, isNullable),
7897
+ isOptional: p.isOptional
7898
+ })), this.makeOptionalType(returnType, isNullable), modifiers);
7899
+ }
7900
+ static makeOptionalType(param, isNullable) {
7901
+ const type = isParameter(param) ? param.type : param;
7902
+ return isNullable(param) ? createOptionalType(type) : type;
7903
+ }
7904
+ static isNullableType(type, typechecker) {
7905
+ return isReferenceType(type) &&
7906
+ (typechecker.isPeer(type) || type.name === Config.astNodeCommonAncestor);
7907
+ }
7908
+ static filterMoreSpecific(methods) {
7909
+ const ifaceName = methods.length && methods[0].parent && isInterface(methods[0].parent) ? methods[0].parent.name : '';
7910
+ const compat = ['ETSTuple', 'ExportNamedDeclaration'];
7911
+ const noCopyCtor = methods
7912
+ .filter(m => !(m.parameters.length === 2 && isContext(m.parameters[0]) && m.parameters[1].name === 'other'));
7913
+ if (compat.includes(ifaceName)) {
7914
+ return methods;
7915
+ }
7916
+ // This is a simplified algo of UniversalCreateTransformer
7917
+ return noCopyCtor.length ? [
7918
+ noCopyCtor.reduce((prev, curr) => curr.parameters.length > prev.parameters.length ? curr : prev, noCopyCtor[0])
7919
+ ] : noCopyCtor;
7920
+ }
7921
+ static filterParameters(params) {
7922
+ return Filter.removeArrayLengthParam(Filter.removeContextParam(params));
7923
+ }
7924
+ static filterMethods(methods) {
7925
+ const names = new Set(methods.map(m => m.name));
7926
+ const others = methods
7927
+ .filter(method => {
7928
+ const bareName = dropSuffix(dropSuffix(method.name, Config.constPostfix), Config.ptrPostfix);
7929
+ // no suffix -> ptr -> const
7930
+ return bareName === method.name ||
7931
+ (method.name.endsWith(Config.ptrPostfix) && !names.has(bareName)) ||
7932
+ (method.name.endsWith(Config.constPostfix) &&
7933
+ !names.has(bareName) && !names.has(`${bareName}${Config.ptrPostfix}`));
7934
+ });
7935
+ return others;
7936
+ }
7937
+ static isOptional(param, typechecker) {
7938
+ return isReferenceType(param.type) &&
7939
+ (typechecker.isPeer(param.type) || param.type.name === Config.astNodeCommonAncestor);
7940
+ }
7941
+ static isArrayLengthParam(param) {
7942
+ return isPrimitiveType(param.type) &&
7943
+ ['u32', 'i32', 'u64', 'i64'].includes(param.type.name) &&
7944
+ ['Len', 'Count', 'Num', 'argc'].some(m => param.name.endsWith(m));
7945
+ }
7946
+ static findArrayLengthParam(parameters, startIndex = 0) {
7947
+ let seqInd = parameters.findIndex((p, index) => index >= startIndex && isSequence(p.type));
7948
+ while (seqInd !== -1) {
7949
+ if (seqInd > 0 && this.isArrayLengthParam(parameters[seqInd - 1])) {
7950
+ return seqInd - 1;
7951
+ }
7952
+ if (seqInd + 1 < parameters.length && this.isArrayLengthParam(parameters[seqInd + 1])) {
7953
+ return seqInd + 1;
7954
+ }
7955
+ seqInd = parameters.findIndex((p, index) => index >= (startIndex + seqInd + 1) && isSequence(p.type));
7956
+ }
7957
+ return -1;
7958
+ }
7959
+ static removeArrayLengthParam(parameters) {
7960
+ const params = [...parameters];
7961
+ let index = this.findArrayLengthParam(params);
7962
+ while (index !== -1) {
7963
+ params.splice(index, 1);
7964
+ index = this.findArrayLengthParam(params, index);
7965
+ }
7966
+ return params;
7967
+ }
7968
+ static removeContextParam(parameters) {
7969
+ const first = parameters.at(0);
7970
+ return first && isContext(first) ? parameters.slice(1) : [...parameters];
7971
+ }
7972
+ }
7973
+
7679
7974
  /*
7680
7975
  * Copyright (c) 2024 Huawei Device Co., Ltd.
7681
7976
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -7707,7 +8002,8 @@ class InteropPrinter extends AbstractVisitor {
7707
8002
  this.visitChildren(node);
7708
8003
  }
7709
8004
  visitInterface(node) {
7710
- node.methods.forEach(it => this.visitMethod(node, it));
8005
+ Filter.filterMethods(node.methods)
8006
+ .forEach(it => this.visitMethod(node, it));
7711
8007
  }
7712
8008
  visitMethod(iface, node) {
7713
8009
  this.printMethod(iface, node);
@@ -7763,9 +8059,13 @@ class BaseTypeConvertor {
7763
8059
  return this.convertTypeReference(type);
7764
8060
  }
7765
8061
  convertTypeReference(type) {
7766
- if (this.typechecker.isReferenceTo(type, isEnum)) {
8062
+ const declaration = this.typechecker.resolveReference(type);
8063
+ if (declaration && isEnum(declaration)) {
7767
8064
  return this.conversions.enum(type);
7768
8065
  }
8066
+ else if (declaration && isTypedef(declaration)) {
8067
+ return this.convertType(declaration.type);
8068
+ }
7769
8069
  return this.conversions.reference(type);
7770
8070
  }
7771
8071
  convertOptional(type) {
@@ -8002,9 +8302,11 @@ class BridgesPrinter extends InteropPrinter {
8002
8302
  return;
8003
8303
  const [methodName, signature] = BridgesPrinter.makeFunctionDeclaration(iface, node, this.returnTypeConvertor);
8004
8304
  this.writer.writeFunctionImplementation(BridgesConstructions.implFunction(methodName), signature, (_) => {
8305
+ var _a;
8005
8306
  let pandaMethodName = BridgesConstructions.callMethod(methodName);
8006
8307
  if (this.config.irHack.isIrHackInterface(iface.name)) {
8007
- pandaMethodName = pandaMethodName.replace(iface.name, `${iface.name}Ir`);
8308
+ const nsName = (_a = nodeNamespace(iface)) !== null && _a !== void 0 ? _a : 'ir';
8309
+ pandaMethodName = pandaMethodName.replace(iface.name, `${iface.name}${capitalize(nsName)}`);
8008
8310
  }
8009
8311
  this.printBody(node, signature, pandaMethodName);
8010
8312
  });
@@ -8094,6 +8396,90 @@ function id(value) {
8094
8396
  return value;
8095
8397
  }
8096
8398
 
8399
+ /*
8400
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
8401
+ * Licensed under the Apache License, Version 2.0 (the "License");
8402
+ * you may not use this file except in compliance with the License.
8403
+ * You may obtain a copy of the License at
8404
+ *
8405
+ * http://www.apache.org/licenses/LICENSE-2.0
8406
+ *
8407
+ * Unless required by applicable law or agreed to in writing, software
8408
+ * distributed under the License is distributed on an "AS IS" BASIS,
8409
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8410
+ * See the License for the specific language governing permissions and
8411
+ * limitations under the License.
8412
+ */
8413
+ class TopLevelTypeConvertor extends BaseTypeConvertor {
8414
+ constructor(typechecker, heirConversions) {
8415
+ super(typechecker, Object.assign(Object.assign({}, heirConversions), {
8416
+ i8: heirConversions.number,
8417
+ iu8: heirConversions.number,
8418
+ i16: heirConversions.number,
8419
+ i32: heirConversions.number,
8420
+ iu32: heirConversions.number,
8421
+ i64: heirConversions.number,
8422
+ iu64: heirConversions.number,
8423
+ f32: heirConversions.number,
8424
+ f64: heirConversions.number,
8425
+ void: heirConversions.void,
8426
+ boolean: heirConversions.boolean,
8427
+ pointer: heirConversions.pointer,
8428
+ undefined: heirConversions.undefined
8429
+ }));
8430
+ }
8431
+ }
8432
+
8433
+ /*
8434
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
8435
+ * Licensed under the Apache License, Version 2.0 (the "License");
8436
+ * you may not use this file except in compliance with the License.
8437
+ * You may obtain a copy of the License at
8438
+ *
8439
+ * http://www.apache.org/licenses/LICENSE-2.0
8440
+ *
8441
+ * Unless required by applicable law or agreed to in writing, software
8442
+ * distributed under the License is distributed on an "AS IS" BASIS,
8443
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8444
+ * See the License for the specific language governing permissions and
8445
+ * limitations under the License.
8446
+ */
8447
+ class _LibraryTypeConvertor extends TopLevelTypeConvertor {
8448
+ constructor(typechecker) {
8449
+ super(typechecker, {
8450
+ enum: (type) => type.name,
8451
+ reference: (type) => type.name,
8452
+ sequence: (type) => `readonly ${this.convertType(innerType(type))}[]`,
8453
+ optional: (type) => `${this.convertType(type.type)} | undefined`,
8454
+ string: (type) => `string`,
8455
+ number: (type) => `number`,
8456
+ void: (type) => `void`,
8457
+ boolean: (type) => `boolean`,
8458
+ pointer: (type) => `KNativePointer`,
8459
+ undefined: (type) => `undefined`
8460
+ });
8461
+ }
8462
+ }
8463
+ class LibraryTypeConvertor extends _LibraryTypeConvertor {
8464
+ constructor(typechecker, fullQualified = false) {
8465
+ super(typechecker);
8466
+ this.fullQualified = fullQualified;
8467
+ }
8468
+ convertTypeReference(type) {
8469
+ const node = this.typechecker.resolveReference(type);
8470
+ if (node && (isEnum(node) || isTypedef(node))) {
8471
+ if (node.name.startsWith(Config.dataClassPrefix)) {
8472
+ // TODO: support enums in namespace?
8473
+ return fixEnumPrefix(node.name);
8474
+ }
8475
+ }
8476
+ const resolver = this.typechecker.resolveReference.bind(this.typechecker);
8477
+ return this.fullQualified
8478
+ ? makeFullyQualifiedName(type, resolver)
8479
+ : makeEnoughQualifiedName(type, resolver);
8480
+ }
8481
+ }
8482
+
8097
8483
  /*
8098
8484
  * Copyright (c) 2024 Huawei Device Co., Ltd.
8099
8485
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -8111,7 +8497,17 @@ function id(value) {
8111
8497
  class EnumsPrinter extends SingleFilePrinter {
8112
8498
  constructor() {
8113
8499
  super(...arguments);
8114
- this.writer = new TSLanguageWriter(new IndentedPrinter(), createEmptyReferenceResolver(), { convert: (node) => { throwException(`Unexpected call to covert type`); } });
8500
+ this.converter = new LibraryTypeConvertor(this.typechecker);
8501
+ this.writer = new TSLanguageWriter(new IndentedPrinter(), createEmptyReferenceResolver(), {
8502
+ convert: (node) => {
8503
+ if (isUnionType(node)) {
8504
+ // TODO: core implementation, it is better tor use the
8505
+ // whole converters from core.
8506
+ return node.types.map(type => this.converter.convertType(type)).join(' | ');
8507
+ }
8508
+ return this.converter.convertType(node);
8509
+ }
8510
+ });
8115
8511
  }
8116
8512
  printInterface(node) { }
8117
8513
  filterInterface(node) {
@@ -8129,6 +8525,9 @@ class EnumsPrinter extends SingleFilePrinter {
8129
8525
  };
8130
8526
  }), { isExport: true });
8131
8527
  }
8528
+ printTypedef(node) {
8529
+ this.writer.writeTypeDeclaration(createTypedef(fixEnumPrefix(node.name), node.type, node.typeParameters));
8530
+ }
8132
8531
  }
8133
8532
 
8134
8533
  /*
@@ -8365,6 +8764,9 @@ class PeersConstructions {
8365
8764
  static get arrayOfPointersToArrayOfPeers() {
8366
8765
  return `unpackNodeArray`;
8367
8766
  }
8767
+ static get arrayOfPointersToArrayOfObjects() {
8768
+ return `unpackNativeObjectArray`;
8769
+ }
8368
8770
  static get receiveString() {
8369
8771
  return `unpackString`;
8370
8772
  }
@@ -8436,8 +8838,7 @@ class PeersConstructions {
8436
8838
  * limitations under the License.
8437
8839
  */
8438
8840
  class Importer {
8439
- constructor(typechecker, dir, self) {
8440
- this.typechecker = typechecker;
8841
+ constructor(dir, self) {
8441
8842
  this.dir = dir;
8442
8843
  this.writer = createDefaultTypescriptWriter();
8443
8844
  this.seen = new Set([
@@ -8448,11 +8849,11 @@ class Importer {
8448
8849
  this.seen.add(self);
8449
8850
  }
8450
8851
  }
8451
- withPeerImport(ref, context) {
8452
- const name = makeEnoughQualifiedName(ref, this.typechecker.resolveReference.bind(this.typechecker));
8852
+ withPeerImport(name) {
8453
8853
  const fq = name.split('.');
8454
8854
  // import namespace name for fq names
8455
- return this.withPeerImport2(fq.length > 1 ? fq.slice(0, -1).join('.') : name);
8855
+ this.withPeerImport2(fq.length > 1 ? fq.slice(0, -1).join('.') : name);
8856
+ return name;
8456
8857
  }
8457
8858
  withPeerImport2(it) {
8458
8859
  if (this.seen.has(it)) {
@@ -8491,40 +8892,6 @@ class Importer {
8491
8892
  }
8492
8893
  }
8493
8894
 
8494
- /*
8495
- * Copyright (c) 2024 Huawei Device Co., Ltd.
8496
- * Licensed under the Apache License, Version 2.0 (the "License");
8497
- * you may not use this file except in compliance with the License.
8498
- * You may obtain a copy of the License at
8499
- *
8500
- * http://www.apache.org/licenses/LICENSE-2.0
8501
- *
8502
- * Unless required by applicable law or agreed to in writing, software
8503
- * distributed under the License is distributed on an "AS IS" BASIS,
8504
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8505
- * See the License for the specific language governing permissions and
8506
- * limitations under the License.
8507
- */
8508
- class TopLevelTypeConvertor extends BaseTypeConvertor {
8509
- constructor(typechecker, heirConversions) {
8510
- super(typechecker, Object.assign(Object.assign({}, heirConversions), {
8511
- i8: heirConversions.number,
8512
- iu8: heirConversions.number,
8513
- i16: heirConversions.number,
8514
- i32: heirConversions.number,
8515
- iu32: heirConversions.number,
8516
- i64: heirConversions.number,
8517
- iu64: heirConversions.number,
8518
- f32: heirConversions.number,
8519
- f64: heirConversions.number,
8520
- void: heirConversions.void,
8521
- boolean: heirConversions.boolean,
8522
- pointer: heirConversions.pointer,
8523
- undefined: heirConversions.undefined
8524
- }));
8525
- }
8526
- }
8527
-
8528
8895
  /*
8529
8896
  * Copyright (c) 2024 Huawei Device Co., Ltd.
8530
8897
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -8582,8 +8949,10 @@ class BindingParameterTypeConvertor extends TopLevelTypeConvertor {
8582
8949
  function unpackWrapper(type, typechecker) {
8583
8950
  const isAstNode = (ref) => (isReferenceType(ref) || isInterface(ref)) && typechecker.isHeir(ref, Config.astNodeCommonAncestor);
8584
8951
  if (isContainerType(type)) {
8585
- if (IDLContainerUtils.isSequence(type)) {
8586
- return PeersConstructions.arrayOfPointersToArrayOfPeers;
8952
+ if (IDLContainerUtils.isSequence(type) && isReferenceType(type.elementType[0])) {
8953
+ return isAstNode(type.elementType[0])
8954
+ ? PeersConstructions.arrayOfPointersToArrayOfPeers
8955
+ : PeersConstructions.arrayOfPointersToArrayOfObjects;
8587
8956
  }
8588
8957
  throwException(`unexpected container of non-sequence type`);
8589
8958
  }
@@ -8624,6 +8993,11 @@ function typeHintArgument(type, typechecker, importer) {
8624
8993
  }
8625
8994
  return undefined;
8626
8995
  }
8996
+ function hasFactoryArgument(wrapper) {
8997
+ return [
8998
+ PeersConstructions.arrayOfPointersToArrayOfObjects,
8999
+ ].includes(wrapper);
9000
+ }
8627
9001
 
8628
9002
  class CommonGenerator {
8629
9003
  static resolveProperty(property, iface, typechecker) {
@@ -8687,83 +9061,6 @@ class CommonGenerator {
8687
9061
  }
8688
9062
  }
8689
9063
 
8690
- class Filter {
8691
- static makeMethod(name, returnType, parameters, modifiers, isNullable) {
8692
- const params = Filter.filterParameters(parameters);
8693
- return makeMethod(name, params.map(p => ({
8694
- name: p.name,
8695
- type: this.makeOptionalType(p, isNullable),
8696
- isOptional: p.isOptional
8697
- })), this.makeOptionalType(returnType, isNullable), modifiers);
8698
- }
8699
- static makeOptionalType(param, isNullable) {
8700
- const type = isParameter(param) ? param.type : param;
8701
- return isNullable(param) ? createOptionalType(type) : type;
8702
- }
8703
- static isNullableType(type, typechecker) {
8704
- return isReferenceType(type) &&
8705
- (typechecker.isPeer(type) || type.name === Config.astNodeCommonAncestor);
8706
- }
8707
- static filterMoreSpecific(methods) {
8708
- const ifaceName = methods.length && methods[0].parent && isInterface(methods[0].parent) ? methods[0].parent.name : '';
8709
- const compat = ['ETSTuple', 'ExportNamedDeclaration'];
8710
- const noCopyCtor = methods
8711
- .filter(m => !(m.parameters.length === 2 && isContext(m.parameters[0]) && m.parameters[1].name === 'other'));
8712
- if (compat.includes(ifaceName)) {
8713
- return methods;
8714
- }
8715
- // This is a simplified algo of UniversalCreateTransformer
8716
- return noCopyCtor.length ? [
8717
- noCopyCtor.reduce((prev, curr) => curr.parameters.length > prev.parameters.length ? curr : prev, noCopyCtor[0])
8718
- ] : noCopyCtor;
8719
- }
8720
- static filterParameters(params) {
8721
- return Filter.removeArrayLengthParam(Filter.removeContextParam(params));
8722
- }
8723
- static filterMethods(methods) {
8724
- const names = new Set(methods.map(m => m.name));
8725
- const others = methods
8726
- .filter(method => !method.name.endsWith(Config.constPostfix) ||
8727
- !names.has(method.name.slice(0, -Config.constPostfix.length)));
8728
- return others;
8729
- }
8730
- static isOptional(param, typechecker) {
8731
- return isReferenceType(param.type) &&
8732
- (typechecker.isPeer(param.type) || param.type.name === Config.astNodeCommonAncestor);
8733
- }
8734
- static isArrayLengthParam(param) {
8735
- return isPrimitiveType(param.type) &&
8736
- ['u32', 'i32', 'u64', 'i64'].includes(param.type.name) &&
8737
- ['Len', 'Count', 'Num', 'argc'].some(m => param.name.endsWith(m));
8738
- }
8739
- static findArrayLengthParam(parameters, startIndex = 0) {
8740
- let seqInd = parameters.findIndex((p, index) => index >= startIndex && isSequence(p.type));
8741
- while (seqInd !== -1) {
8742
- if (seqInd > 0 && this.isArrayLengthParam(parameters[seqInd - 1])) {
8743
- return seqInd - 1;
8744
- }
8745
- if (seqInd + 1 < parameters.length && this.isArrayLengthParam(parameters[seqInd + 1])) {
8746
- return seqInd + 1;
8747
- }
8748
- seqInd = parameters.findIndex((p, index) => index >= (startIndex + seqInd + 1) && isSequence(p.type));
8749
- }
8750
- return -1;
8751
- }
8752
- static removeArrayLengthParam(parameters) {
8753
- const params = [...parameters];
8754
- let index = this.findArrayLengthParam(params);
8755
- while (index !== -1) {
8756
- params.splice(index, 1);
8757
- index = this.findArrayLengthParam(params, index);
8758
- }
8759
- return params;
8760
- }
8761
- static removeContextParam(parameters) {
8762
- const first = parameters.at(0);
8763
- return first && isContext(first) ? parameters.slice(1) : [...parameters];
8764
- }
8765
- }
8766
-
8767
9064
  /*
8768
9065
  * Copyright (c) 2024 Huawei Device Co., Ltd.
8769
9066
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -8799,9 +9096,10 @@ class PeerPrinter {
8799
9096
  printPeer(iface, writer) {
8800
9097
  var _a;
8801
9098
  const _parent = (_a = iface.inheritance[0]) !== null && _a !== void 0 ? _a : createReferenceType(Config.defaultAncestor);
9099
+ const parentName = makeEnoughQualifiedName(_parent, this.typechecker.resolveReference.bind(this.typechecker));
8802
9100
  this.importer.addSeen(PeersConstructions.peerName(iface.name));
8803
9101
  writer.writeClass(PeersConstructions.peerName(iface.name), // XXX: Change peer name to iface.name
8804
- (writer) => this.printBody(iface, writer), this.importer.withPeerImport(_parent));
9102
+ (writer) => this.printBody(iface, writer), this.importer.withPeerImport(parentName));
8805
9103
  }
8806
9104
  printBody(iface, writer) {
8807
9105
  this.printConstructor(iface, writer);
@@ -8916,6 +9214,9 @@ class PeerPrinter {
8916
9214
  const innerType = innerTypeCommon(returnType);
8917
9215
  if (wrapper) {
8918
9216
  const args = [nativeCall];
9217
+ if (hasFactoryArgument(wrapper) && isReferenceType(innerType)) {
9218
+ args.push(this.makeNativeObjectFactory(innerType, writer));
9219
+ }
8919
9220
  if (hasTypeHintArgument(wrapper)) {
8920
9221
  const hint = typeHintArgument(innerType, this.typechecker, this.importer);
8921
9222
  if (hint) {
@@ -8925,8 +9226,16 @@ class PeerPrinter {
8925
9226
  return writer.makeFunctionCall(wrapper, args);
8926
9227
  }
8927
9228
  const convertName = (ref) => makeEnoughQualifiedName(ref, this.typechecker.resolveReference.bind(this.typechecker));
8928
- return isOptionalType(returnType) && isReferenceType(innerType) ?
8929
- writer.makeNewObject(convertName(innerType), [nativeCall]) : nativeCall;
9229
+ const resolvedType = isReferenceType(innerType) ? this.typechecker.resolveRecursive(innerType) : innerType;
9230
+ return isReferenceType(innerType) && resolvedType && isInterface(resolvedType)
9231
+ ? writer.makeNewObject(convertName(innerType), [nativeCall]) : nativeCall;
9232
+ }
9233
+ makeNativeObjectFactory(type, writer) {
9234
+ const args = [{ name: 'peer', type: IDLPointerType }];
9235
+ const stmts = [
9236
+ writer.makeReturn(writer.makeNewObject(makeEnoughQualifiedName(type, this.typechecker.resolveReference.bind(this.typechecker)), args.map(a => writer.makeString(a.name))))
9237
+ ];
9238
+ return writer.makeLambda(NamedMethodSignature.make(type, args), stmts);
8930
9239
  }
8931
9240
  printCreateOrUpdate(iface, node, writer) {
8932
9241
  const extraParameters = CommonGenerator.makeExtraParameters(iface, this.config, this.typechecker);
@@ -9023,61 +9332,21 @@ function convertAndImport(importer, converter, type, config) {
9023
9332
  if (node && isEnum(node)) {
9024
9333
  importer.withEnumImport(result);
9025
9334
  }
9335
+ else if (node && isTypedef(node)) {
9336
+ importer.withEnumImport(result); // typedefs print as enums
9337
+ }
9026
9338
  else if (node && isInterface(node) && converter.typechecker.isPeer(node)) {
9027
9339
  if (config.ignore.hasReexportReplacement(fqName(node))) {
9028
9340
  importer.withReexportImport(dropPrefix(type.name, Config.dataClassPrefix));
9029
9341
  }
9030
9342
  else {
9031
- importer.withPeerImport(type);
9343
+ importer.withPeerImport(result);
9032
9344
  }
9033
9345
  }
9034
9346
  }
9035
9347
  return result;
9036
9348
  }
9037
9349
 
9038
- /*
9039
- * Copyright (c) 2024 Huawei Device Co., Ltd.
9040
- * Licensed under the Apache License, Version 2.0 (the "License");
9041
- * you may not use this file except in compliance with the License.
9042
- * You may obtain a copy of the License at
9043
- *
9044
- * http://www.apache.org/licenses/LICENSE-2.0
9045
- *
9046
- * Unless required by applicable law or agreed to in writing, software
9047
- * distributed under the License is distributed on an "AS IS" BASIS,
9048
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9049
- * See the License for the specific language governing permissions and
9050
- * limitations under the License.
9051
- */
9052
- class _LibraryTypeConvertor extends TopLevelTypeConvertor {
9053
- constructor(typechecker) {
9054
- super(typechecker, {
9055
- enum: (type) => type.name,
9056
- reference: (type) => type.name,
9057
- sequence: (type) => `readonly ${this.convertType(innerType(type))}[]`,
9058
- optional: (type) => `${this.convertType(type.type)} | undefined`,
9059
- string: (type) => `string`,
9060
- number: (type) => `number`,
9061
- void: (type) => `void`,
9062
- boolean: (type) => `boolean`,
9063
- pointer: (type) => `KNativePointer`,
9064
- undefined: (type) => `undefined`
9065
- });
9066
- }
9067
- }
9068
- class LibraryTypeConvertor extends _LibraryTypeConvertor {
9069
- convertTypeReference(type) {
9070
- const node = this.typechecker.resolveReference(type);
9071
- if (node && isEnum(node)) {
9072
- if (node.name.startsWith(Config.dataClassPrefix)) {
9073
- // TODO: support enums in namespace?
9074
- return `Es2panda${node.name.slice(Config.dataClassPrefix.length)}`;
9075
- }
9076
- }
9077
- return makeEnoughQualifiedName(type, this.typechecker.resolveReference.bind(this.typechecker));
9078
- }
9079
- }
9080
-
9081
9350
  /*
9082
9351
  * Copyright (c) 2024 Huawei Device Co., Ltd.
9083
9352
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -9108,9 +9377,13 @@ class AllPeersPrinter extends MultiFilePrinter {
9108
9377
  if (members.length === 0) {
9109
9378
  return [];
9110
9379
  }
9111
- return [this.printFile(ns.name, [ns.name], (printer, writer) => {
9380
+ return [this.printFile(ns.name, [ns.name], (printer, writer, importer) => {
9381
+ ns.members // Is ns.* a typo or it really needed?
9382
+ .filter(isInterface)
9383
+ .forEach(iface => importer.addSeen(iface.name)); // Do not import classes from this namespace
9112
9384
  writer.pushNamespace(ns.name, { ident: false });
9113
- members.forEach(m => printer.printInterface(m, writer));
9385
+ this.sortInterfaces(members)
9386
+ .forEach(m => printer.printInterface(m, writer));
9114
9387
  writer.popNamespace({ ident: false });
9115
9388
  })];
9116
9389
  }
@@ -9125,13 +9398,16 @@ class AllPeersPrinter extends MultiFilePrinter {
9125
9398
  writer.popNamespace({ ident: false });
9126
9399
  });
9127
9400
  }
9128
- return this.printFile(iface.name, ['*'], (printer, writer) => printer.printInterface(iface, writer));
9401
+ return this.printFile(iface.name, ['*'], (printer, writer, importer) => {
9402
+ importer.addSeen(PeersConstructions.peerName(iface.name));
9403
+ printer.printInterface(iface, writer);
9404
+ });
9129
9405
  }
9130
9406
  printFile(name, exports, cb) {
9131
- const importer = new Importer(this.typechecker, '.', name);
9407
+ const importer = new Importer('.', name);
9132
9408
  const writer = this.makeWriter(importer);
9133
9409
  const printer = new PeerPrinter(this.config, this.typechecker, importer);
9134
- cb(printer, writer);
9410
+ cb(printer, writer, importer);
9135
9411
  return {
9136
9412
  exports: exports,
9137
9413
  fileName: PeersConstructions.fileName(name),
@@ -9159,6 +9435,22 @@ class AllPeersPrinter extends MultiFilePrinter {
9159
9435
  };
9160
9436
  return visitInterfaces(this.idl);
9161
9437
  }
9438
+ /**
9439
+ * Sort interfaces in order of inheritance.
9440
+ */
9441
+ sortInterfaces(ifaces) {
9442
+ const sorted = [];
9443
+ ifaces.forEach((iface) => {
9444
+ const parents = this.typechecker.flatParents(iface);
9445
+ parents.reverse().forEach(p => {
9446
+ const index = sorted.findIndex(ps => p.name === ps.name);
9447
+ if (index === -1) {
9448
+ sorted.push(p);
9449
+ }
9450
+ });
9451
+ });
9452
+ return sorted;
9453
+ }
9162
9454
  makeWriter(importer) {
9163
9455
  const converter = {
9164
9456
  convert: (node) => convertAndImport(importer, new LibraryTypeConvertor(this.typechecker), node, this.config)
@@ -9244,8 +9536,8 @@ class FactoryPrinter extends SingleFilePrinter {
9244
9536
  constructor(config, idl) {
9245
9537
  super(idl);
9246
9538
  this.config = config;
9247
- this.importer = new Importer(this.typechecker, `peers`);
9248
- this.converter = new LibraryTypeConvertor(this.typechecker);
9539
+ this.importer = new Importer(`peers`);
9540
+ this.converter = new LibraryTypeConvertor(this.typechecker, true /* fq names */);
9249
9541
  this.writer = new TSLanguageWriter(new IndentedPrinter(), createEmptyReferenceResolver(), {
9250
9542
  convert: (node) => convertAndImport(this.importer, this.converter, node, this.config)
9251
9543
  });
@@ -9291,7 +9583,7 @@ class FactoryPrinter extends SingleFilePrinter {
9291
9583
  type: Filter.makeOptionalType(p.type, isNullable),
9292
9584
  isOptional: p.isOptional
9293
9585
  })), createReferenceType(node.name));
9294
- this.writer.writeMethodImplementation(new Method(PeersConstructions.universalCreate(node.name), signature), () => this.writer.writeStatement(this.writer.makeReturn(this.writer.makeFunctionCall(this.callUniversalCreate(node, universalName), signature.argNames
9586
+ this.writer.writeMethodImplementation(new Method(PeersConstructions.universalCreate(node.name), signature), () => this.writer.writeStatement(this.writer.makeReturn(this.writer.makeStaticMethodCall(makeFullyQualifiedName(node), PeersConstructions.createOrUpdate(node.name, universalName), signature.argNames
9295
9587
  .map(mangleIfKeyword)
9296
9588
  .map(it => this.writer.makeString(it))))));
9297
9589
  }
@@ -9323,7 +9615,7 @@ class FactoryPrinter extends SingleFilePrinter {
9323
9615
  if (parameters.length) {
9324
9616
  writer.writeStatement(writer.makeCondition(expr(isSameAll), writer.makeReturn(expr(FactoryConstructions.original))));
9325
9617
  }
9326
- const createCall = writer.makeFunctionCall(this.callUniversalCreate(node, universalName), parameters
9618
+ const createCall = writer.makeStaticMethodCall(makeFullyQualifiedName(node), PeersConstructions.createOrUpdate(node.name, universalName), parameters
9327
9619
  .concat(extraParameters)
9328
9620
  .map(p => expr(mangleIfKeyword(p.name))));
9329
9621
  writer.writeStatement(writer.makeReturn(writer.makeFunctionCall(FactoryConstructions.updateNodeByNode, [
@@ -9331,9 +9623,6 @@ class FactoryPrinter extends SingleFilePrinter {
9331
9623
  ])));
9332
9624
  });
9333
9625
  }
9334
- callUniversalCreate(node, name) {
9335
- return PeersConstructions.callPeerMethod(node.name, PeersConstructions.createOrUpdate(node.name, name));
9336
- }
9337
9626
  gettersForParams(params, methods) {
9338
9627
  const toTypeName = (type) => {
9339
9628
  const rawType = isOptionalType(type) ? type.type : type;
@@ -9530,7 +9819,7 @@ class DynamicEmitter {
9530
9819
  this.generatorVersion = `Unknown`;
9531
9820
  this.logDir = `./out/log-idl`;
9532
9821
  this.logCount = 0;
9533
- this.bridgesPrinter = new SingleFileEmitter((idl) => new BridgesPrinter(this.config, idl).print(), `libarkts/generated/native/bridges.cc`, `bridges.cc`, true);
9822
+ this.bridgesPrinter = new SingleFileEmitter((idl) => new BridgesPrinter(this.config, idl).print(), `libarkts/generated/native/bridges.cpp`, `bridges.cpp`, true);
9534
9823
  this.bindingsPrinter = new SingleFileEmitter((idl) => new BindingsPrinter(idl).print(), `libarkts/generated/Es2pandaNativeModule.ts`, `Es2pandaNativeModule.ts`, true);
9535
9824
  this.enumsPrinter = new SingleFileEmitter((idl) => new EnumsPrinter(idl).print(), `libarkts/generated/Es2pandaEnums.ts`, `Es2pandaEnums.ts`, true);
9536
9825
  this.indexPrinter = new SingleFileEmitter((idl) => new IndexPrinter(this.config, idl).print(), // overriden below