@abaplint/transpiler-cli 2.11.95 → 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);
@@ -22736,7 +22742,7 @@ class TypeUtils {
22736
22742
  if (!(sourceRowType instanceof basic_1.StructureType)) {
22737
22743
  return false;
22738
22744
  }
22739
- else if (!(this.structureContainsString(sourceRowType))
22745
+ else if (!this.structureContainsString(sourceRowType)
22740
22746
  && this.structureContainsVoid(sourceRowType) === false) {
22741
22747
  return false;
22742
22748
  }
@@ -22746,7 +22752,7 @@ class TypeUtils {
22746
22752
  if (!(targetRowType instanceof basic_1.StructureType)) {
22747
22753
  return false;
22748
22754
  }
22749
- else if (!(this.structureContainsString(targetRowType))
22755
+ else if (!this.structureContainsString(targetRowType)
22750
22756
  && this.structureContainsVoid(targetRowType) === false) {
22751
22757
  return false;
22752
22758
  }
@@ -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`);
@@ -24544,7 +24550,7 @@ class CorrespondingBody {
24544
24550
  }
24545
24551
  const base = (_a = node.findDirectExpression(Expressions.CorrespondingBodyBase)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Source);
24546
24552
  if (base) {
24547
- source_1.Source.runSyntax(base, input);
24553
+ source_1.Source.runSyntax(base, input, targetType);
24548
24554
  }
24549
24555
  let type = undefined;
24550
24556
  for (const s of node.findDirectExpressions(Expressions.Source)) {
@@ -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.217";
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
@@ -59488,7 +59517,6 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
59488
59517
  const source = high.findExpressionAfterToken("MESSAGE");
59489
59518
  if ((source === null || source === void 0 ? void 0 : source.get()) instanceof Expressions.MessageSourceSource
59490
59519
  && ((_a = source.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Source) {
59491
- ;
59492
59520
  const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
59493
59521
  const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
59494
59522
  const firstToken = high.getFirstToken();
@@ -62920,7 +62948,7 @@ class FullyTypeConstants extends _abap_rule_1.ABAPRule {
62920
62948
  for (const stat of file.getStatements()) {
62921
62949
  if ((stat.get() instanceof Statements.Constant
62922
62950
  || (this.conf.checkData === true && stat.get() instanceof Statements.Data))
62923
- && (!this.isTyped(stat))) {
62951
+ && !this.isTyped(stat)) {
62924
62952
  const type = stat.get() instanceof Statements.Constant ? "constant definition" : "data definition";
62925
62953
  let token = (_a = stat.findFirstExpression(expressions_1.NamespaceSimpleName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
62926
62954
  if (token === undefined) {
@@ -62935,7 +62963,7 @@ class FullyTypeConstants extends _abap_rule_1.ABAPRule {
62935
62963
  return issues;
62936
62964
  }
62937
62965
  isTyped(stat) {
62938
- return (stat.findFirstExpression(expressions_1.Type) || stat.findFirstExpression(expressions_1.TypeTable));
62966
+ return stat.findFirstExpression(expressions_1.Type) || stat.findFirstExpression(expressions_1.TypeTable);
62939
62967
  }
62940
62968
  }
62941
62969
  exports.FullyTypeConstants = FullyTypeConstants;
@@ -63591,20 +63619,51 @@ WRITE 'world'.`,
63591
63619
  ////////////////
63592
63620
  analyzeIf(file, node) {
63593
63621
  var _a;
63594
- 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) {
63595
63626
  return [];
63596
63627
  }
63597
- const ifBody = node.findDirectStructure(Structures.Body);
63598
- 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
+ }
63599
63661
  return [];
63600
63662
  }
63601
- const elseBody = (_a = node.findDirectStructure(Structures.Else)) === null || _a === void 0 ? void 0 : _a.findDirectStructure(Structures.Body);
63602
- if (elseBody === undefined || ifBody === undefined) {
63663
+ else if (elseBody === undefined || ifBody === undefined) {
63603
63664
  return [];
63604
63665
  }
63605
63666
  {
63606
- const ifFirst = ifBody.getFirstChild();
63607
- const elseFirst = elseBody.getFirstChild();
63608
63667
  if (ifFirst === undefined || elseFirst === undefined || this.isChained(ifFirst)) {
63609
63668
  return [];
63610
63669
  }
@@ -63615,8 +63674,6 @@ WRITE 'world'.`,
63615
63674
  }
63616
63675
  }
63617
63676
  {
63618
- const ifLast = ifBody.getLastChild();
63619
- const elseLast = elseBody.getLastChild();
63620
63677
  if (ifLast === undefined || elseLast === undefined || this.isChained(ifLast)) {
63621
63678
  return [];
63622
63679
  }
@@ -64045,7 +64102,15 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
64045
64102
  const issue = issue_1.Issue.atIdentifier(found, "Do not implement abstract method \"" + md.name + "\"", this.getMetadata().key, this.conf.severity);
64046
64103
  ret.push(issue);
64047
64104
  }
64048
- 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
+ }
64049
64114
  }
64050
64115
  if (impl === undefined) {
64051
64116
  const message = "Class implementation for \"" + def.name + "\" not found";
@@ -64148,8 +64213,19 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
64148
64213
  return [idef];
64149
64214
  }
64150
64215
  for (const m of this.findInterfaceMethods(idef)) {
64151
- if (interfaceInfo.abstractMethods.includes(m.method.name.toUpperCase())) {
64152
- continue;
64216
+ if (this.isAbstract(m, interfaceInfo, def)) {
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
+ }
64153
64229
  }
64154
64230
  if (this.isImplemented(m, def, impl) === false) {
64155
64231
  const message = "Implement method \"" + m.method.name + "\" from interface \"" + m.objectName + "\"";
@@ -64167,6 +64243,23 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
64167
64243
  }
64168
64244
  return ret;
64169
64245
  }
64246
+ isAbstract(m, interfaceInfo, def) {
64247
+ if (interfaceInfo.abstractMethods.includes(m.method.name.toUpperCase())) {
64248
+ return true;
64249
+ }
64250
+ if (!def.superClassName) {
64251
+ return false;
64252
+ }
64253
+ // look up in superclass if method is abstract there
64254
+ const superClass = this.findClass(def.superClassName);
64255
+ const superInterface = superClass === null || superClass === void 0 ? void 0 : superClass.def.interfaces.find(iface => iface.name.toUpperCase() === m.objectName.toUpperCase());
64256
+ if (superClass && superInterface) {
64257
+ return this.isAbstract(m, superInterface, superClass.def);
64258
+ }
64259
+ else {
64260
+ return false;
64261
+ }
64262
+ }
64170
64263
  isImplemented(m, def, impl) {
64171
64264
  if (impl === undefined) {
64172
64265
  return false;
@@ -69547,6 +69640,7 @@ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@ab
69547
69640
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
69548
69641
  const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
69549
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");
69550
69644
  class Parser702ChainingConf extends _basic_rule_config_1.BasicRuleConfig {
69551
69645
  }
69552
69646
  exports.Parser702ChainingConf = Parser702ChainingConf;
@@ -69558,7 +69652,7 @@ class Parser702Chaining extends _abap_rule_1.ABAPRule {
69558
69652
  getMetadata() {
69559
69653
  return {
69560
69654
  key: "parser_702_chaining",
69561
- title: "Parser Error, bad chanining on 702",
69655
+ title: "Parser Error, bad chaining on 702",
69562
69656
  shortDescription: `ABAP on 702 does not allow for method chaining with IMPORTING/EXPORTING/CHANGING keywords,
69563
69657
  this rule finds these and reports errors.
69564
69658
  Only active on target version 702 and below.`,
@@ -69599,13 +69693,47 @@ Only active on target version 702 and below.`,
69599
69693
  || param.findDirectTokenByText("CHANGING")
69600
69694
  || param.findDirectTokenByText("EXCEPTIONS")) {
69601
69695
  const message = "This kind of method chaining not possible in 702";
69602
- const issue = issue_1.Issue.atPosition(file, param.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity);
69603
- issues.push(issue);
69696
+ this.pushIssue(message, file, param, issues);
69697
+ }
69698
+ }
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;
69604
69717
  }
69718
+ this.ensureSourceHasNoProceduralKeywords(source, file, issues);
69605
69719
  }
