@idlizer/arktscgen 2.1.10-arktscgen-7 → 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.
package/lib/index.js CHANGED
@@ -778,8 +778,9 @@ class IDLWriter {
778
778
  printProperty(idl) {
779
779
  const staticMod = idl.isStatic ? "static " : "";
780
780
  const readonlyMod = idl.isReadonly ? "readonly " : "";
781
+ const optional = idl.isOptional ? "optional " : "";
781
782
  return this.printExtendedAttributes(idl)
782
- .print(`${staticMod}${readonlyMod}attribute ${nameWithType(idl)};`);
783
+ .print(`${staticMod}${readonlyMod}${optional}attribute ${nameWithType(idl)};`);
783
784
  }
784
785
  printExtendedAttributes(idl) {
785
786
  var _a;
@@ -2032,6 +2033,7 @@ var MethodModifier;
2032
2033
  MethodModifier[MethodModifier["FREE"] = 9] = "FREE";
2033
2034
  MethodModifier[MethodModifier["FORCE_CONTEXT"] = 10] = "FORCE_CONTEXT";
2034
2035
  MethodModifier[MethodModifier["OVERRIDE"] = 11] = "OVERRIDE";
2036
+ MethodModifier[MethodModifier["OPEN"] = 12] = "OPEN";
2035
2037
  })(MethodModifier || (MethodModifier = {}));
2036
2038
  var ClassModifier;
