@abaplint/transpiler-cli 2.11.96 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/abap_transpile CHANGED
@@ -1,2 +1,2 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  require("./build/bundle");
package/build/bundle.js CHANGED
@@ -47,7 +47,6 @@ class TranspilerConfig {
47
47
  ignoreSyntaxCheck: false,
48
48
  addFilenames: true,
49
49
  addCommonJS: true,
50
- skipConstants: false,
51
50
  unknownTypes: transpiler_1.UnknownTypesEnum.compileError,
52
51
  },
53
52
  };
@@ -6509,7 +6508,7 @@ const combi_1 = __webpack_require__(/*! ../combi */ "./node_modules/@abaplint/co
6509
6508
  const tokens_1 = __webpack_require__(/*! ../../1_lexer/tokens */ "./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js");
6510
6509
  class ReportName extends combi_1.Expression {
6511
6510
  getRunnable() {
6512
- return (0, combi_1.seq)((0, combi_1.regex)(/^[\w/$%]+$/), (0, combi_1.star)((0, combi_1.seq)((0, combi_1.tok)(tokens_1.Dash), (0, combi_1.regex)(/^\w+$/))));
6511
+ return (0, combi_1.seq)((0, combi_1.regex)(/^[\w/$%&]+$/), (0, combi_1.star)((0, combi_1.seq)((0, combi_1.tok)(tokens_1.Dash), (0, combi_1.regex)(/^\w+$/))));
6513
6512
  }
6514
6513
  }
6515
6514
  exports.ReportName = ReportName;
@@ -7067,13 +7066,14 @@ const sql_field_name_1 = __webpack_require__(/*! ./sql_field_name */ "./node_mod
7067
7066
  const sql_source_1 = __webpack_require__(/*! ./sql_source */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/sql_source.js");
7068
7067
  class SQLCase extends combi_1.Expression {
7069
7068
  getRunnable() {
7069
+ const abap = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WAt), _1.SimpleFieldChain2);
7070
7070
  const field = (0, combi_1.altPrio)(_1.SQLAggregation, SQLCase, _1.SQLFunction, _1.SQLPath, sql_field_name_1.SQLFieldName, constant_1.Constant);
7071
7071
  const sub = (0, combi_1.seq)((0, combi_1.altPrio)("+", "-", "*", "/", "&&"), (0, combi_1.optPrio)((0, combi_1.tok)(tokens_1.WParenLeftW)), field, (0, combi_1.optPrio)((0, combi_1.tok)(tokens_1.WParenRightW)));
7072
7072
  const sourc = (0, combi_1.altPrio)(SQLCase, _1.SQLAggregation, _1.SQLFunction, sql_source_1.SQLSource, constant_1.Constant);
7073
- const val = (0, combi_1.altPrio)(sql_cond_1.SQLCond, constant_1.Constant, (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WAt), _1.SimpleSource3));
7073
+ const val = (0, combi_1.altPrio)(sql_cond_1.SQLCond, constant_1.Constant, abap);
7074
7074
  const when = (0, combi_1.seq)("WHEN", val, "THEN", sourc, (0, combi_1.starPrio)(sub));
7075
7075
  const els = (0, combi_1.seq)("ELSE", sourc);
7076
- return (0, combi_1.ver)(version_1.Version.v740sp05, (0, combi_1.seq)("CASE", (0, combi_1.opt)(sql_field_name_1.SQLFieldName), (0, combi_1.plusPrio)(when), (0, combi_1.optPrio)(els), "END"));
7076
+ return (0, combi_1.ver)(version_1.Version.v740sp05, (0, combi_1.seq)("CASE", (0, combi_1.opt)((0, combi_1.altPrio)(sql_field_name_1.SQLFieldName, abap)), (0, combi_1.plusPrio)(when), (0, combi_1.optPrio)(els), "END"));
7077
7077
  }
7078
7078
  }
7079
7079
  exports.SQLCase = SQLCase;