69606
69720
  }
69607
69721
  return issues;
69608
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
+ }
69609
69737
  }
69610
69738
  exports.Parser702Chaining = Parser702Chaining;
69611
69739
  //# sourceMappingURL=parser_702_chaining.js.map
@@ -74529,9 +74657,9 @@ ENDFORM.`,
74529
74657
  for (let i = 0; i < statements.length; i++) {
74530
74658
  const node = statements[i];
74531
74659
  const nodeType = node.get();
74532
- if ((nodeType instanceof Statements.MethodImplementation
74660
+ if (nodeType instanceof Statements.MethodImplementation
74533
74661
  || nodeType instanceof Statements.Form
74534
- || nodeType instanceof Statements.FunctionModule)) {
74662
+ || nodeType instanceof Statements.FunctionModule) {
74535
74663
  statementCounter = 0;
74536
74664
  continue;
74537
74665
  }
@@ -77653,8 +77781,8 @@ class PopulateTables {
77653
77781
  if (!this.hasT000) {
77654
77782
  return "";
77655
77783
  }
77656
- // todo, this should take the client number from the settings
77657
- return `INSERT INTO t000 ('mandt', 'cccategory', 'ccnocliind') VALUES ('123', '', '');`;
77784
+ // todo, this should take the client number from the json abap_transpile.json settings
77785
+ return `INSERT INTO t000 ("mandt", "cccategory", "ccnocliind") VALUES ('123', '', '');`;
77658
77786
  }
77659
77787
  escape(value) {
77660
77788
  let ret = value.replace(/\'/g, "''");
@@ -82985,9 +83113,13 @@ import "./_top.mjs";\n`;
82985
83113
  import runtime from "@abaplint/runtime";