2037
2039
  (function (ClassModifier) {
@@ -2184,13 +2186,16 @@ class LanguageWriter {
2184
2186
  writeExpressionStatements(...statements) {
2185
2187
  statements.forEach(it => this.writeExpressionStatement(it));
2186
2188
  }
2187
- writeStaticBlock(op) {
2188
- this.print("static {");
2189
+ writePrefixedBlock(prefix, op) {
2190
+ this.print(`${prefix} {`);
2189
2191
  this.pushIndent();
2190
2192
  op(this);
2191
2193
  this.popIndent();
2192
2194
  this.print("}");
2193
2195
  }
2196
+ writeStaticInitBlock(op) {
2197
+ this.writePrefixedBlock("static", op);
2198
+ }
2194
2199
  makeRef(type, _options) {
2195
2200
  return type;
2196
2201
  }
@@ -2371,6 +2376,12 @@ class LanguageWriter {
2371
2376
  makeNot(expr) {
2372
2377
  return this.makeString(`!(${expr.asString()})`);
2373
2378
  }
2379
+ makeAnd(...args) {
2380
+ return this.makeNaryOp("&&", args);
2381
+ }
2382
+ makeOr(...args) {
2383
+ return this.makeNaryOp("||", args);
2384
+ }
2374
2385
  makeSerializedBufferGetter(serializer) {
2375
2386
  return this.makeMethodCall(serializer, `asBuffer`, []);
2376
2387
  }
@@ -2382,7 +2393,7 @@ class LanguageWriter {
2382
2393
  makeCallIsObject(value) {
2383
2394
  return this.makeString(`typeof ${value} === "object"`);
2384
2395
  }
2385
- makeStaticBlock(op) {
2396
+ writeStaticEntitiesBlock(op) {
2386
2397
  op(this);
2387
2398
  }
2388
2399
  instanceOf(value, type) {
@@ -2712,7 +2723,7 @@ const unsupportedDeclarations = new Set(["deleter", "getter", "includes", "inher
2712
2723
  const interfaceContent = new Set([IDLKind.Constructor, IDLKind.Const, IDLKind.Property, IDLKind.Method, IDLKind.Callable]);
2713
2724
  const globalContent = new Set([IDLKind.Namespace, IDLKind.Interface, IDLKind.Enum, IDLKind.Method, IDLKind.Typedef, IDLKind.Callback, IDLKind.Import, IDLKind.Version, IDLKind.Const]);
2714
2725
  const havingBlocks = new Set([IDLKind.Namespace, IDLKind.Interface, IDLKind.Enum]);
2715
- const modifierTokens = new Set(["static", "readonly", "async"]);
2726
+ const modifierTokens = new Set(["static", "readonly", "async", "optional"]);
2716
2727
  class Parser {
2717
2728
  constructor(fileName, content) {
2718
2729
  var _a, _b;
@@ -3026,7 +3037,7 @@ class Parser {
3026
3037
  }
3027
3038
  switch (this.curValue) {
3028
3039
  case "attribute":
3029
- this.assertPossibleModifiers("static", "readonly");
3040
+ this.assertPossibleModifiers("static", "readonly", "optional");
3030
3041
  return this.parseAttribute();
3031
3042
  case "callback":
3032
3043
  return this.parseCallback();
@@ -3347,7 +3358,7 @@ class Parser {
3347
3358
  const ext = this.consumeCurrentExtended();
3348
3359
  const isReadonly = !!this.currentModifiers.readonly;
3349
3360
  const isStatic = !!this.currentModifiers.static;
3350
- const isOptional = extractOptional(ext);
3361
+ let isOptional = !!this.currentModifiers.optional || extractOptional(ext);
3351
3362
  this.skip("attribute");
3352
3363
  const type = this.parseType();
3353
3364
  const name = this.parseSingleIdentifier();
@@ -5216,6 +5227,14 @@ function isDefined(value) {
5216
5227
  function capitalize(string) {
5217
5228
  return string.charAt(0).toUpperCase() + string.slice(1);
5218
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
+ }
5219
5238
  function indentedBy(input, indentedBy) {
5220
5239
  if (input.length > 0 || input.endsWith('\n')) {
5221
5240
  let space = "";
@@ -7197,6 +7216,9 @@ class Config {
7197
7216
  static get constPostfix() {
7198
7217
  return `Const`;
7199
7218
  }
7219
+ static get ptrPostfix() {
7220
+ return `Ptr`;
7221
+ }
7200
7222
  static get nodeTypeAttribute() {
7201
7223
  return `Es2pandaAstNodeType`;
7202
7224
  }
@@ -7410,6 +7432,7 @@ function dropPrefix(value, toDrop) {
7410
7432
  */
7411
7433
  function peerMethod(name) {
7412
7434
  name = dropPostfix(name, Config.constPostfix);
7435
+ name = dropPostfix(name, Config.ptrPostfix);
7413
7436
  name = dropPrefix(name, Config.uselessPrefix);
7414
7437
  name = pascalToCamel(name);
7415
7438
  return name;
@@ -7432,7 +7455,7 @@ function splitCreateOrUpdate(fullName) {
7432
7455
  }
7433
7456
  function mangleIfKeyword(name) {
7434
7457
  if (InteropConstructions.keywords.includes(name)) {
7435
- return `_${name}`;
7458
+ return `_${name}_`;
7436
7459
  }
7437
7460
  return name;
7438
7461
  }
@@ -7487,7 +7510,7 @@ function isImplInterface(name) {
7487
7510
  function fixEnumPrefix(name) {
7488
7511
  if (name.startsWith(`es2panda_`)) {
7489
7512
  name = dropPrefix(name, `es2panda_`);
7490
- name = `Es2panda${name}`;
7513
+ name = `Es2panda${capitalize(name)}`;
7491
7514
  }
7492
7515
  return name;
7493
7516
  }
@@ -7624,19 +7647,16 @@ function flatParentsImpl(ref, resolveReference) {
7624
7647
  }
7625
7648
  return result; // with self
7626
7649
  }
7627
- /**
7628
- * A fully qualified of a type that reference points to.
7629
- * @note 'ir' namespace is ignored and treated as global namespace.
7630
- */
7631
- function makeFullyQualifiedName(ref, resolveReference) {
7632
- const decl = resolveReference(ref);
7633
- if (!decl) {
7634
- return ref.name;
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;
7635
7655
  }
7636
- return getNamespacesPathFor(decl)
7656
+ return getNamespacesPathFor(node)
7637
7657
  .filter(n => n.name !== Config.irNamespace)
7638
7658
  .map(n => n.name)
7639
- .concat(decl.name)
7659
+ .concat(dropPrefix(node.name, Config.dataClassPrefix))
7640
7660
  .join('.');
7641
7661
  }
7642
7662
  /**
@@ -7714,6 +7734,12 @@ class Typechecker {
7714
7734
  }
7715
7735
  return entry;
7716
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
+ }
7717
7743
  flatParents(ref) {
7718
7744
  const resolveReference = (ref, pov) =>
7719
7745
  // TODO: idlize/core version, change to ours after testing
@@ -7778,7 +7804,14 @@ class Typechecker {
7778
7804
  return declaration !== undefined && isTarget(declaration);
7779
7805
  }
7780
7806
  isConstReturnValue(node) {
7781
- 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)) {
7782
7815
  return false;
7783
7816
  }
7784
7817
  return node.name.endsWith(Config.constPostfix);
@@ -7825,6 +7858,7 @@ class SingleFilePrinter extends AbstractVisitor {
7825
7858
  this.typechecker = new Typechecker(this.idl);
7826
7859
  }
7827
7860
  printEnum(node) { }
7861
+ printTypedef(node) { }
7828
7862
  visit(node) {
7829
7863
  if (isInterface(node) && !this.filterInterface(node)) {
7830
7864
  this.printInterface(node);
@@ -7832,6 +7866,9 @@ class SingleFilePrinter extends AbstractVisitor {
7832
7866
  if (isEnum(node)) {
7833
7867
  this.printEnum(node);
7834
7868
  }
7869
+ if (isTypedef(node)) {
7870
+ this.printTypedef(node);
7871
+ }
7835
7872
  this.visitChildren(node);
7836
7873
  }
7837
7874
  prologue() { }
@@ -7851,6 +7888,89 @@ class SingleFilePrinter extends AbstractVisitor {
7851
7888
  }
7852
7889
  }
7853
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
+
7854
7974
  /*
7855
7975
  * Copyright (c) 2024 Huawei Device Co., Ltd.
7856
7976
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -7882,7 +8002,8 @@ class InteropPrinter extends AbstractVisitor {
7882
8002
  this.visitChildren(node);
7883
8003
  }
7884
8004
  visitInterface(node) {
7885
- node.methods.forEach(it => this.visitMethod(node, it));
8005
+ Filter.filterMethods(node.methods)
8006
+ .forEach(it => this.visitMethod(node, it));
7886
8007
  }
7887
8008
  visitMethod(iface, node) {
7888
8009
  this.printMethod(iface, node);
@@ -7938,9 +8059,13 @@ class BaseTypeConvertor {
7938
8059
  return this.convertTypeReference(type);
7939
8060
  }
7940
8061
  convertTypeReference(type) {
7941
- if (this.typechecker.isReferenceTo(type, isEnum)) {
8062
+ const declaration = this.typechecker.resolveReference(type);
8063
+ if (declaration && isEnum(declaration)) {
7942
8064
  return this.conversions.enum(type);
7943
8065
  }
8066
+ else if (declaration && isTypedef(declaration)) {
8067
+ return this.convertType(declaration.type);
8068
+ }
7944
8069
  return this.conversions.reference(type);
7945
8070
  }
7946
8071
  convertOptional(type) {
@@ -8177,9 +8302,11 @@ class BridgesPrinter extends InteropPrinter {
8177
8302
  return;
8178
8303
  const [methodName, signature] = BridgesPrinter.makeFunctionDeclaration(iface, node, this.returnTypeConvertor);
8179
8304
  this.writer.writeFunctionImplementation(BridgesConstructions.implFunction(methodName), signature, (_) => {
8305
+ var _a;
8180
8306
  let pandaMethodName = BridgesConstructions.callMethod(methodName);
8181
8307
  if (this.config.irHack.isIrHackInterface(iface.name)) {
8182
- 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)}`);
8183
8310
  }
8184
8311
  this.printBody(node, signature, pandaMethodName);
8185
8312
  });
@@ -8269,6 +8396,90 @@ function id(value) {
8269
8396
  return value;
8270
8397
  }
8271
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
+
8272
8483
  /*
8273
8484
  * Copyright (c) 2024 Huawei Device Co., Ltd.
8274
8485
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -8286,7 +8497,17 @@ function id(value) {
8286
8497
  class EnumsPrinter extends SingleFilePrinter {
8287
8498
  constructor() {
8288
8499
  super(...arguments);
8289
- 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
+ });
8290
8511
  }
8291
8512
  printInterface(node) { }
8292
8513
  filterInterface(node) {
@@ -8304,6 +8525,9 @@ class EnumsPrinter extends SingleFilePrinter {
8304
8525
  };
8305
8526
  }), { isExport: true });
8306
8527
  }
8528
+ printTypedef(node) {
8529
+ this.writer.writeTypeDeclaration(createTypedef(fixEnumPrefix(node.name), node.type, node.typeParameters));
8530
+ }
8307
8531
  }
8308
8532
 
8309
8533
  /*
@@ -8540,6 +8764,9 @@ class PeersConstructions {
8540
8764
  static get arrayOfPointersToArrayOfPeers() {
8541
8765
  return `unpackNodeArray`;
8542
8766
  }
8767
+ static get arrayOfPointersToArrayOfObjects() {
8768
+ return `unpackNativeObjectArray`;
8769
+ }
8543
8770
  static get receiveString() {
8544
8771
  return `unpackString`;
8545
8772
  }
@@ -8665,40 +8892,6 @@ class Importer {
8665
8892
  }
8666
8893
  }
8667
8894
 
8668
- /*
8669
- * Copyright (c) 2024 Huawei Device Co., Ltd.
8670
- * Licensed under the Apache License, Version 2.0 (the "License");
8671
- * you may not use this file except in compliance with the License.
8672
- * You may obtain a copy of the License at
8673
- *
8674
- * http://www.apache.org/licenses/LICENSE-2.0
8675
- *
8676
- * Unless required by applicable law or agreed to in writing, software
8677
- * distributed under the License is distributed on an "AS IS" BASIS,
8678
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8679
- * See the License for the specific language governing permissions and
8680
- * limitations under the License.
8681
- */
8682
- class TopLevelTypeConvertor extends BaseTypeConvertor {
8683
- constructor(typechecker, heirConversions) {
8684
- super(typechecker, Object.assign(Object.assign({}, heirConversions), {
8685
- i8: heirConversions.number,
8686
- iu8: heirConversions.number,
8687
- i16: heirConversions.number,
8688
- i32: heirConversions.number,
8689
- iu32: heirConversions.number,
8690
- i64: heirConversions.number,
8691
- iu64: heirConversions.number,
8692
- f32: heirConversions.number,
8693
- f64: heirConversions.number,
8694
- void: heirConversions.void,
8695
- boolean: heirConversions.boolean,
8696
- pointer: heirConversions.pointer,
8697
- undefined: heirConversions.undefined
8698
- }));
8699
- }
8700
- }
8701
-
8702
8895
  /*
8703
8896
  * Copyright (c) 2024 Huawei Device Co., Ltd.
8704
8897
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -8756,8 +8949,10 @@ class BindingParameterTypeConvertor extends TopLevelTypeConvertor {
8756
8949
  function unpackWrapper(type, typechecker) {
8757
8950
  const isAstNode = (ref) => (isReferenceType(ref) || isInterface(ref)) && typechecker.isHeir(ref, Config.astNodeCommonAncestor);
8758
8951
  if (isContainerType(type)) {
8759
- if (IDLContainerUtils.isSequence(type)) {
8760
- return PeersConstructions.arrayOfPointersToArrayOfPeers;
8952
+ if (IDLContainerUtils.isSequence(type) && isReferenceType(type.elementType[0])) {
8953
+ return isAstNode(type.elementType[0])
8954
+ ? PeersConstructions.arrayOfPointersToArrayOfPeers
8955
+ : PeersConstructions.arrayOfPointersToArrayOfObjects;
8761
8956
  }
8762
8957
  throwException(`unexpected container of non-sequence type`);
8763
8958
  }
@@ -8798,6 +8993,11 @@ function typeHintArgument(type, typechecker, importer) {
8798
8993
  }
8799
8994
  return undefined;
8800
8995
  }
8996
+ function hasFactoryArgument(wrapper) {
8997
+ return [
8998
+ PeersConstructions.arrayOfPointersToArrayOfObjects,
8999
+ ].includes(wrapper);
9000
+ }
8801
9001
 
8802
9002
  class CommonGenerator {
8803
9003
  static resolveProperty(property, iface, typechecker) {
@@ -8861,83 +9061,6 @@ class CommonGenerator {
8861
9061
  }
8862
9062
  }
8863
9063
 
8864
- class Filter {
8865
- static makeMethod(name, returnType, parameters, modifiers, isNullable) {
8866
- const params = Filter.filterParameters(parameters);
8867
- return makeMethod(name, params.map(p => ({
8868
- name: p.name,
8869
- type: this.makeOptionalType(p, isNullable),
8870
- isOptional: p.isOptional
8871
- })), this.makeOptionalType(returnType, isNullable), modifiers);
8872
- }
8873
- static makeOptionalType(param, isNullable) {
8874
- const type = isParameter(param) ? param.type : param;
8875
- return isNullable(param) ? createOptionalType(type) : type;
8876
- }
8877
- static isNullableType(type, typechecker) {
8878
- return isReferenceType(type) &&
8879
- (typechecker.isPeer(type) || type.name === Config.astNodeCommonAncestor);
8880
- }
8881
- static filterMoreSpecific(methods) {
8882
- const ifaceName = methods.length && methods[0].parent && isInterface(methods[0].parent) ? methods[0].parent.name : '';
8883
- const compat = ['ETSTuple', 'ExportNamedDeclaration'];
8884
- const noCopyCtor = methods
8885
- .filter(m => !(m.parameters.length === 2 && isContext(m.parameters[0]) && m.parameters[1].name === 'other'));
8886
- if (compat.includes(ifaceName)) {
8887
- return methods;
8888
- }
8889
- // This is a simplified algo of UniversalCreateTransformer
8890
- return noCopyCtor.length ? [
8891
- noCopyCtor.reduce((prev, curr) => curr.parameters.length > prev.parameters.length ? curr : prev, noCopyCtor[0])
8892
- ] : noCopyCtor;
8893
- }
8894
- static filterParameters(params) {
8895
- return Filter.removeArrayLengthParam(Filter.removeContextParam(params));
8896
- }
8897
- static filterMethods(methods) {
8898
- const names = new Set(methods.map(m => m.name));
8899
- const others = methods
8900
- .filter(method => !method.name.endsWith(Config.constPostfix) ||
8901
- !names.has(method.name.slice(0, -Config.constPostfix.length)));
8902
- return others;
8903
- }
8904
- static isOptional(param, typechecker) {
8905
- return isReferenceType(param.type) &&
8906
- (typechecker.isPeer(param.type) || param.type.name === Config.astNodeCommonAncestor);
8907
- }
8908
- static isArrayLengthParam(param) {
8909
- return isPrimitiveType(param.type) &&
8910
- ['u32', 'i32', 'u64', 'i64'].includes(param.type.name) &&
8911
- ['Len', 'Count', 'Num', 'argc'].some(m => param.name.endsWith(m));
8912
- }
8913
- static findArrayLengthParam(parameters, startIndex = 0) {
8914
- let seqInd = parameters.findIndex((p, index) => index >= startIndex && isSequence(p.type));
8915
- while (seqInd !== -1) {
8916
- if (seqInd > 0 && this.isArrayLengthParam(parameters[seqInd - 1])) {
8917
- return seqInd - 1;
8918
- }
8919
- if (seqInd + 1 < parameters.length && this.isArrayLengthParam(parameters[seqInd + 1])) {
8920
- return seqInd + 1;
8921
- }
8922
- seqInd = parameters.findIndex((p, index) => index >= (startIndex + seqInd + 1) && isSequence(p.type));
8923
- }
8924
- return -1;
8925
- }
8926
- static removeArrayLengthParam(parameters) {
8927
- const params = [...parameters];
8928
- let index = this.findArrayLengthParam(params);
8929
- while (index !== -1) {
8930
- params.splice(index, 1);
8931
- index = this.findArrayLengthParam(params, index);
8932
- }
8933
- return params;
8934
- }
8935
- static removeContextParam(parameters) {
8936
- const first = parameters.at(0);
8937
- return first && isContext(first) ? parameters.slice(1) : [...parameters];
8938
- }
8939
- }
8940
-
8941
9064
  /*
8942
9065
  * Copyright (c) 2024 Huawei Device Co., Ltd.
8943
9066
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -9091,6 +9214,9 @@ class PeerPrinter {
9091
9214
  const innerType = innerTypeCommon(returnType);
9092
9215
  if (wrapper) {
9093
9216
  const args = [nativeCall];
9217
+ if (hasFactoryArgument(wrapper) && isReferenceType(innerType)) {
9218
+ args.push(this.makeNativeObjectFactory(innerType, writer));
9219
+ }
9094
9220
  if (hasTypeHintArgument(wrapper)) {
9095
9221
  const hint = typeHintArgument(innerType, this.typechecker, this.importer);
9096
9222
  if (hint) {
@@ -9100,8 +9226,16 @@ class PeerPrinter {
9100
9226
  return writer.makeFunctionCall(wrapper, args);
9101
9227
  }
9102
9228
  const convertName = (ref) => makeEnoughQualifiedName(ref, this.typechecker.resolveReference.bind(this.typechecker));
9103
- return isOptionalType(returnType) && isReferenceType(innerType) ?
9104
- 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);
9105
9239
  }
9106
9240
  printCreateOrUpdate(iface, node, writer) {
9107
9241
  const extraParameters = CommonGenerator.makeExtraParameters(iface, this.config, this.typechecker);
@@ -9198,6 +9332,9 @@ function convertAndImport(importer, converter, type, config) {
9198
9332
  if (node && isEnum(node)) {
9199
9333
  importer.withEnumImport(result);
9200
9334
  }
9335
+ else if (node && isTypedef(node)) {
9336
+ importer.withEnumImport(result); // typedefs print as enums
9337
+ }
9201
9338
  else if (node && isInterface(node) && converter.typechecker.isPeer(node)) {
9202
9339
  if (config.ignore.hasReexportReplacement(fqName(node))) {
9203
9340
  importer.withReexportImport(dropPrefix(type.name, Config.dataClassPrefix));
@@ -9210,56 +9347,6 @@ function convertAndImport(importer, converter, type, config) {
9210
9347
  return result;
9211
9348
  }
9212
9349
 
9213
- /*
9214
- * Copyright (c) 2024 Huawei Device Co., Ltd.
9215
- * Licensed under the Apache License, Version 2.0 (the "License");
9216
- * you may not use this file except in compliance with the License.
9217
- * You may obtain a copy of the License at
9218
- *
9219
- * http://www.apache.org/licenses/LICENSE-2.0
9220
- *
9221
- * Unless required by applicable law or agreed to in writing, software
9222
- * distributed under the License is distributed on an "AS IS" BASIS,
9223
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9224
- * See the License for the specific language governing permissions and
9225
- * limitations under the License.
9226
- */
9227
- class _LibraryTypeConvertor extends TopLevelTypeConvertor {
9228
- constructor(typechecker) {
9229
- super(typechecker, {
9230
- enum: (type) => type.name,
9231
- reference: (type) => type.name,
9232
- sequence: (type) => `readonly ${this.convertType(innerType(type))}[]`,
9233
- optional: (type) => `${this.convertType(type.type)} | undefined`,
9234
- string: (type) => `string`,
9235
- number: (type) => `number`,
9236
- void: (type) => `void`,
9237
- boolean: (type) => `boolean`,
9238
- pointer: (type) => `KNativePointer`,
9239
- undefined: (type) => `undefined`
9240
- });
9241
- }
9242
- }
9243
- class LibraryTypeConvertor extends _LibraryTypeConvertor {
9244
- constructor(typechecker, fullQualified = false) {
9245
- super(typechecker);
9246
- this.fullQualified = fullQualified;
9247
- }
9248
- convertTypeReference(type) {
9249
- const node = this.typechecker.resolveReference(type);
9250
- if (node && isEnum(node)) {
9251
- if (node.name.startsWith(Config.dataClassPrefix)) {
9252
- // TODO: support enums in namespace?
9253
- return `Es2panda${node.name.slice(Config.dataClassPrefix.length)}`;
9254
- }
9255
- }
9256
- const resolver = this.typechecker.resolveReference.bind(this.typechecker);
9257
- return this.fullQualified
9258
- ? makeFullyQualifiedName(type, resolver)
9259
- : makeEnoughQualifiedName(type, resolver);
9260
- }
9261
- }
9262
-
9263
9350
  /*
9264
9351
  * Copyright (c) 2024 Huawei Device Co., Ltd.
9265
9352
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -9290,9 +9377,13 @@ class AllPeersPrinter extends MultiFilePrinter {
9290
9377
  if (members.length === 0) {
9291
9378
  return [];
9292
9379
  }
9293
- 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
9294
9384
  writer.pushNamespace(ns.name, { ident: false });
9295
- members.forEach(m => printer.printInterface(m, writer));
9385
+ this.sortInterfaces(members)
9386
+ .forEach(m => printer.printInterface(m, writer));
9296
9387
  writer.popNamespace({ ident: false });
9297
9388
  })];
9298
9389
  }
@@ -9307,13 +9398,16 @@ class AllPeersPrinter extends MultiFilePrinter {
9307
9398
  writer.popNamespace({ ident: false });
9308
9399
  });
9309
9400
  }
9310
- 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
+ });
9311
9405
  }
9312
9406
  printFile(name, exports, cb) {
9313
9407
  const importer = new Importer('.', name);
9314
9408
  const writer = this.makeWriter(importer);
9315
9409
  const printer = new PeerPrinter(this.config, this.typechecker, importer);
9316
- cb(printer, writer);
9410
+ cb(printer, writer, importer);
9317
9411
  return {
9318
9412
  exports: exports,
9319
9413
  fileName: PeersConstructions.fileName(name),
@@ -9341,6 +9435,22 @@ class AllPeersPrinter extends MultiFilePrinter {
9341
9435
  };
9342
9436
  return visitInterfaces(this.idl);
9343
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
+ }
9344
9454
  makeWriter(importer) {
9345
9455
  const converter = {
9346
9456
  convert: (node) => convertAndImport(importer, new LibraryTypeConvertor(this.typechecker), node, this.config)
@@ -9473,7 +9583,7 @@ class FactoryPrinter extends SingleFilePrinter {
9473
9583
  type: Filter.makeOptionalType(p.type, isNullable),
9474
9584
  isOptional: p.isOptional
9475
9585
  })), createReferenceType(node.name));
9476
- 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
9477
9587
  .map(mangleIfKeyword)
9478
9588
  .map(it => this.writer.makeString(it))))));
9479
9589
  }
@@ -9505,7 +9615,7 @@ class FactoryPrinter extends SingleFilePrinter {
9505
9615
  if (parameters.length) {
9506
9616
  writer.writeStatement(writer.makeCondition(expr(isSameAll), writer.makeReturn(expr(FactoryConstructions.original))));
9507
9617
  }
9508
- const createCall = writer.makeFunctionCall(this.callUniversalCreate(node, universalName), parameters
9618
+ const createCall = writer.makeStaticMethodCall(makeFullyQualifiedName(node), PeersConstructions.createOrUpdate(node.name, universalName), parameters
9509
9619
  .concat(extraParameters)
9510
9620
  .map(p => expr(mangleIfKeyword(p.name))));
9511
9621
  writer.writeStatement(writer.makeReturn(writer.makeFunctionCall(FactoryConstructions.updateNodeByNode, [
@@ -9513,9 +9623,6 @@ class FactoryPrinter extends SingleFilePrinter {
9513
9623
  ])));
9514
9624
  });
9515
9625
  }
9516
- callUniversalCreate(node, name) {
9517
- return PeersConstructions.callPeerMethod(node.name, PeersConstructions.createOrUpdate(node.name, name));
9518
- }
9519
9626
  gettersForParams(params, methods) {
9520
9627
  const toTypeName = (type) => {
9521
9628
  const rawType = isOptionalType(type) ? type.type : type;