@@ -14110,7 +14110,8 @@ class ModifyEntities {
14110
14110
  const updateFrom = (0, combi_1.seq)("UPDATE FROM", expressions_1.Source, (0, combi_1.opt)(relating));
14111
14111
  const deleteFrom = (0, combi_1.seq)("DELETE FROM", expressions_1.Source);
14112
14112
  const updateFields = (0, combi_1.seq)("UPDATE", fieldsWith);
14113
- const operation = (0, combi_1.alt)((0, combi_1.seq)("UPDATE SET FIELDS WITH", expressions_1.Source), (0, combi_1.seq)("CREATE SET FIELDS WITH", expressions_1.Source), updateFields, deleteFrom, updateFrom, create, execute, (0, combi_1.seq)("CREATE", (0, combi_1.opt)(by), (0, combi_1.optPrio)("AUTO FILL CID"), (0, combi_1.altPrio)(withh, fieldsWith)));
14113
+ const updateSetFields = (0, combi_1.seq)("UPDATE SET FIELDS WITH", expressions_1.Source);
14114
+ const operation = (0, combi_1.alt)(updateSetFields, (0, combi_1.seq)("CREATE SET FIELDS WITH", expressions_1.Source), updateFields, deleteFrom, updateFrom, create, execute, (0, combi_1.seq)("CREATE", (0, combi_1.opt)(by), (0, combi_1.optPrio)("AUTO FILL CID"), (0, combi_1.altPrio)(withh, fieldsWith)));
14114
14115
  const failed = (0, combi_1.seq)("FAILED", expressions_1.Target);
14115
14116
  const result = (0, combi_1.seq)("RESULT", expressions_1.Target);
14116
14117
  const mapped = (0, combi_1.seq)("MAPPED", expressions_1.Target);
@@ -14120,7 +14121,7 @@ class ModifyEntities {
14120
14121
  const create2 = (0, combi_1.seq)("CREATE", fieldsWith, (0, combi_1.opt)((0, combi_1.seq)("CREATE BY", expressions_1.AssociationName, fieldsWith)));
14121
14122
  const create3 = (0, combi_1.seq)("CREATE BY", expressions_1.AssociationName, fieldsWith);
14122
14123
  const create4 = (0, combi_1.seq)("CREATE FROM", expressions_1.Source, (0, combi_1.plus)((0, combi_1.seq)("CREATE BY", expressions_1.AssociationName, "FROM", expressions_1.Source)));
14123
- const entity = (0, combi_1.seq)("ENTITY", (0, combi_1.opt)("IN LOCAL MODE"), (0, combi_1.alt)(expressions_1.NamespaceSimpleName, expressions_1.EntityAssociation), (0, combi_1.alt)(execute, create, updateFields, deleteFrom, updateFrom, create2, create3, create4));
14124
+ const entity = (0, combi_1.seq)("ENTITY", (0, combi_1.opt)("IN LOCAL MODE"), (0, combi_1.alt)(expressions_1.NamespaceSimpleName, expressions_1.EntityAssociation), (0, combi_1.alt)(execute, create, updateFields, deleteFrom, updateSetFields, updateFrom, create2, create3, create4));
14124
14125
  return (0, combi_1.ver)(version_1.Version.v754, (0, combi_1.seq)("MODIFY", (0, combi_1.alt)(entities, entity), end));
14125
14126
  }
14126
14127
  }