82986
83114
  globalThis.abap = new runtime.ABAP();\n`;
82987
83115
  }
82988
- ret += `${this.buildImports(reg, useImport, options)}
82989
-
82990
- 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`;
82991
83123
  ret += ` const sqlite = [];\n`;
82992
83124
  for (const i of dbSetup.schemas.sqlite) {
82993
83125
  ret += ` sqlite.push(\`${i}\`);\n`;
@@ -83008,14 +83140,15 @@ export async function initializeABAP() {\n`;
83008
83140
  ret += ` insert.push(\`${i}\`);\n`;
83009
83141
  }
83010
83142
  ret += `\n`;
83011
- if (options?.extraSetup === undefined || options?.extraSetup === "") {
83012
- 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`;
83013
83145
  }
83014
- else {
83015
- ret += ` const {setup} = await import("${options?.extraSetup}");\n` +
83016
- ` 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`;
83017
83151
  }
83018
- ret += `}`;
83019
83152
  return ret;
83020
83153
  }
83021
83154
  buildImports(reg, useImport, options) {
@@ -92010,12 +92143,11 @@ class UnitTest {
92010
92143
  import fs from "fs";
92011
92144
  import path from "path";
92012
92145
  import {fileURLToPath} from "url";
92013
- import {initializeABAP} from "./init.mjs";
92146
+ import "./init.mjs";
92014
92147
 
92015
92148
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
92016
92149
 
92017
92150
  async function run() {
92018
- await initializeABAP();
92019
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":[]});
92020
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)});
92021
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()});
@@ -92154,7 +92286,7 @@ run().then(() => {
92154
92286
  };
92155
92287
  let ret = `/* eslint-disable curly */
92156
92288
  /* eslint-disable max-len */
92157
- import {initializeABAP} from "./init.mjs";
92289
+ import "./init.mjs";
92158
92290
 
92159
92291
  function getData() {
92160
92292
  const ret = [];\n`;
@@ -92181,7 +92313,6 @@ function getData() {
92181
92313
  async function run() {
92182
92314
  const skipCritical = process.argv[2] === "--skip-critical";
92183
92315
  const onlyCritical = process.argv[2] === "--only-critical";
92184
- await initializeABAP();
92185
92316
  for (const st of getData()) {
92186
92317
  const imported = await import(st.filename);
92187
92318
  const localClass = imported[st.localClass];
@@ -103311,9 +103442,6 @@ class Progress {
103311
103442
  }
103312
103443
  async function loadLib(config) {
103313
103444
  const files = [];
103314
- if (config.lib && config.lib !== "" && config.libs === undefined) {
103315
- config.libs = [{ url: config.lib }];
103316
- }
103317
103445
  for (const l of config.libs || []) {
103318
103446
  let dir = "";
103319
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.95",
3
+ "version": "2.12.0",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -27,17 +27,17 @@
27
27
  "author": "abaplint",
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@abaplint/core": "^2.113.217",
31
- "@abaplint/transpiler": "^2.11.95",
30
+ "@abaplint/core": "^2.113.222",
31
+ "@abaplint/transpiler": "^2.12.0",
32
32
  "@types/glob": "^8.1.0",
33
- "@types/node": "^24.5.2",
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",
37
37
  "ts-json-schema-generator": "^2.4.0",
38
- "typescript": "^5.9.2",
38
+ "typescript": "^5.9.3",
39
39
  "p-limit": "^3.1.0",
40
40
  "webpack-cli": "^6.0.1",
41
- "webpack": "^5.101.3"
41
+ "webpack": "^5.102.0"
42
42
  }
43
43
  }