@abaplint/transpiler-cli 2.13.85 → 2.13.86

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 (2) hide show
  1. package/build/bundle.js +184 -34
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -63578,6 +63578,9 @@ const ddic_1 = __webpack_require__(/*! ../ddic */ "./node_modules/@abaplint/core
63578
63578
  const Types = __importStar(__webpack_require__(/*! ../abap/types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js"));
63579
63579
  const xml_utils_1 = __webpack_require__(/*! ../xml_utils */ "./node_modules/@abaplint/core/build/src/xml_utils.js");
63580
63580
  const domain_1 = __webpack_require__(/*! ./domain */ "./node_modules/@abaplint/core/build/src/objects/domain.js");
63581
+ const _identifier_1 = __webpack_require__(/*! ../abap/4_file_information/_identifier */ "./node_modules/@abaplint/core/build/src/abap/4_file_information/_identifier.js");
63582
+ const identifier_1 = __webpack_require__(/*! ../abap/1_lexer/tokens/identifier */ "./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/identifier.js");
63583
+ const position_1 = __webpack_require__(/*! ../position */ "./node_modules/@abaplint/core/build/src/position.js");
63581
63584
  class DataElement extends _abstract_object_1.AbstractObject {
63582
63585
  constructor() {
63583
63586
  super(...arguments);
@@ -63598,6 +63601,17 @@ class DataElement extends _abstract_object_1.AbstractObject {
63598
63601
  allowNamespace: true,
63599
63602
  };
63600
63603
  }
63604
+ getIdentifier() {
63605
+ const xmlIdentifier = super.getIdentifier();
63606
+ if (xmlIdentifier) {
63607
+ return xmlIdentifier;
63608
+ }
63609
+ const file = this.getAFFFile();
63610
+ if (file === undefined) {
63611
+ return undefined;
63612
+ }
63613
+ return new _identifier_1.Identifier(new identifier_1.Identifier(new position_1.Position(1, 1), this.getName()), file.getFilename());
63614
+ }
63601
63615
  setDirty() {
63602
63616
  this.parsedXML = undefined;
63603
63617
  this.parsedType = undefined;
@@ -63645,7 +63659,6 @@ class DataElement extends _abstract_object_1.AbstractObject {
63645
63659
  return (_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.dtelmaster;
63646
63660
  }
63647
63661
  parseType(reg) {
63648
- var _a;
63649
63662
  const references = [];
63650
63663
  let lookup = undefined;
63651
63664
  this.parse();
@@ -63657,7 +63670,53 @@ class DataElement extends _abstract_object_1.AbstractObject {
63657
63670
  return this.parsedType;
63658
63671
  }
63659
63672
  const ddic = new ddic_1.DDIC(reg);
63660
- if (this.parsedXML.refkind === "D") {
63673
+ const lookupPredefinedType = () => {
63674
+ var _a, _b;
63675
+ if (((_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.datatype) === undefined || this.parsedXML.datatype === "") {
63676
+ return { type: new Types.UnknownType("DATATYPE unexpectely empty in " + this.getName()) };
63677
+ }
63678
+ return { type: ddic.textToType({
63679
+ text: this.parsedXML.datatype,
63680
+ length: this.parsedXML.leng,
63681
+ decimals: this.parsedXML.decimals,
63682
+ infoText: this.getName(),
63683
+ qualifiedName: this.getName(),
63684
+ conversionExit: undefined,
63685
+ ddicName: this.getName(),
63686
+ description: (_b = this.parsedXML.texts) === null || _b === void 0 ? void 0 : _b.heading,
63687
+ }) };
63688
+ };
63689
+ if (this.parsedXML.affCategory === "referenceToPredefinedType") {
63690
+ const predefined = lookupPredefinedType();
63691
+ lookup = predefined.type instanceof Types.UnknownType
63692
+ ? predefined
63693
+ : { type: new Types.DataReference(predefined.type, this.getName()) };
63694
+ }
63695
+ else if (this.parsedXML.affCategory === "referenceDictionaryType") {
63696
+ if (this.parsedXML.domname === undefined || this.parsedXML.domname === "") {
63697
+ lookup = { type: new Types.UnknownType("Type name unexpectely empty in " + this.getName()) };
63698
+ }
63699
+ else {
63700
+ const referenced = ddic.lookup(this.parsedXML.domname);
63701
+ lookup = referenced.type instanceof Types.UnknownType
63702
+ ? referenced
63703
+ : Object.assign(Object.assign({}, referenced), { type: new Types.DataReference(referenced.type, this.getName()) });
63704
+ }
63705
+ }
63706
+ else if (this.parsedXML.affCategory === "referenceClasIntType") {
63707
+ if (this.parsedXML.domname === undefined || this.parsedXML.domname === "") {
63708
+ lookup = { type: new Types.UnknownType("Type name unexpectely empty in " + this.getName()) };
63709
+ }
63710
+ else {
63711
+ lookup = ddic.lookupObject(this.parsedXML.domname);
63712
+ }
63713
+ }
63714
+ else if (this.parsedXML.affCategory !== undefined
63715
+ && this.parsedXML.affCategory !== "domain"
63716
+ && this.parsedXML.affCategory !== "predefinedType") {
63717
+ lookup = { type: new Types.UnknownType("Unknown AFF data type category " + this.parsedXML.affCategory + " in " + this.getName()) };
63718
+ }
63719
+ else if (this.parsedXML.refkind === "D") {
63661
63720
  if (this.parsedXML.domname === undefined || this.parsedXML.domname === "") {
63662
63721
  lookup = { type: new Types.UnknownType("DOMNAME unexpectely empty in " + this.getName()) };
63663
63722
  }
@@ -63674,21 +63733,7 @@ class DataElement extends _abstract_object_1.AbstractObject {
63674
63733
  }
63675
63734
  }
63676
63735
  else {
63677
- if (this.parsedXML.datatype === undefined || this.parsedXML.datatype === "") {
63678
- lookup = { type: new Types.UnknownType("DATATYPE unexpectely empty in " + this.getName()) };
63679
- }
63680
- else {
63681
- lookup = { type: ddic.textToType({
63682
- text: this.parsedXML.datatype,
63683
- length: this.parsedXML.leng,
63684
- decimals: this.parsedXML.decimals,
63685
- infoText: this.getName(),
63686
- qualifiedName: this.getName(),
63687
- conversionExit: undefined,
63688
- ddicName: this.getName(),
63689
- description: (_a = this.parsedXML.texts) === null || _a === void 0 ? void 0 : _a.heading,
63690
- }) };
63691
- }
63736
+ lookup = lookupPredefinedType();
63692
63737
  }
63693
63738
  }
63694
63739
  if (lookup.object) {
@@ -63703,17 +63748,52 @@ class DataElement extends _abstract_object_1.AbstractObject {
63703
63748
  return lookup.type;
63704
63749
  }
63705
63750
  parse() {
63706
- var _a, _b, _c, _d, _e, _f, _g;
63751
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
63707
63752
  if (this.parsedXML !== undefined) {
63708
63753
  return { updated: false, runtime: 0 };
63709
63754
  }
63710
63755
  const start = Date.now();
63711
63756
  this.parsedXML = {};
63757
+ const jsonFile = this.getAFFFile();
63758
+ if (jsonFile) {
63759
+ try {
63760
+ const parsed = JSON.parse(jsonFile.getRaw());
63761
+ const typeInformation = parsed.dataTypeInformation;
63762
+ const predefinedType = typeInformation === null || typeInformation === void 0 ? void 0 : typeInformation.predefinedType;
63763
+ const fieldLabels = parsed.fieldLabels;
63764
+ this.parsedXML = {
63765
+ description: (_a = parsed.header) === null || _a === void 0 ? void 0 : _a.description,
63766
+ affCategory: typeInformation === null || typeInformation === void 0 ? void 0 : typeInformation.category,
63767
+ refkind: (typeInformation === null || typeInformation === void 0 ? void 0 : typeInformation.category) === "domain" ? "D" : undefined,
63768
+ domname: typeInformation === null || typeInformation === void 0 ? void 0 : typeInformation.typeName,
63769
+ datatype: predefinedType === null || predefinedType === void 0 ? void 0 : predefinedType.dataType,
63770
+ leng: (_b = predefinedType === null || predefinedType === void 0 ? void 0 : predefinedType.length) === null || _b === void 0 ? void 0 : _b.toString(),
63771
+ decimals: (_c = predefinedType === null || predefinedType === void 0 ? void 0 : predefinedType.decimals) === null || _c === void 0 ? void 0 : _c.toString(),
63772
+ texts: {
63773
+ short: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.short,
63774
+ medium: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.medium,
63775
+ long: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.long,
63776
+ heading: fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.heading,
63777
+ },
63778
+ textMaxLengths: {
63779
+ short: (_d = fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.shortLength) === null || _d === void 0 ? void 0 : _d.toString(),
63780
+ medium: (_e = fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.mediumLength) === null || _e === void 0 ? void 0 : _e.toString(),
63781
+ long: (_f = fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.longLength) === null || _f === void 0 ? void 0 : _f.toString(),
63782
+ heading: (_g = fieldLabels === null || fieldLabels === void 0 ? void 0 : fieldLabels.headingLength) === null || _g === void 0 ? void 0 : _g.toString(),
63783
+ },
63784
+ };
63785
+ }
63786
+ catch (_q) {
63787
+ // handled by parseType()
63788
+ }
63789
+ const end = Date.now();
63790
+ return { updated: true, runtime: end - start };
63791
+ }
63712
63792
  const parsed = super.parseRaw2();
63713
63793
  if (parsed === undefined) {
63714
63794
  return { updated: false, runtime: 0 };
63715
63795
  }
63716
- const dd04v = (_c = (_b = (_a = parsed.abapGit) === null || _a === void 0 ? void 0 : _a["asx:abap"]) === null || _b === void 0 ? void 0 : _b["asx:values"]) === null || _c === void 0 ? void 0 : _c.DD04V;
63796
+ const dd04v = (_k = (_j = (_h = parsed.abapGit) === null || _h === void 0 ? void 0 : _h["asx:abap"]) === null || _j === void 0 ? void 0 : _j["asx:values"]) === null || _k === void 0 ? void 0 : _k.DD04V;
63717
63797
  this.parsedXML = {
63718
63798
  description: dd04v === null || dd04v === void 0 ? void 0 : dd04v.DDTEXT,
63719
63799
  refkind: dd04v === null || dd04v === void 0 ? void 0 : dd04v.REFKIND,
@@ -63736,7 +63816,7 @@ class DataElement extends _abstract_object_1.AbstractObject {
63736
63816
  },
63737
63817
  };
63738
63818
  this.parsedXML.textsTranslations = [];
63739
- for (const item of (0, xml_utils_1.xmlToArray)((_g = (_f = (_e = (_d = parsed.abapGit) === null || _d === void 0 ? void 0 : _d["asx:abap"]) === null || _e === void 0 ? void 0 : _e["asx:values"]) === null || _f === void 0 ? void 0 : _f.DD04_TEXTS) === null || _g === void 0 ? void 0 : _g.item)) {
63819
+ for (const item of (0, xml_utils_1.xmlToArray)((_p = (_o = (_m = (_l = parsed.abapGit) === null || _l === void 0 ? void 0 : _l["asx:abap"]) === null || _m === void 0 ? void 0 : _m["asx:values"]) === null || _o === void 0 ? void 0 : _o.DD04_TEXTS) === null || _p === void 0 ? void 0 : _p.item)) {
63740
63820
  this.parsedXML.textsTranslations.push({
63741
63821
  language: item.DDLANGUAGE,
63742
63822
  description: item.DDTEXT,
@@ -63749,6 +63829,9 @@ class DataElement extends _abstract_object_1.AbstractObject {
63749
63829
  const end = Date.now();
63750
63830
  return { updated: true, runtime: end - start };
63751
63831
  }
63832
+ getAFFFile() {
63833
+ return this.getFiles().find(file => file.getFilename().toLowerCase().endsWith(".dtel.json"));
63834
+ }
63752
63835
  }
63753
63836
  exports.DataElement = DataElement;
63754
63837
  //# sourceMappingURL=data_element.js.map
@@ -63895,16 +63978,21 @@ const _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ "./node
63895
63978
  const Types = __importStar(__webpack_require__(/*! ../abap/types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js"));
63896
63979
  const ddic_1 = __webpack_require__(/*! ../ddic */ "./node_modules/@abaplint/core/build/src/ddic.js");
63897
63980
  const xml_utils_1 = __webpack_require__(/*! ../xml_utils */ "./node_modules/@abaplint/core/build/src/xml_utils.js");
63981
+ const _identifier_1 = __webpack_require__(/*! ../abap/4_file_information/_identifier */ "./node_modules/@abaplint/core/build/src/abap/4_file_information/_identifier.js");
63982
+ const identifier_1 = __webpack_require__(/*! ../abap/1_lexer/tokens/identifier */ "./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/identifier.js");
63983
+ const position_1 = __webpack_require__(/*! ../position */ "./node_modules/@abaplint/core/build/src/position.js");
63898
63984
  class Domain extends _abstract_object_1.AbstractObject {
63899
63985
  getType() {
63900
63986
  return "DOMA";
63901
63987
  }
63902
63988
  getDescription() {
63903
63989
  var _a;
63990
+ this.parse();
63904
63991
  return (_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.description;
63905
63992
  }
63906
63993
  getConversionExit() {
63907
63994
  var _a;
63995
+ this.parse();
63908
63996
  return (_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.conversionExit;
63909
63997
  }
63910
63998
  getDataType() {
@@ -63918,6 +64006,17 @@ class Domain extends _abstract_object_1.AbstractObject {
63918
64006
  allowNamespace: true,
63919
64007
  };
63920
64008
  }
64009
+ getIdentifier() {
64010
+ const xmlIdentifier = super.getIdentifier();
64011
+ if (xmlIdentifier) {
64012
+ return xmlIdentifier;
64013
+ }
64014
+ const file = this.getAFFFile();
64015
+ if (file === undefined) {
64016
+ return undefined;
64017
+ }
64018
+ return new _identifier_1.Identifier(new identifier_1.Identifier(new position_1.Position(1, 1), this.getName()), file.getFilename());
64019
+ }
63921
64020
  setDirty() {
63922
64021
  this.parsedXML = undefined;
63923
64022
  super.setDirty();
@@ -63944,18 +64043,57 @@ class Domain extends _abstract_object_1.AbstractObject {
63944
64043
  });
63945
64044
  }
63946
64045
  parse() {
63947
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
64046
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
64047
+ var _v, _w;
63948
64048
  if (this.parsedXML) {
63949
64049
  return { updated: false, runtime: 0 };
63950
64050
  }
63951
64051
  const start = Date.now();
63952
64052
  this.parsedXML = {};
64053
+ const jsonFile = this.getAFFFile();
64054
+ if (jsonFile) {
64055
+ try {
64056
+ const parsed = JSON.parse(jsonFile.getRaw());
64057
+ const language = (_a = parsed.header) === null || _a === void 0 ? void 0 : _a.originalLanguage;
64058
+ const values = [];
64059
+ for (const fixedValue of (_v = parsed.fixedValues) !== null && _v !== void 0 ? _v : []) {
64060
+ values.push({
64061
+ low: fixedValue === null || fixedValue === void 0 ? void 0 : fixedValue.fixedValue,
64062
+ high: "",
64063
+ description: fixedValue === null || fixedValue === void 0 ? void 0 : fixedValue.description,
64064
+ language: language,
64065
+ });
64066
+ }
64067
+ for (const interval of (_w = parsed.fixedValueIntervals) !== null && _w !== void 0 ? _w : []) {
64068
+ values.push({
64069
+ low: interval === null || interval === void 0 ? void 0 : interval.lowLimit,
64070
+ high: interval === null || interval === void 0 ? void 0 : interval.highLimit,
64071
+ description: interval === null || interval === void 0 ? void 0 : interval.description,
64072
+ language: language,
64073
+ });
64074
+ }
64075
+ this.parsedXML = {
64076
+ description: (_b = parsed.header) === null || _b === void 0 ? void 0 : _b.description,
64077
+ datatype: (_c = parsed.format) === null || _c === void 0 ? void 0 : _c.dataType,
64078
+ length: (_e = (_d = parsed.format) === null || _d === void 0 ? void 0 : _d.length) === null || _e === void 0 ? void 0 : _e.toString(),
64079
+ decimals: (_g = (_f = parsed.format) === null || _f === void 0 ? void 0 : _f.decimals) === null || _g === void 0 ? void 0 : _g.toString(),
64080
+ conversionExit: (_h = parsed.outputCharacteristics) === null || _h === void 0 ? void 0 : _h.conversionRoutine,
64081
+ values: values,
64082
+ valuesTranslations: [],
64083
+ };
64084
+ }
64085
+ catch (_x) {
64086
+ // handled by parseType()
64087
+ }
64088
+ const end = Date.now();
64089
+ return { updated: true, runtime: end - start };
64090
+ }
63953
64091
  const parsed = super.parseRaw2();
63954
64092
  if (parsed === undefined) {
63955
64093
  return { updated: false, runtime: 0 };
63956
64094
  }
63957
- const dd01v = (_c = (_b = (_a = parsed.abapGit) === null || _a === void 0 ? void 0 : _a["asx:abap"]) === null || _b === void 0 ? void 0 : _b["asx:values"]) === null || _c === void 0 ? void 0 : _c.DD01V;
63958
- const dd07v_tab = (0, xml_utils_1.xmlToArray)((_g = (_f = (_e = (_d = parsed.abapGit) === null || _d === void 0 ? void 0 : _d["asx:abap"]) === null || _e === void 0 ? void 0 : _e["asx:values"]) === null || _f === void 0 ? void 0 : _f.DD07V_TAB) === null || _g === void 0 ? void 0 : _g.DD07V);
64095
+ const dd01v = (_l = (_k = (_j = parsed.abapGit) === null || _j === void 0 ? void 0 : _j["asx:abap"]) === null || _k === void 0 ? void 0 : _k["asx:values"]) === null || _l === void 0 ? void 0 : _l.DD01V;
64096
+ const dd07v_tab = (0, xml_utils_1.xmlToArray)((_q = (_p = (_o = (_m = parsed.abapGit) === null || _m === void 0 ? void 0 : _m["asx:abap"]) === null || _o === void 0 ? void 0 : _o["asx:values"]) === null || _p === void 0 ? void 0 : _p.DD07V_TAB) === null || _q === void 0 ? void 0 : _q.DD07V);
63959
64097
  const values = [];
63960
64098
  for (const ddo7v of dd07v_tab) {
63961
64099
  const value = {
@@ -63966,7 +64104,7 @@ class Domain extends _abstract_object_1.AbstractObject {
63966
64104
  };
63967
64105
  values.push(value);
63968
64106
  }
63969
- const dd07v_texts = (0, xml_utils_1.xmlToArray)((_l = (_k = (_j = (_h = parsed.abapGit) === null || _h === void 0 ? void 0 : _h["asx:abap"]) === null || _j === void 0 ? void 0 : _j["asx:values"]) === null || _k === void 0 ? void 0 : _k.DD07_TEXTS) === null || _l === void 0 ? void 0 : _l.item);
64107
+ const dd07v_texts = (0, xml_utils_1.xmlToArray)((_u = (_t = (_s = (_r = parsed.abapGit) === null || _r === void 0 ? void 0 : _r["asx:abap"]) === null || _s === void 0 ? void 0 : _s["asx:values"]) === null || _t === void 0 ? void 0 : _t.DD07_TEXTS) === null || _u === void 0 ? void 0 : _u.item);
63970
64108
  const translationValues = [];
63971
64109
  for (const dd07v of dd07v_texts) {
63972
64110
  const value = {
@@ -63997,6 +64135,9 @@ class Domain extends _abstract_object_1.AbstractObject {
63997
64135
  var _b;
63998
64136
  return (_b = (_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.valuesTranslations) !== null && _b !== void 0 ? _b : [];
63999
64137
  }
64138
+ getAFFFile() {
64139
+ return this.getFiles().find(file => file.getFilename().toLowerCase().endsWith(".doma.json"));
64140
+ }
64000
64141
  }
64001
64142
  exports.Domain = Domain;
64002
64143
  //# sourceMappingURL=domain.js.map
@@ -70877,7 +71018,7 @@ class Registry {
70877
71018
  }
70878
71019
  static abaplintVersion() {
70879
71020
  // magic, see build script "version.js"
70880
- return "2.120.48";
71021
+ return "2.120.50";
70881
71022
  }
70882
71023
  getDDICReferences() {
70883
71024
  return this.ddicReferences;
@@ -104661,8 +104802,10 @@ class ConstantTranspiler {
104661
104802
  return new chunk_1.Chunk(`todo, Constant`);
104662
104803
  }
104663
104804
  handleCharacter(res) {
104664
- const foo = res.replace(/''/g, "'");
104665
- let length = foo.length - 2;
104805
+ // length of the value: strip the enclosing quotes first, an escaped
104806
+ // quote ('') inside counts as one character and must not merge with them
104807
+ const inner = res.substring(1, res.length - 1).replace(/''/g, "'");
104808
+ let length = inner.length;
104666
104809
  if (length <= 0) {
104667
104810
  // note: Characters cannot have length = zero, 1 is minimum
104668
104811
  length = 1;
@@ -110585,7 +110728,8 @@ globalThis.abap = new runtime.ABAP();\n`;
110585
110728
  || obj instanceof abaplint.Objects.Oauth2Profile
110586
110729
  || obj instanceof abaplint.Objects.WebMIME
110587
110730
  || obj instanceof abaplint.Objects.TypePool
110588
- || obj instanceof abaplint.Objects.TableType) {
110731
+ || obj instanceof abaplint.Objects.TableType
110732
+ || obj instanceof abaplint.Objects.View) {
110589
110733
  list.push(imp(`${escapeNamespaceFilename(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
110590
110734
  }
110591
110735
  }
@@ -118788,9 +118932,11 @@ class SelectTranspiler {
118788
118932
  where = sqlCond;
118789
118933
  }
118790
118934
  }
118935
+ let whereClause = "";
118791
118936
  if (where) {
118792
- select += "WHERE " + new expressions_1.SQLCondTranspiler().transpile(where, traversal, table).getCode() + " ";
118937
+ whereClause = "WHERE " + new expressions_1.SQLCondTranspiler().transpile(where, traversal, table).getCode() + " ";
118793
118938
  }
118939
+ select += whereClause;
118794
118940
  const groupBy = node.findFirstExpression(abaplint.Expressions.SQLGroupBy);
118795
118941
  if (groupBy) {
118796
118942
  select += new sql_group_by_1.SQLGroupByTranspiler().transpile(groupBy, traversal).getCode() + " ";
@@ -118831,6 +118977,7 @@ class SelectTranspiler {
118831
118977
  else {
118832
118978
  const code = new expressions_1.FieldChainTranspiler(true).transpile(chain, traversal).getCode();
118833
118979
  select = select.replace(search, `" + ${code} + "`);
118980
+ whereClause = whereClause.replace(search, `" + ${code} + "`);
118834
118981
  }
118835
118982
  }
118836
118983
  }
@@ -118858,14 +119005,17 @@ class SelectTranspiler {
118858
119005
  const unique2 = unique_identifier_1.UniqueIdentifier.get();
118859
119006
  const fn = node.findFirstExpression(abaplint.Expressions.SQLForAllEntries)?.findDirectExpression(abaplint.Expressions.SQLSource);
118860
119007
  const faeTranspiled = new expressions_1.SQLSourceTranspiler().transpile(fn, traversal).getCode();
119008
+ // ABAP semantics: with an empty driving table the whole WHERE condition is ignored
119009
+ const selectEmpty = select.replace(whereClause, "");
118861
119010
  select = select.replace(new RegExp(" " + escapeRegExp(faeTranspiled), "g"), " " + unique);
118862
119011
  select = select.replace(unique + ".get().table_line.get()", unique + ".get()"); // there can be only one?
118863
- let by = `Object.keys(${target}.getRowType().get())`;
118864
- if (keys.length > 0) {
118865
- by = JSON.stringify(keys);
118866
- }
119012
+ // FOR ALL ENTRIES removes duplicate rows from the result: duplicates of
119013
+ // the selected columns, so de-duplicate by the target's components. The
119014
+ // DB key alone is wrong for projections (INTO CORRESPONDING FIELDS
119015
+ // without the key fields crashed on the missing component names)
119016
+ const by = `Object.keys(${target}.getRowType().get())`;
118867
119017
  const code = `if (${faeTranspiled}.array().length === 0) {
118868
- throw new Error("FAE, todo, empty table");
119018
+ await abap.statements.select(${target}, {select: "${selectEmpty.trim()}"${extra}});
118869
119019
  } else {
118870
119020
  const ${unique2} = ${faeTranspiled}.array();
118871
119021
  ${target}.clear();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.13.85",
3
+ "version": "2.13.86",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -27,8 +27,8 @@
27
27
  "author": "abaplint",
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@abaplint/core": "^2.120.48",
31
- "@abaplint/transpiler": "^2.13.85",
30
+ "@abaplint/core": "^2.120.50",
31
+ "@abaplint/transpiler": "^2.13.86",
32
32
  "@types/glob": "^9.0.0",
33
33
  "@types/node": "^26.4.1",
34
34
  "@types/progress": "^2.0.7",