@@ -15062,7 +15063,8 @@ class ReadEntities {
15062
15063
  const result = (0, combi_1.seq)("RESULT", expressions_1.Target);
15063
15064
  const failed = (0, combi_1.seq)("FAILED", expressions_1.Target);
15064
15065
  const reported = (0, combi_1.seq)("REPORTED", expressions_1.Target);
15065
- const entity = (0, combi_1.seq)("ENTITY", expressions_1.NamespaceSimpleName, (0, combi_1.opt)((0, combi_1.seq)("BY", expressions_1.AssociationName)), (0, combi_1.alt)(fields, from, all), (0, combi_1.optPrio)(result));
15066
+ const foo = (0, combi_1.seq)((0, combi_1.opt)((0, combi_1.seq)("BY", expressions_1.AssociationName)), (0, combi_1.alt)(fields, from, all), (0, combi_1.optPrio)(result));
15067
+ const entity = (0, combi_1.seq)("ENTITY", expressions_1.NamespaceSimpleName, (0, combi_1.plus)(foo));
15066
15068
  const s = (0, combi_1.seq)("ENTITIES OF", expressions_1.NamespaceSimpleName, (0, combi_1.opt)("IN LOCAL MODE"), (0, combi_1.plus)(entity), (0, combi_1.optPrio)((0, combi_1.seq)("LINK", expressions_1.Target)), (0, combi_1.optPrio)((0, combi_1.per)(failed, reported)));
15067
15069
  const byall = (0, combi_1.seq)("BY", expressions_1.AssociationName, all);
15068
15070
  const by = (0, combi_1.seq)("BY", expressions_1.AssociationName, fields);
@@ -16505,11 +16507,13 @@ class Submit {
16505
16507
  const cover = (0, combi_1.seq)("SAP COVER PAGE", expressions_1.Source);
16506
16508
  const copies = (0, combi_1.seq)("COPIES", expressions_1.Source);
16507
16509
  const datasetExpiration = (0, combi_1.seq)("DATASET EXPIRATION", expressions_1.Source);
16510
+ const coverText = (0, combi_1.seq)("COVER TEXT", expressions_1.Source);
16511
+ const listName = (0, combi_1.seq)("LIST NAME", expressions_1.Source);
16508
16512
  const keep = (0, combi_1.seq)("KEEP IN SPOOL", expressions_1.Source);
16509
16513
  const imm = (0, combi_1.seq)("IMMEDIATELY", expressions_1.Source);
16510
16514
  const dest = (0, combi_1.seq)("DESTINATION", expressions_1.Source);
16511
16515
  const language = (0, combi_1.seq)("LANGUAGE", expressions_1.Source);
16512
- const perm = (0, combi_1.per)((0, combi_1.plus)(awith), selectionTable, (0, combi_1.plus)(awith), spool, lineSize, lineCount, archive, user, sset, ssetp, keep, cover, imm, layout, dest, language, free, newList, uss, copies, datasetExpiration, "TO SAP-SPOOL", "WITHOUT SPOOL DYNPRO", "VIA SELECTION-SCREEN", exporting, expressions_1.AndReturn, job);
16516
+ const perm = (0, combi_1.per)((0, combi_1.plus)(awith), selectionTable, (0, combi_1.plus)(awith), spool, lineSize, lineCount, archive, user, sset, ssetp, keep, cover, imm, layout, dest, coverText, listName, language, free, newList, uss, copies, datasetExpiration, "TO SAP-SPOOL", "WITHOUT SPOOL DYNPRO", "VIA SELECTION-SCREEN", exporting, expressions_1.AndReturn, job);
16513
16517
  const ret = (0, combi_1.seq)("SUBMIT", prog, (0, combi_1.opt)(perm));
16514
16518
  return (0, combi_1.verNot)(version_1.Version.Cloud, ret);
16515
16519
  }
@@ -20276,7 +20280,9 @@ class BuiltIn {
20276
20280
  // https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-us/abennews-610-system.htm
20277
20281
  const id3 = new tokens_1.Identifier(new position_1.Position(this.row++, 1), "sy-repid");
20278
20282
  const syrepid = new _typed_identifier_1.TypedIdentifier(id3, BuiltIn.filename, new basic_1.CharacterType(40, { qualifiedName: "sy-repid" }), ["read_only" /* IdentifierMeta.ReadOnly */, "built-in" /* IdentifierMeta.BuiltIn */]);
20279
- return [sy, syst, syrepid];
20283
+ const id4 = new tokens_1.Identifier(new position_1.Position(this.row++, 1), "syst-repid");
20284
+ const systrepid = new _typed_identifier_1.TypedIdentifier(id4, BuiltIn.filename, new basic_1.CharacterType(40, { qualifiedName: "syst-repid" }), ["read_only" /* IdentifierMeta.ReadOnly */, "built-in" /* IdentifierMeta.BuiltIn */]);
20285
+ return [sy, syst, syrepid, systrepid];
20280
20286
  }
20281
20287
  buildConstant(name, type, value) {
20282
20288
  const id = new tokens_1.Identifier(new position_1.Position(this.row++, 1), name);
@@ -23296,7 +23302,7 @@ class BasicTypes {
23296
23302
  const name = typename.concatTokens();
23297
23303
  const type = (_d = this.input.scope.getDDIC().lookupDDLS(name)) === null || _d === void 0 ? void 0 : _d.type;
23298
23304
  if (type) {
23299
- return new Types.TableType(basic_1.VoidType.get("RapTodo"), options);
23305
+ return new Types.TableType(basic_1.VoidType.get("RAP-TODO"), options);
23300
23306
  }
23301
23307
  else if (this.input.scope.getDDIC().inErrorNamespace(name)) {
23302
23308
  return new Types.UnknownType(`DDLS ${name} not found`);
@@ -29583,7 +29589,7 @@ class ClassImplementation {
29583
29589
  }
29584
29590
  else {
29585
29591
  // todo: instead of the void type, do proper typing, ie. only empty constructor method
29586
- input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(new tokens_1.Identifier(new position_1.Position(1, 1), "super"), _builtin_1.BuiltIn.filename, basic_1.VoidType.get("noSuper")));
29592
+ input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(new tokens_1.Identifier(new position_1.Position(1, 1), "super"), _builtin_1.BuiltIn.filename, basic_1.VoidType.get("noSuperClass")));
29587
29593
  }
29588
29594
  input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(new tokens_1.Identifier(new position_1.Position(1, 1), "me"), _builtin_1.BuiltIn.filename, new basic_1.ObjectReferenceType(classDefinition)));
29589
29595
  helper.addAliasedAttributes(classDefinition); // todo, this is not correct, take care of instance vs static
@@ -40046,7 +40052,7 @@ const cds_integer_1 = __webpack_require__(/*! ./cds_integer */ "./node_modules/@
40046
40052
  class CDSArithmetics extends combi_1.Expression {
40047
40053
  getRunnable() {
40048
40054
  const name = (0, combi_1.seq)(_1.CDSName, (0, combi_1.optPrio)((0, combi_1.seq)(".", _1.CDSName)));
40049
- const val = (0, combi_1.altPrio)(cds_integer_1.CDSInteger, _1.CDSFunction, _1.CDSCase, _1.CDSCast, _1.CDSString, name);
40055
+ const val = (0, combi_1.altPrio)(cds_integer_1.CDSInteger, _1.CDSFunction, _1.CDSCase, _1.CDSCast, _1.CDSString, _1.CDSAggregate, name);
40050
40056
  const operator = (0, combi_1.altPrio)("+", "-", "*", "/");
40051
40057
  const operatorValue = (0, combi_1.seq)(operator, val);
40052
40058
  const paren = (0, combi_1.seq)("(", val, (0, combi_1.plusPrio)(operatorValue), ")");
@@ -40171,7 +40177,8 @@ const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node
40171
40177
  class CDSCast extends combi_1.Expression {
40172
40178
  getRunnable() {
40173
40179
  const name = (0, combi_1.seq)(_1.CDSName, (0, combi_1.starPrio)((0, combi_1.seq)(".", _1.CDSName)));
40174
- return (0, combi_1.seq)("CAST", "(", (0, combi_1.altPrio)(_1.CDSFunction, _1.CDSCase, _1.CDSAggregate, _1.CDSArithmetics, CDSCast, _1.CDSString, name), "AS", _1.CDSType, (0, combi_1.optPrio)((0, combi_1.seq)("PRESERVING", "TYPE")), ")");
40180
+ const first = (0, combi_1.altPrio)(_1.CDSFunction, _1.CDSCase, _1.CDSAggregate, _1.CDSArithmetics, CDSCast, _1.CDSString, _1.CDSInteger, name);
40181
+ return (0, combi_1.seq)("CAST", "(", first, "AS", _1.CDSType, (0, combi_1.optPrio)((0, combi_1.seq)("PRESERVING", "TYPE")), ")");
40175
40182
  }
40176
40183
  }
40177
40184
  exports.CDSCast = CDSCast;
@@ -40487,7 +40494,7 @@ const combi_1 = __webpack_require__(/*! ../../abap/2_statements/combi */ "./node
40487
40494
  class CDSFunctionInput extends combi_1.Expression {
40488
40495
  getRunnable() {
40489
40496
  const qualified = (0, combi_1.seq)(_1.CDSName, (0, combi_1.opt)(_1.CDSParameters), (0, combi_1.starPrio)((0, combi_1.seq)(".", _1.CDSName, (0, combi_1.opt)(_1.CDSParameters))));
40490
- const input = (0, combi_1.altPrio)(_1.CDSCast, _1.CDSFunction, _1.CDSArithmetics, _1.CDSCase, _1.CDSString, qualified, _1.CDSInteger);
40497
+ const input = (0, combi_1.altPrio)(_1.CDSArithmetics, _1.CDSCast, _1.CDSFunction, _1.CDSCase, _1.CDSString, qualified, _1.CDSInteger);
40491
40498
  return input;
40492
40499
  }
40493
40500
  }
@@ -40579,7 +40586,7 @@ class CDSJoin extends combi_1.Expression {
40579
40586
  getRunnable() {
40580
40587
  const cond = (0, combi_1.seq)(_1.CDSSource, "ON", cds_condition_1.CDSCondition);
40581
40588
  const foo = (0, combi_1.altPrio)((0, combi_1.seq)("(", cond, ")"), cond);
40582
- return (0, combi_1.seq)((0, combi_1.optPrio)((0, combi_1.altPrio)("LEFT OUTER TO ONE", "LEFT OUTER", "INNER", "CROSS")), "JOIN", foo);
40589
+ return (0, combi_1.seq)((0, combi_1.optPrio)((0, combi_1.altPrio)("LEFT OUTER TO ONE", "LEFT OUTER", "INNER", "CROSS", "RIGHT OUTER")), "JOIN", foo);
40583
40590
  }
40584
40591
  }
40585
40592
  exports.CDSJoin = CDSJoin;
@@ -53450,7 +53457,7 @@ class Registry {
53450
53457
  }
53451
53458
  static abaplintVersion() {
53452
53459
  // magic, see build script "version.sh"
53453
- return "2.113.218";
53460
+ return "2.113.222";
53454
53461
  }
53455
53462
  getDDICReferences() {
53456
53463
  return this.ddicReferences;
@@ -54757,6 +54764,7 @@ ENDINTERFACE.`,
54757
54764
  }
54758
54765
  issues.push(...this.checkTypes(stru, file));
54759
54766
  issues.push(...this.checkMethods(stru, file));
54767
+ issues.push(...this.checkEvents(stru, file));
54760
54768
  return issues;
54761
54769
  }
54762
54770
  check(fields, column, file) {
@@ -54816,6 +54824,26 @@ ENDINTERFACE.`,
54816
54824
  }
54817
54825
  return issues;
54818
54826
  }
54827
+ checkEvents(stru, file) {
54828
+ const issues = [];
54829
+ const events = stru.findAllStatements(Statements.Events);
54830
+ for (const e of events) {
54831
+ const fields = [];
54832
+ const params = e.findAllExpressions(Expressions.MethodParam);
54833
+ let column = 0;
54834
+ for (const p of params) {
54835
+ const children = p.getChildren();
54836
+ const name = children[children.length - 2];
54837
+ fields.push({
54838
+ nameEnd: name.getLastToken().getEnd(),
54839
+ after: p.findFirstExpression(Expressions.TypeParam).getFirstToken().getStart()
54840
+ });
54841
+ column = Math.max(column, name.getFirstToken().getEnd().getCol() + 1);
54842
+ }
54843
+ issues.push(...this.check(fields, column, file));
54844
+ }
54845
+ return issues;
54846
+ }
54819
54847
  checkTypes(stru, file) {
54820
54848
  const issues = [];
54821
54849
  const types = stru.findAllStructuresRecursive(Structures.Types);
@@ -57117,6 +57145,7 @@ class CloudTypes {
57117
57145
  || obj instanceof Objects.ApplicationLogObject
57118
57146
  || obj instanceof Objects.CommunicationScenario
57119
57147
  || obj instanceof Objects.DataControl
57148
+ || obj instanceof Objects.Namespace
57120
57149
  || obj instanceof Objects.KnowledgeTransferDocument
57121
57150
  || obj instanceof Objects.DataDefinition
57122
57151
  || obj instanceof Objects.DataElement
@@ -63590,20 +63619,51 @@ WRITE 'world'.`,
63590
63619
  ////////////////
63591
63620
  analyzeIf(file, node) {
63592
63621
  var _a;
63593
- if (node.getChildren().length !== 4) {
63622
+ const ifBody = node.findDirectStructure(Structures.Body);
63623
+ const elseIfBodies = node.findDirectStructures(Structures.ElseIf) || [];
63624
+ const elseBody = (_a = node.findDirectStructure(Structures.Else)) === null || _a === void 0 ? void 0 : _a.findDirectStructure(Structures.Body);
63625
+ if (elseBody === undefined) {
63594
63626
  return [];
63595
63627
  }
63596
- const ifBody = node.findDirectStructure(Structures.Body);
63597
- if (node.findDirectStructure(Structures.ElseIf)) {
63628
+ const ifFirst = ifBody === null || ifBody === void 0 ? void 0 : ifBody.getFirstChild();
63629
+ const elseFirst = elseBody === null || elseBody === void 0 ? void 0 : elseBody.getFirstChild();
63630
+ const ifLast = ifBody === null || ifBody === void 0 ? void 0 : ifBody.getLastChild();
63631
+ const elseLast = elseBody === null || elseBody === void 0 ? void 0 : elseBody.getLastChild();
63632
+ if (elseIfBodies.length > 0) {
63633
+ let firstMatch = true;
63634
+ let lastMatch = true;
63635
+ for (const elseif of elseIfBodies) {
63636
+ const elseifBody = elseif.findDirectStructure(Structures.Body);
63637
+ const elseifFirst = elseifBody === null || elseifBody === void 0 ? void 0 : elseifBody.getFirstChild();
63638
+ const elseifLast = elseifBody === null || elseifBody === void 0 ? void 0 : elseifBody.getLastChild();
63639
+ if (ifFirst === undefined
63640
+ || ifLast === undefined
63641
+ || elseLast === undefined
63642
+ || elseFirst === undefined) {
63643
+ return [];
63644
+ }
63645
+ if (elseifFirst === undefined
63646
+ || ifFirst.concatTokens() !== elseifFirst.concatTokens()
63647
+ || elseFirst.concatTokens() !== elseifFirst.concatTokens()) {
63648
+ firstMatch = false;
63649
+ }
63650
+ if (elseifLast === undefined
63651
+ || ifLast.concatTokens() !== elseifLast.concatTokens()
63652
+ || elseLast.concatTokens() !== elseifLast.concatTokens()) {
63653
+ lastMatch = false;
63654
+ }
63655
+ }
63656
+ if (firstMatch === true || lastMatch === true) {
63657
+ const message = "Identical contents";
63658
+ const issue = issue_1.Issue.atToken(file, node.getFirstToken(), message, this.getMetadata().key, this.conf.severity);
63659
+ return [issue];
63660
+ }
63598
63661
  return [];
63599
63662
  }
63600
- const elseBody = (_a = node.findDirectStructure(Structures.Else)) === null || _a === void 0 ? void 0 : _a.findDirectStructure(Structures.Body);
63601
- if (elseBody === undefined || ifBody === undefined) {
63663
+ else if (elseBody === undefined || ifBody === undefined) {
63602
63664
  return [];
63603
63665
  }
63604
63666
  {
63605
- const ifFirst = ifBody.getFirstChild();
63606
- const elseFirst = elseBody.getFirstChild();
63607
63667
  if (ifFirst === undefined || elseFirst === undefined || this.isChained(ifFirst)) {
63608
63668
  return [];
63609
63669
  }
@@ -63614,8 +63674,6 @@ WRITE 'world'.`,
63614
63674
  }
63615
63675
  }
63616
63676
  {
63617
- const ifLast = ifBody.getLastChild();
63618
- const elseLast = elseBody.getLastChild();
63619
63677
  if (ifLast === undefined || elseLast === undefined || this.isChained(ifLast)) {
63620
63678
  return [];
63621
63679
  }
@@ -64044,7 +64102,15 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
64044
64102
  const issue = issue_1.Issue.atIdentifier(found, "Do not implement abstract method \"" + md.name + "\"", this.getMetadata().key, this.conf.severity);
64045
64103
  ret.push(issue);
64046
64104
  }
64047
- continue;
64105
+ if (def.isAbstract) {
64106
+ continue;
64107
+ }
64108
+ else {
64109
+ const message = "Abstract methods can only be defined in abstract classes, " + md.name;
64110
+ const issue = issue_1.Issue.atIdentifier(md.identifier, message, this.getMetadata().key, this.conf.severity);
64111
+ ret.push(issue);
64112
+ break;
64113
+ }
64048
64114
  }
64049
64115
  if (impl === undefined) {
64050
64116
  const message = "Class implementation for \"" + def.name + "\" not found";
@@ -64148,7 +64214,18 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
64148
64214
  }
64149
64215
  for (const m of this.findInterfaceMethods(idef)) {
64150
64216
  if (this.isAbstract(m, interfaceInfo, def)) {
64151
- continue;
64217
+ if (def.isAbstract) {
64218
+ continue;
64219
+ }
64220
+ else {
64221
+ // there is some bug here, which I cannot reproduce right now
64222
+ /*
64223
+ const message = "Abstract methods can only be defined in abstract classes, " + m.method.name;
64224
+ const issue = Issue.atIdentifier(m.method.identifier, message, this.getMetadata().key, this.conf.severity);
64225
+ ret.push(issue);
64226
+ break;
64227
+ */
64228
+ }
64152
64229
  }
64153
64230
  if (this.isImplemented(m, def, impl) === false) {
64154
64231
  const message = "Implement method \"" + m.method.name + "\" from interface \"" + m.objectName + "\"";
@@ -69563,6 +69640,7 @@ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@ab
69563
69640
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
69564
69641
  const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
69565
69642
  const version_1 = __webpack_require__(/*! ../version */ "./node_modules/@abaplint/core/build/src/version.js");
69643
+ const __1 = __webpack_require__(/*! .. */ "./node_modules/@abaplint/core/build/src/index.js");
69566
69644
  class Parser702ChainingConf extends _basic_rule_config_1.BasicRuleConfig {
69567
69645
  }
69568
69646
  exports.Parser702ChainingConf = Parser702ChainingConf;
@@ -69574,7 +69652,7 @@ class Parser702Chaining extends _abap_rule_1.ABAPRule {
69574
69652
  getMetadata() {
69575
69653
  return {
69576
69654
  key: "parser_702_chaining",
69577
- title: "Parser Error, bad chanining on 702",
69655
+ title: "Parser Error, bad chaining on 702",
69578
69656
  shortDescription: `ABAP on 702 does not allow for method chaining with IMPORTING/EXPORTING/CHANGING keywords,
69579
69657
  this rule finds these and reports errors.
69580
69658
  Only active on target version 702 and below.`,
@@ -69615,13 +69693,47 @@ Only active on target version 702 and below.`,
69615
69693
  || param.findDirectTokenByText("CHANGING")
69616
69694
  || param.findDirectTokenByText("EXCEPTIONS")) {
69617
69695
  const message = "This kind of method chaining not possible in 702";
69618
- const issue = issue_1.Issue.atPosition(file, param.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity);
69619
- issues.push(issue);
69696
+ this.pushIssue(message, file, param, issues);
69620
69697
  }
69621
69698
  }
69622
69699
  }
69700
+ // after a value assignment (move statement whose source is a method call, or method parameter assignment),
69701
+ // there can't be any EXPORTING/IMPORTING/CHANGING/EXCEPTIONS
69702
+ for (const statement of file.getStatements()) {
69703
+ if (!(statement.get() instanceof __1.Statements.Move)) {
69704
+ continue;
69705
+ }
69706
+ const source = statement.findDirectExpression(Expressions.Source);
69707
+ if (source === undefined) {
69708
+ continue;
69709
+ }
69710
+ this.ensureSourceHasNoProceduralKeywords(source, file, issues);
69711
+ }
69712
+ for (const methodParameters of stru.findAllExpressions(Expressions.MethodParameters)) {
69713
+ for (const params of methodParameters.findAllExpressions(Expressions.ParameterS)) {
69714
+ const source = params.findDirectExpression(Expressions.Source);
69715
+ if (source === undefined) {
69716
+ continue;
69717
+ }
69718
+ this.ensureSourceHasNoProceduralKeywords(source, file, issues);
69719
+ }
69720
+ }
69623
69721
  return issues;
69624
69722
  }
69723
+ ensureSourceHasNoProceduralKeywords(source, file, issues) {
69724
+ const forbiddenTokens = ["EXPORTING", "IMPORTING", "CHANGING", "EXCEPTIONS"];
69725
+ for (const param of source.findAllExpressions(Expressions.MethodParameters)) {
69726
+ const usedForbiddenToken = forbiddenTokens.find(text => param.findDirectTokenByText(text));
69727
+ if (usedForbiddenToken) {
69728
+ const message = `Unexpected word ${usedForbiddenToken} in functional method call`;
69729
+ this.pushIssue(message, file, param, issues);
69730
+ }
69731
+ }
69732
+ }
69733
+ pushIssue(message, file, node, issues) {
69734
+ const issue = issue_1.Issue.atPosition(file, node.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity);
69735
+ issues.push(issue);
69736
+ }
69625
69737
  }
69626
69738
  exports.Parser702Chaining = Parser702Chaining;
69627
69739
  //# sourceMappingURL=parser_702_chaining.js.map
@@ -83001,9 +83113,13 @@ import "./_top.mjs";\n`;
83001
83113
  import runtime from "@abaplint/runtime";
83002
83114
  globalThis.abap = new runtime.ABAP();\n`;
83003
83115
  }
83004
- ret += `${this.buildImports(reg, useImport, options)}
83005
-
83006
- export async function initializeABAP() {\n`;
83116
+ if (options?.setup?.filename === undefined || options?.setup?.filename === "") {
83117
+ ret += `// no setup logic specified in config\n`;
83118
+ }
83119
+ else {
83120
+ ret += `const setup = await import("${options?.setup?.filename}");\n`;
83121
+ }
83122
+ ret += `export async function initializeABAP() {\n`;
83007
83123
  ret += ` const sqlite = [];\n`;
83008
83124
  for (const i of dbSetup.schemas.sqlite) {
83009
83125
  ret += ` sqlite.push(\`${i}\`);\n`;
@@ -83024,14 +83140,15 @@ export async function initializeABAP() {\n`;
83024
83140
  ret += ` insert.push(\`${i}\`);\n`;
83025
83141
  }
83026
83142
  ret += `\n`;
83027
- if (options?.extraSetup === undefined || options?.extraSetup === "") {
83028
- ret += `// no setup logic specified in config\n`;
83143
+ if (options?.setup?.preFunction !== undefined) {
83144
+ ret += ` await setup.${options?.setup?.preFunction}(globalThis.abap, schemas, insert);\n`;
83029
83145
  }
83030
- else {
83031
- ret += ` const {setup} = await import("${options?.extraSetup}");\n` +
83032
- ` await setup(globalThis.abap, schemas, insert);\n`;
83146
+ ret += `}\n\n`;
83147
+ ret += `await initializeABAP();\n\n`;
83148
+ ret += `${this.buildImports(reg, useImport, options)}`;
83149
+ if (options?.setup?.postFunction !== undefined) {
83150
+ ret += `\n\nawait setup.${options?.setup?.postFunction}(globalThis.abap, schemas, insert);\n`;
83033
83151
  }
83034
- ret += `}`;
83035
83152
  return ret;
83036
83153
  }
83037
83154
  buildImports(reg, useImport, options) {
@@ -92026,12 +92143,11 @@ class UnitTest {
92026
92143
  import fs from "fs";
92027
92144
  import path from "path";
92028
92145
  import {fileURLToPath} from "url";
92029
- import {initializeABAP} from "./init.mjs";
92146
+ import "./init.mjs";
92030
92147
 
92031
92148
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
92032
92149
 
92033
92150
  async function run() {
92034
- await initializeABAP();
92035
92151
  let lt_input = new abap.types.Table(new abap.types.Structure({class_name: new abap.types.Character(30), testclass_name: new abap.types.Character(30), method_name: new abap.types.Character(30)}), {"withHeader":false,"type":"STANDARD","isUnique":false,"keyFields":[]});
92036
92152
  let ls_input = new abap.types.Structure({class_name: new abap.types.Character(30), testclass_name: new abap.types.Character(30), method_name: new abap.types.Character(30)});
92037
92153
  let ls_result = new abap.types.Structure({list: new abap.types.Table(new abap.types.Structure({class_name: new abap.types.Character(30), testclass_name: new abap.types.Character(30), method_name: new abap.types.Character(30), expected: new abap.types.String(), actual: new abap.types.String(), status: new abap.types.String(), runtime: new abap.types.Integer(), message: new abap.types.String(), js_location: new abap.types.String(), console: new abap.types.String()}), {"withHeader":false,"type":"STANDARD","isUnique":false,"keyFields":[]}), json: new abap.types.String()});
@@ -92170,7 +92286,7 @@ run().then(() => {
92170
92286
  };
92171
92287
  let ret = `/* eslint-disable curly */
92172
92288
  /* eslint-disable max-len */
92173
- import {initializeABAP} from "./init.mjs";
92289
+ import "./init.mjs";
92174
92290
 
92175
92291
  function getData() {
92176
92292
  const ret = [];\n`;
@@ -92197,7 +92313,6 @@ function getData() {
92197
92313
  async function run() {
92198
92314
  const skipCritical = process.argv[2] === "--skip-critical";
92199
92315
  const onlyCritical = process.argv[2] === "--only-critical";
92200
- await initializeABAP();
92201
92316
  for (const st of getData()) {
92202
92317
  const imported = await import(st.filename);
92203
92318
  const localClass = imported[st.localClass];
@@ -103327,9 +103442,6 @@ class Progress {
103327
103442
  }
103328
103443
  async function loadLib(config) {
103329
103444
  const files = [];
103330
- if (config.lib && config.lib !== "" && config.libs === undefined) {
103331
- config.libs = [{ url: config.lib }];
103332
- }
103333
103445
  for (const l of config.libs || []) {
103334
103446
  let dir = "";
103335
103447
  let cleanupFolder = false;
package/build/types.d.ts CHANGED
@@ -6,10 +6,6 @@ export interface ITranspilerConfig {
6
6
  /** list of regex, case insensitive */
7
7
  exclude_filter?: string[];
8
8
  output_folder: string;
9
- /** to be deprecated, "lib", use "libs" instead
10
- * @deprecated
11
- */
12
- lib?: string;
13
9
  libs?: {
14
10
  url?: string;
15
11
  folder?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.11.96",
3
+ "version": "2.12.0",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -27,10 +27,10 @@
27
27
  "author": "abaplint",
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@abaplint/core": "^2.113.218",
31
- "@abaplint/transpiler": "^2.11.96",
30
+ "@abaplint/core": "^2.113.222",
31
+ "@abaplint/transpiler": "^2.12.0",
32
32
  "@types/glob": "^8.1.0",
33
- "@types/node": "^24.6.1",
33
+ "@types/node": "^24.6.2",
34
34
  "@types/progress": "^2.0.7",
35
35
  "glob": "=7.2.0",
36
36
  "progress": "^2.0.3",