@abaplint/transpiler-cli 2.5.71 → 2.5.73

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 +257 -72
  2. package/package.json +3 -3
package/build/bundle.js CHANGED
@@ -18583,7 +18583,7 @@ BuiltIn.methods = [
18583
18583
  {
18584
18584
  name: "CONCAT_LINES_OF",
18585
18585
  mandatory: {
18586
- "table": new basic_1.TableType(new basic_1.AnyType(), { withHeader: false }),
18586
+ "table": new basic_1.TableType(new basic_1.AnyType(), { withHeader: false, keyType: basic_1.TableKeyType.default }),
18587
18587
  },
18588
18588
  optional: {
18589
18589
  "sep": new basic_1.StringType(),
@@ -18879,7 +18879,7 @@ BuiltIn.methods = [
18879
18879
  {
18880
18880
  name: "LINES",
18881
18881
  mandatory: {
18882
- "val": new basic_1.TableType(new basic_1.AnyType(), { withHeader: false }),
18882
+ "val": new basic_1.TableType(new basic_1.AnyType(), { withHeader: false, keyType: basic_1.TableKeyType.default }),
18883
18883
  },
18884
18884
  return: new basic_1.IntegerType(),
18885
18885
  },
@@ -20099,10 +20099,10 @@ class Procedural {
20099
20099
  }
20100
20100
  if (param.direction === types_1.FunctionModuleParameterDirection.tables) {
20101
20101
  if (found instanceof basic_1.TableType) {
20102
- found = new basic_1.TableType(found.getRowType(), { withHeader: true });
20102
+ found = new basic_1.TableType(found.getRowType(), { withHeader: true, keyType: basic_1.TableKeyType.default });
20103
20103
  }
20104
20104
  else {
20105
- found = new basic_1.TableType(found, { withHeader: true });
20105
+ found = new basic_1.TableType(found, { withHeader: true, keyType: basic_1.TableKeyType.default });
20106
20106
  }
20107
20107
  }
20108
20108
  if ((found instanceof basic_1.UnknownType || found instanceof basic_1.VoidType) && ((_a = param.type) === null || _a === void 0 ? void 0 : _a.includes("-"))) {
@@ -20659,7 +20659,7 @@ class BasicTypes {
20659
20659
  }
20660
20660
  else if (child.concatTokens() === "[]") {
20661
20661
  if (type instanceof Types.TableType) {
20662
- type = new basic_1.TableType(type.getRowType(), { withHeader: false });
20662
+ type = new basic_1.TableType(type.getRowType(), { withHeader: false, keyType: Types.TableKeyType.default });
20663
20663
  }
20664
20664
  }
20665
20665
  else { // field name
@@ -20792,13 +20792,18 @@ class BasicTypes {
20792
20792
  return undefined;
20793
20793
  }
20794
20794
  let type = undefined;
20795
- if (text.startsWith("TYPE STANDARD TABLE ") || text.startsWith("LIKE STANDARD TABLE ")) {
20795
+ if (text.startsWith("TYPE STANDARD TABLE ")
20796
+ || text.startsWith("TYPE TABLE ")
20797
+ || text.startsWith("LIKE TABLE ")
20798
+ || text.startsWith("LIKE STANDARD TABLE ")) {
20796
20799
  type = basic_1.TableAccessType.standard;
20797
20800
  }
20798
- else if (text.startsWith("TYPE SORTED TABLE ") || text.startsWith("LIKE SORTED TABLE ")) {
20801
+ else if (text.startsWith("TYPE SORTED TABLE ")
20802
+ || text.startsWith("LIKE SORTED TABLE ")) {
20799
20803
  type = basic_1.TableAccessType.sorted;
20800
20804
  }
20801
- else if (text.startsWith("TYPE HASHED TABLE ") || text.startsWith("LIKE HASHED TABLE ")) {
20805
+ else if (text.startsWith("TYPE HASHED TABLE ")
20806
+ || text.startsWith("LIKE HASHED TABLE ")) {
20802
20807
  type = basic_1.TableAccessType.hashed;
20803
20808
  }
20804
20809
  const typeTableKeys = node.findAllExpressions(expressions_1.TypeTableKey);
@@ -20806,7 +20811,7 @@ class BasicTypes {
20806
20811
  const isNamed = (firstKey === null || firstKey === void 0 ? void 0 : firstKey.findDirectExpression(expressions_1.Field)) !== undefined;
20807
20812
  const primaryKey = {
20808
20813
  name: "primary_key",
20809
- type: type,
20814
+ type: type || basic_1.TableAccessType.standard,
20810
20815
  isUnique: isNamed ? false : (firstKey === null || firstKey === void 0 ? void 0 : firstKey.concatTokens().toUpperCase().includes("WITH UNIQUE ")) === true,
20811
20816
  keyFields: [],
20812
20817
  };
@@ -20837,8 +20842,16 @@ class BasicTypes {
20837
20842
  }
20838
20843
  secondaryKeys.push(secondary);
20839
20844
  }
20845
+ let keyType = Types.TableKeyType.user;
20846
+ if (text.includes(" EMPTY KEY")) {
20847
+ keyType = Types.TableKeyType.empty;
20848
+ }
20849
+ else if (text.includes(" DEFAULT KEY")) {
20850
+ keyType = Types.TableKeyType.default;
20851
+ }
20840
20852
  const options = {
20841
20853
  withHeader: text.includes(" WITH HEADER LINE"),
20854
+ keyType: keyType,
20842
20855
  primaryKey: primaryKey,
20843
20856
  secondary: secondaryKeys,
20844
20857
  };
@@ -20889,6 +20902,7 @@ class BasicTypes {
20889
20902
  { name: "low", type: found },
20890
20903
  { name: "high", type: found },
20891
20904
  ]);
20905
+ options.primaryKey.type = basic_1.TableAccessType.standard;
20892
20906
  return new Types.TableType(structure, options, name);
20893
20907
  }
20894
20908
  else if (text.startsWith("LIKE RANGE OF ")) {
@@ -20903,6 +20917,7 @@ class BasicTypes {
20903
20917
  { name: "low", type: found },
20904
20918
  { name: "high", type: found },
20905
20919
  ], name);
20920
+ options.primaryKey.type = basic_1.TableAccessType.standard;
20906
20921
  return new Types.TableType(structure, options);
20907
20922
  }
20908
20923
  else if (typename && (text.startsWith("TYPE TABLE FOR CREATE ")
@@ -20983,7 +20998,7 @@ class BasicTypes {
20983
20998
  || text === "TYPE HASHED TABLE"
20984
20999
  || text === "TYPE INDEX TABLE"
20985
21000
  || text === "TYPE ANY TABLE") {
20986
- return new Types.TableType(new Types.AnyType(), { withHeader: node.concatTokens().toUpperCase().includes("WITH HEADER LINE") });
21001
+ return new Types.TableType(new Types.AnyType(), { withHeader: node.concatTokens().toUpperCase().includes("WITH HEADER LINE"), keyType: Types.TableKeyType.default });
20987
21002
  }
20988
21003
  else if (text.startsWith("LIKE ")) {
20989
21004
  let sub = node.findFirstExpression(Expressions.Type);
@@ -21001,7 +21016,7 @@ class BasicTypes {
21001
21016
  }
21002
21017
  found = this.resolveLikeName(sub);
21003
21018
  if (found && this.isOccurs(node)) {
21004
- found = new Types.TableType(found, { withHeader: text.includes("WITH HEADER LINE") }, qualifiedName);
21019
+ found = new Types.TableType(found, { withHeader: text.includes("WITH HEADER LINE"), keyType: Types.TableKeyType.default }, qualifiedName);
21005
21020
  }
21006
21021
  }
21007
21022
  else if (text.startsWith("TYPE LINE OF ")) {
@@ -21030,17 +21045,17 @@ class BasicTypes {
21030
21045
  found = this.resolveTypeName(typeName, this.findLength(node), this.findDecimals(node), qualifiedName);
21031
21046
  const concat = node.concatTokens().toUpperCase();
21032
21047
  if (found && this.isOccurs(node)) {
21033
- found = new Types.TableType(found, { withHeader: concat.includes(" WITH HEADER LINE") }, qualifiedName);
21048
+ found = new Types.TableType(found, { withHeader: concat.includes(" WITH HEADER LINE"), keyType: Types.TableKeyType.default }, qualifiedName);
21034
21049
  }
21035
21050
  else if (found && concat.includes(" WITH HEADER LINE")) {
21036
21051
  if (found instanceof Types.VoidType) {
21037
- found = new Types.TableType(found, { withHeader: true });
21052
+ found = new Types.TableType(found, { withHeader: true, keyType: Types.TableKeyType.default });
21038
21053
  }
21039
21054
  else if (!(found instanceof Types.TableType)) {
21040
21055
  throw new Error("WITH HEADER LINE can only be used with internal table");
21041
21056
  }
21042
21057
  else {
21043
- found = new Types.TableType(found.getRowType(), { withHeader: true });
21058
+ found = new Types.TableType(found.getRowType(), { withHeader: true, keyType: Types.TableKeyType.default });
21044
21059
  }
21045
21060
  }
21046
21061
  if (found === undefined && typeName === undefined) {
@@ -21054,7 +21069,7 @@ class BasicTypes {
21054
21069
  }
21055
21070
  found = new Types.CharacterType(length, { qualifiedName: qualifiedName }); // fallback
21056
21071
  if (this.isOccurs(node)) {
21057
- found = new Types.TableType(found, { withHeader: concat.includes(" WITH HEADER LINE") }, qualifiedName);
21072
+ found = new Types.TableType(found, { withHeader: concat.includes(" WITH HEADER LINE"), keyType: Types.TableKeyType.default }, qualifiedName);
21058
21073
  }
21059
21074
  }
21060
21075
  }
@@ -23235,8 +23250,10 @@ class MethodDefReturning {
23235
23250
  if (type === undefined) {
23236
23251
  throw new Error("method_parameter.ts, unexpected structure");
23237
23252
  }
23238
- const found = new basic_types_1.BasicTypes(filename, scope).parseType(type);
23239
- // console.dir(found);
23253
+ let found = new basic_types_1.BasicTypes(filename, scope).parseType(type);
23254
+ if ((found === null || found === void 0 ? void 0 : found.isGeneric()) === true) {
23255
+ found = new basic_1.UnknownType("RETURNING parameter must be fully specified");
23256
+ }
23240
23257
  if (found) {
23241
23258
  return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), filename, found, meta);
23242
23259
  }
@@ -26225,7 +26242,7 @@ class Controls {
26225
26242
  { name: "LINE_SELECTOR", type: new basic_1.CharacterType(1) },
26226
26243
  { name: "H_GRID", type: new basic_1.CharacterType(1) },
26227
26244
  { name: "V_GRID", type: new basic_1.CharacterType(1) },
26228
- { name: "COLS", type: new basic_1.TableType(cols, { withHeader: false }) },
26245
+ { name: "COLS", type: new basic_1.TableType(cols, { withHeader: false, keyType: basic_1.TableKeyType.default }) },
26229
26246
  { name: "INVISIBLE", type: new basic_1.CharacterType(1) },
26230
26247
  ]);
26231
26248
  const id = new _typed_identifier_1.TypedIdentifier(token, filename, type);
@@ -26460,7 +26477,12 @@ class Data {
26460
26477
  runSyntax(node, scope, filename) {
26461
26478
  const dd = node.findFirstExpression(Expressions.DataDefinition);
26462
26479
  if (dd) {
26463
- return new data_definition_1.DataDefinition().runSyntax(dd, scope, filename);
26480
+ const id = new data_definition_1.DataDefinition().runSyntax(dd, scope, filename);
26481
+ if ((id === null || id === void 0 ? void 0 : id.getType().isGeneric()) === true
26482
+ && (id === null || id === void 0 ? void 0 : id.getType().containsVoid()) === false) {
26483
+ throw new Error("DATA definition cannot be generic");
26484
+ }
26485
+ return id;
26464
26486
  }
26465
26487
  const name = node.findFirstExpression(Expressions.DefinitionName);
26466
26488
  if (name) {
@@ -26867,13 +26889,13 @@ class Find {
26867
26889
  { name: "LINE", type: new basic_1.IntegerType() },
26868
26890
  { name: "OFFSET", type: new basic_1.IntegerType() },
26869
26891
  { name: "LENGTH", type: new basic_1.IntegerType() },
26870
- { name: "SUBMATCHES", type: new basic_1.TableType(sub, { withHeader: false }) },
26892
+ { name: "SUBMATCHES", type: new basic_1.TableType(sub, { withHeader: false, keyType: basic_1.TableKeyType.default }) },
26871
26893
  ], "MATCH_RESULT", "MATCH_RESULT");
26872
26894
  if (node.concatTokens().toUpperCase().startsWith("FIND FIRST")) {
26873
26895
  this.inline(rfound, scope, filename, type);
26874
26896
  }
26875
26897
  else {
26876
- this.inline(rfound, scope, filename, new basic_1.TableType(type, { withHeader: false }, "MATCH_RESULT_TAB"));
26898
+ this.inline(rfound, scope, filename, new basic_1.TableType(type, { withHeader: false, keyType: basic_1.TableKeyType.default }, "MATCH_RESULT_TAB"));
26877
26899
  }
26878
26900
  }
26879
26901
  const ofound = node.findExpressionsAfterToken("OFFSET");
@@ -28403,7 +28425,7 @@ class Ranges {
28403
28425
  { name: "low", type: found },
28404
28426
  { name: "high", type: found },
28405
28427
  ]);
28406
- const type = new basic_1.TableType(structure, { withHeader: true });
28428
+ const type = new basic_1.TableType(structure, { withHeader: true, keyType: basic_1.TableKeyType.default });
28407
28429
  const id = new _typed_identifier_1.TypedIdentifier(nameToken, filename, type);
28408
28430
  scope.addIdentifier(id);
28409
28431
  }
@@ -28863,7 +28885,7 @@ class SelectOption {
28863
28885
  { name: "LOW", type: found },
28864
28886
  { name: "HIGH", type: found },
28865
28887
  ]);
28866
- scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(nameToken, filename, new basic_1.TableType(stru, { withHeader: true })));
28888
+ scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(nameToken, filename, new basic_1.TableType(stru, { withHeader: true, keyType: basic_1.TableKeyType.default })));
28867
28889
  return;
28868
28890
  }
28869
28891
  if (nameToken) {
@@ -29150,7 +29172,7 @@ const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/
29150
29172
  class Split {
29151
29173
  runSyntax(node, scope, filename) {
29152
29174
  const intoTable = node.findTokenSequencePosition("INTO", "TABLE") !== undefined;
29153
- const type = intoTable ? new basic_1.TableType(new basic_1.StringType(), { withHeader: false }) : new basic_1.StringType();
29175
+ const type = intoTable ? new basic_1.TableType(new basic_1.StringType(), { withHeader: false, keyType: basic_1.TableKeyType.default }) : new basic_1.StringType();
29154
29176
  for (const target of node.findAllExpressions(Expressions.Target)) {
29155
29177
  const inline = target.findDirectExpression(Expressions.InlineData);
29156
29178
  if (inline) {
@@ -30025,7 +30047,7 @@ class Data {
30025
30047
  }
30026
30048
  if (found instanceof Basic.VoidType) {
30027
30049
  if (table === true) {
30028
- return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.TableType(found, { withHeader: true }));
30050
+ return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.TableType(found, { withHeader: true, keyType: Basic.TableKeyType.default }));
30029
30051
  }
30030
30052
  else {
30031
30053
  return new _typed_identifier_1.TypedIdentifier(name, filename, found);
@@ -30043,7 +30065,7 @@ class Data {
30043
30065
  }
30044
30066
  }
30045
30067
  if (table === true) {
30046
- return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.TableType(new Basic.StructureType(components), { withHeader: true }));
30068
+ return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.TableType(new Basic.StructureType(components), { withHeader: true, keyType: Basic.TableKeyType.default }));
30047
30069
  }
30048
30070
  else {
30049
30071
  const val = Object.keys(values).length > 0 ? values : undefined;
@@ -30114,7 +30136,7 @@ class Statics {
30114
30136
  }
30115
30137
  if (found instanceof Basic.VoidType) {
30116
30138
  if (table === true) {
30117
- return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.TableType(found, { withHeader: true }));
30139
+ return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.TableType(found, { withHeader: true, keyType: Basic.TableKeyType.default }));
30118
30140
  }
30119
30141
  else {
30120
30142
  return new _typed_identifier_1.TypedIdentifier(name, filename, found);
@@ -30132,7 +30154,7 @@ class Statics {
30132
30154
  }
30133
30155
  }
30134
30156
  if (table === true) {
30135
- return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.TableType(new Basic.StructureType(components), { withHeader: true }));
30157
+ return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.TableType(new Basic.StructureType(components), { withHeader: true, keyType: Basic.TableKeyType.default }));
30136
30158
  }
30137
30159
  else {
30138
30160
  return new _typed_identifier_1.TypedIdentifier(name, filename, new Basic.StructureType(components));
@@ -32697,7 +32719,8 @@ class DataReference extends _abstract_type_1.AbstractType {
32697
32719
  return "REF TO " + this.type.toABAP();
32698
32720
  }
32699
32721
  isGeneric() {
32700
- return this.type.isGeneric();
32722
+ // a DATA definition can be "REF TO data", so its not generic
32723
+ return false;
32701
32724
  }
32702
32725
  containsVoid() {
32703
32726
  return this.type.containsVoid();
@@ -32971,7 +32994,8 @@ class GenericObjectReferenceType extends _abstract_type_1.AbstractType {
32971
32994
  return "```REF TO object```";
32972
32995
  }
32973
32996
  isGeneric() {
32974
- return true;
32997
+ // a DATA definition can be "REF TO object", so its not generic
32998
+ return false;
32975
32999
  }
32976
33000
  toABAP() {
32977
33001
  return "REF TO object";
@@ -33430,7 +33454,7 @@ exports.StructureType = StructureType;
33430
33454
  "use strict";
33431
33455
 
33432
33456
  Object.defineProperty(exports, "__esModule", ({ value: true }));
33433
- exports.TableType = exports.TableAccessType = void 0;
33457
+ exports.TableType = exports.TableKeyType = exports.TableAccessType = void 0;
33434
33458
  const _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ "./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js");
33435
33459
  var TableAccessType;
33436
33460
  (function (TableAccessType) {
@@ -33440,6 +33464,12 @@ var TableAccessType;
33440
33464
  TableAccessType["index"] = "INDEX";
33441
33465
  TableAccessType["any"] = "ANY";
33442
33466
  })(TableAccessType = exports.TableAccessType || (exports.TableAccessType = {}));
33467
+ var TableKeyType;
33468
+ (function (TableKeyType) {
33469
+ TableKeyType["default"] = "DEFAULT";
33470
+ TableKeyType["user"] = "USER";
33471
+ TableKeyType["empty"] = "EMPTY";
33472
+ })(TableKeyType = exports.TableKeyType || (exports.TableKeyType = {}));
33443
33473
  class TableType extends _abstract_type_1.AbstractType {
33444
33474
  constructor(rowType, options, qualifiedName) {
33445
33475
  var _a;
@@ -33477,6 +33507,12 @@ class TableType extends _abstract_type_1.AbstractType {
33477
33507
  }
33478
33508
  }
33479
33509
  isGeneric() {
33510
+ var _a, _b;
33511
+ if (((_a = this.options.primaryKey) === null || _a === void 0 ? void 0 : _a.type) !== TableAccessType.standard
33512
+ && this.options.keyType === TableKeyType.user
33513
+ && ((_b = this.options.primaryKey) === null || _b === void 0 ? void 0 : _b.keyFields.length) === 0) {
33514
+ return true;
33515
+ }
33480
33516
  return this.rowType.isGeneric();
33481
33517
  }
33482
33518
  containsVoid() {
@@ -34280,10 +34316,10 @@ class FormDefinition extends _identifier_1.Identifier {
34280
34316
  let type = p.getType();
34281
34317
  const isStructure = param.findDirectTokenByText("STRUCTURE") !== undefined;
34282
34318
  if (isStructure) {
34283
- type = new basic_1.TableType(type, { withHeader: true });
34319
+ type = new basic_1.TableType(type, { withHeader: true, keyType: basic_1.TableKeyType.default });
34284
34320
  }
34285
34321
  if (type instanceof basic_1.TableType) {
34286
- type = new basic_1.TableType(type.getRowType(), { withHeader: true });
34322
+ type = new basic_1.TableType(type.getRowType(), { withHeader: true, keyType: basic_1.TableKeyType.default });
34287
34323
  }
34288
34324
  else if (!(type instanceof basic_1.UnknownType) && !(type instanceof basic_1.VoidType)) {
34289
34325
  type = new basic_1.UnknownType("FORM TABLES type must be table type");
@@ -36518,7 +36554,7 @@ class DDIC {
36518
36554
  case "%_C_POINTER":
36519
36555
  return new Types.HexType(8, qualifiedName);
36520
36556
  case "TABLE":
36521
- return new Types.TableType(new Types.AnyType(), { withHeader: false });
36557
+ return new Types.TableType(new Types.AnyType(), { withHeader: false, keyType: Types.TableKeyType.default });
36522
36558
  case "DATA":
36523
36559
  return new Types.AnyType({ qualifiedName: qualifiedName });
36524
36560
  case "NUMERIC":
@@ -45005,6 +45041,7 @@ class TableType extends _abstract_object_1.AbstractObject {
45005
45041
  var _a, _b, _c;
45006
45042
  const tableOptions = {
45007
45043
  withHeader: false,
45044
+ keyType: Types.TableKeyType.user,
45008
45045
  secondary: [],
45009
45046
  };
45010
45047
  for (const k of ((_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.dd43v) || []) {
@@ -46213,7 +46250,7 @@ class Registry {
46213
46250
  }
46214
46251
  static abaplintVersion() {
46215
46252
  // magic, see build script "version.sh"
46216
- return "2.95.51";
46253
+ return "2.97.0";
46217
46254
  }
46218
46255
  getDDICReferences() {
46219
46256
  return this.references;
@@ -49639,7 +49676,7 @@ class ConstantClasses {
49639
49676
  title: "Validate constant classes",
49640
49677
  shortDescription: `Checks that a class contains exactly the constants corresponding to a domain's fixed values.`,
49641
49678
  extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-enumeration-classes-to-constants-interfaces`,
49642
- tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Experimental],
49679
+ tags: [_irule_1.RuleTag.Styleguide],
49643
49680
  };
49644
49681
  }
49645
49682
  initialize(reg) {
@@ -50903,7 +50940,7 @@ class Downport {
50903
50940
  return {
50904
50941
  key: "downport",
50905
50942
  title: "Downport statement",
50906
- shortDescription: `Experimental downport functionality`,
50943
+ shortDescription: `Downport functionality`,
50907
50944
  extendedInformation: `Much like the 'commented_code' rule this rule loops through unknown statements and tries parsing with
50908
50945
  a higher level language version. If successful, various rules are applied to downport the statement.
50909
50946
  Target downport version is always v702, thus rule is only enabled if target version is v702.
@@ -50936,7 +50973,7 @@ Current rules:
50936
50973
  * MESSAGE with non simple source
50937
50974
 
50938
50975
  Only one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,
50939
- tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
50976
+ tags: [_irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],
50940
50977
  };
50941
50978
  }
50942
50979
  getConfig() {
@@ -54533,6 +54570,75 @@ exports.FullyTypeConstants = FullyTypeConstants;
54533
54570
 
54534
54571
  /***/ }),
54535
54572
 
54573
+ /***/ "./node_modules/@abaplint/core/build/src/rules/fully_type_itabs.js":
54574
+ /*!*************************************************************************!*\
54575
+ !*** ./node_modules/@abaplint/core/build/src/rules/fully_type_itabs.js ***!
54576
+ \*************************************************************************/
54577
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
54578
+
54579
+ "use strict";
54580
+
54581
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
54582
+ exports.FullyTypeITabs = exports.FullyTypeITabsConf = void 0;
54583
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
54584
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
54585
+ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
54586
+ const Statements = __webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js");
54587
+ const Expressions = __webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js");
54588
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
54589
+ class FullyTypeITabsConf extends _basic_rule_config_1.BasicRuleConfig {
54590
+ }
54591
+ exports.FullyTypeITabsConf = FullyTypeITabsConf;
54592
+ class FullyTypeITabs extends _abap_rule_1.ABAPRule {
54593
+ constructor() {
54594
+ super(...arguments);
54595
+ this.conf = new FullyTypeITabsConf();
54596
+ }
54597
+ getMetadata() {
54598
+ return {
54599
+ key: "fully_type_itabs",
54600
+ title: "Fully type internal tables",
54601
+ shortDescription: `No implict table types or table keys`,
54602
+ badExample: `DATA lt_foo TYPE TABLE OF ty.
54603
+ DATA lt_bar TYPE STANDARD TABLE OF ty.`,
54604
+ goodExample: `DATA lt_foo TYPE STANDARD TABLE OF ty WITH EMPTY KEY.`,
54605
+ tags: [_irule_1.RuleTag.SingleFile],
54606
+ };
54607
+ }
54608
+ getConfig() {
54609
+ return this.conf;
54610
+ }
54611
+ setConfig(conf) {
54612
+ this.conf = conf;
54613
+ }
54614
+ runParsed(file) {
54615
+ const issues = [];
54616
+ for (const statement of file.getStatements()) {
54617
+ if (!(statement.get() instanceof Statements.Data)) {
54618
+ continue;
54619
+ }
54620
+ const tt = statement.findFirstExpression(Expressions.TypeTable);
54621
+ if (tt === undefined) {
54622
+ continue;
54623
+ }
54624
+ const concat = tt.concatTokens().toUpperCase();
54625
+ if (concat.includes("TYPE TABLE OF")) {
54626
+ const message = "Specify table type";
54627
+ issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
54628
+ }
54629
+ else if (concat.includes(" WITH ") === false) {
54630
+ const message = "Specify table key";
54631
+ issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
54632
+ }
54633
+ }
54634
+ return issues;
54635
+ }
54636
+ }
54637
+ exports.FullyTypeITabs = FullyTypeITabs;
54638
+ //# sourceMappingURL=fully_type_itabs.js.map
54639
+
54640
+ /***/ }),
54641
+
54536
54642
  /***/ "./node_modules/@abaplint/core/build/src/rules/function_module_recommendations.js":
54537
54643
  /*!****************************************************************************************!*\
54538
54644
  !*** ./node_modules/@abaplint/core/build/src/rules/function_module_recommendations.js ***!
@@ -56031,6 +56137,7 @@ __exportStar(__webpack_require__(/*! ./forbidden_pseudo_and_pragma */ "./node_mo
56031
56137
  __exportStar(__webpack_require__(/*! ./forbidden_void_type */ "./node_modules/@abaplint/core/build/src/rules/forbidden_void_type.js"), exports);
56032
56138
  __exportStar(__webpack_require__(/*! ./form_tables_obsolete */ "./node_modules/@abaplint/core/build/src/rules/form_tables_obsolete.js"), exports);
56033
56139
  __exportStar(__webpack_require__(/*! ./fully_type_constants */ "./node_modules/@abaplint/core/build/src/rules/fully_type_constants.js"), exports);
56140
+ __exportStar(__webpack_require__(/*! ./fully_type_itabs */ "./node_modules/@abaplint/core/build/src/rules/fully_type_itabs.js"), exports);
56034
56141
  __exportStar(__webpack_require__(/*! ./function_module_recommendations */ "./node_modules/@abaplint/core/build/src/rules/function_module_recommendations.js"), exports);
56035
56142
  __exportStar(__webpack_require__(/*! ./functional_writing */ "./node_modules/@abaplint/core/build/src/rules/functional_writing.js"), exports);
56036
56143
  __exportStar(__webpack_require__(/*! ./global_class */ "./node_modules/@abaplint/core/build/src/rules/global_class.js"), exports);
@@ -56108,6 +56215,7 @@ __exportStar(__webpack_require__(/*! ./space_before_dot */ "./node_modules/@abap
56108
56215
  __exportStar(__webpack_require__(/*! ./sql_escape_host_variables */ "./node_modules/@abaplint/core/build/src/rules/sql_escape_host_variables.js"), exports);
56109
56216
  __exportStar(__webpack_require__(/*! ./start_at_tab */ "./node_modules/@abaplint/core/build/src/rules/start_at_tab.js"), exports);
56110
56217
  __exportStar(__webpack_require__(/*! ./static_call_via_instance */ "./node_modules/@abaplint/core/build/src/rules/static_call_via_instance.js"), exports);
56218
+ __exportStar(__webpack_require__(/*! ./strict_sql */ "./node_modules/@abaplint/core/build/src/rules/strict_sql.js"), exports);
56111
56219
  __exportStar(__webpack_require__(/*! ./superclass_final */ "./node_modules/@abaplint/core/build/src/rules/superclass_final.js"), exports);
56112
56220
  __exportStar(__webpack_require__(/*! ./superfluous_value */ "./node_modules/@abaplint/core/build/src/rules/superfluous_value.js"), exports);
56113
56221
  __exportStar(__webpack_require__(/*! ./sy_modification */ "./node_modules/@abaplint/core/build/src/rules/sy_modification.js"), exports);
@@ -62103,7 +62211,8 @@ If the target is a sorted/hashed table, no issue is reported`,
62103
62211
  type = found;
62104
62212
  }
62105
62213
  if (type instanceof basic_1.TableType
62106
- && ((type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.sorted || (type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.hashed)) {
62214
+ && ((type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.sorted
62215
+ || (type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.hashed)) {
62107
62216
  return true;
62108
62217
  }
62109
62218
  }
@@ -62931,6 +63040,7 @@ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@ab
62931
63040
  const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
62932
63041
  const version_1 = __webpack_require__(/*! ../version */ "./node_modules/@abaplint/core/build/src/version.js");
62933
63042
  const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
63043
+ const edit_helper_1 = __webpack_require__(/*! ../edit_helper */ "./node_modules/@abaplint/core/build/src/edit_helper.js");
62934
63044
  class SQLEscapeHostVariablesConf extends _basic_rule_config_1.BasicRuleConfig {
62935
63045
  }
62936
63046
  exports.SQLEscapeHostVariablesConf = SQLEscapeHostVariablesConf;
@@ -62945,7 +63055,7 @@ class SQLEscapeHostVariables extends _abap_rule_1.ABAPRule {
62945
63055
  title: "Escape SQL host variables",
62946
63056
  shortDescription: `Escape SQL host variables, from 740sp05`,
62947
63057
  extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#avoid-obsolete-language-elements`,
62948
- tags: [_irule_1.RuleTag.Upport, _irule_1.RuleTag.Styleguide],
63058
+ tags: [_irule_1.RuleTag.Upport, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.Syntax],
62949
63059
  badExample: `SELECT * FROM tab INTO TABLE res WHERE field = val.`,
62950
63060
  goodExample: `SELECT * FROM tab INTO TABLE @res WHERE field = @val.`,
62951
63061
  };
@@ -62958,52 +63068,45 @@ class SQLEscapeHostVariables extends _abap_rule_1.ABAPRule {
62958
63068
  }
62959
63069
  runParsed(file, obj) {
62960
63070
  const issues = [];
62961
- if (obj.getType() === "INTF") {
63071
+ const type = obj.getType();
63072
+ if (type === "INTF" || type === "TYPE") {
62962
63073
  return [];
62963
63074
  }
62964
- if (this.reg.getConfig().getVersion() < version_1.Version.v740sp02 && this.reg.getConfig().getVersion() !== version_1.Version.Cloud) {
63075
+ if (this.reg.getConfig().getVersion() < version_1.Version.v740sp02
63076
+ && this.reg.getConfig().getVersion() !== version_1.Version.Cloud) {
62965
63077
  return [];
62966
63078
  }
62967
63079
  for (const s of file.getStatements()) {
62968
- const str = s.concatTokens().toUpperCase();
62969
- if (s.get() instanceof Statements.Select
62970
- || s.get() instanceof Statements.SelectLoop) {
62971
- // this is not completely correct and does not catch all, but okay for now
62972
- // todo: replace with logic from "else if" branch below, when/if it proves to work
62973
- if (str.includes(" INTO ( @")
62974
- || str.includes(" INTO (@")
62975
- || str.includes(" INTO @")
62976
- || str.includes(" INTO TABLE @")
62977
- || str.includes(" INTO CORRESPONDING FIELDS OF @")
62978
- || str.includes(" INTO CORRESPONDING FIELDS OF TABLE @")
62979
- || str.includes(" APPENDING TABLE @")
62980
- || (str.includes(" APPENDING ") === false && str.includes(" INTO ") === false)
62981
- || str.includes(" APPENDING CORRESPONDING FIELDS OF TABLE @")) {
62982
- continue;
62983
- }
62984
- else {
62985
- const message = "Escape SQL host variables";
62986
- const issue = issue_1.Issue.atToken(file, s.getFirstToken(), message, this.getMetadata().key, this.conf.severity);
62987
- issues.push(issue);
62988
- }
62989
- }
62990
- else if (s.get() instanceof Statements.UpdateDatabase
63080
+ if (s.get() instanceof Statements.UpdateDatabase
62991
63081
  || s.get() instanceof Statements.ModifyDatabase
63082
+ || s.get() instanceof Statements.Select
63083
+ || s.get() instanceof Statements.SelectLoop
62992
63084
  || s.get() instanceof Statements.InsertDatabase
62993
63085
  || s.get() instanceof Statements.DeleteDatabase) {
62994
- if (str.startsWith("MODIFY SCREEN FROM ")) {
62995
- continue;
62996
- }
62997
63086
  for (const o of s.findAllExpressions(Expressions.SQLSource)) {
62998
63087
  const first = o.getFirstChild();
62999
63088
  if (((first === null || first === void 0 ? void 0 : first.get()) instanceof Expressions.Source && first.getChildren()[0].get() instanceof Expressions.FieldChain)
63000
63089
  || ((first === null || first === void 0 ? void 0 : first.get()) instanceof Expressions.SimpleSource3 && first.getChildren()[0].get() instanceof Expressions.FieldChain)) {
63001
63090
  const message = "Escape SQL host variables";
63002
- const issue = issue_1.Issue.atToken(file, first.getFirstToken(), message, this.getMetadata().key, this.conf.severity);
63091
+ const firstToken = o.getFirstChild().getFirstToken();
63092
+ const fix = edit_helper_1.EditHelper.replaceToken(file, firstToken, "@" + (firstToken === null || firstToken === void 0 ? void 0 : firstToken.getStr()));
63093
+ const issue = issue_1.Issue.atToken(file, first.getFirstToken(), message, this.getMetadata().key, this.conf.severity, fix);
63003
63094
  issues.push(issue);
63004
63095
  break;
63005
63096
  }
63006
63097
  }
63098
+ for (const o of s.findAllExpressions(Expressions.SQLTarget)) {
63099
+ const escaped = o.findDirectTokenByText("@");
63100
+ if (escaped !== undefined) {
63101
+ continue;
63102
+ }
63103
+ const message = "Escape SQL host variables";
63104
+ const firstToken = o.getFirstChild().getFirstToken();
63105
+ const fix = edit_helper_1.EditHelper.replaceToken(file, firstToken, "@" + (firstToken === null || firstToken === void 0 ? void 0 : firstToken.getStr()));
63106
+ const issue = issue_1.Issue.atToken(file, o.getFirstToken(), message, this.getMetadata().key, this.conf.severity, fix);
63107
+ issues.push(issue);
63108
+ break;
63109
+ }
63007
63110
  }
63008
63111
  }
63009
63112
  return issues;
@@ -63189,6 +63292,87 @@ exports.StaticCallViaInstance = StaticCallViaInstance;
63189
63292
 
63190
63293
  /***/ }),
63191
63294
 
63295
+ /***/ "./node_modules/@abaplint/core/build/src/rules/strict_sql.js":
63296
+ /*!*******************************************************************!*\
63297
+ !*** ./node_modules/@abaplint/core/build/src/rules/strict_sql.js ***!
63298
+ \*******************************************************************/
63299
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
63300
+
63301
+ "use strict";
63302
+
63303
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
63304
+ exports.StrictSQL = exports.StrictSQLConf = void 0;
63305
+ const Statements = __webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js");
63306
+ const Expressions = __webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js");
63307
+ const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
63308
+ const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
63309
+ const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
63310
+ const version_1 = __webpack_require__(/*! ../version */ "./node_modules/@abaplint/core/build/src/version.js");
63311
+ const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
63312
+ class StrictSQLConf extends _basic_rule_config_1.BasicRuleConfig {
63313
+ }
63314
+ exports.StrictSQLConf = StrictSQLConf;
63315
+ class StrictSQL extends _abap_rule_1.ABAPRule {
63316
+ constructor() {
63317
+ super(...arguments);
63318
+ this.conf = new StrictSQLConf();
63319
+ }
63320
+ getMetadata() {
63321
+ return {
63322
+ key: "strict_sql",
63323
+ title: "Strict SQL",
63324
+ shortDescription: `Strict SQL`,
63325
+ extendedInformation: `https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/abapinto_clause.htm
63326
+
63327
+ https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-us/abenopensql_strict_mode_750.htm
63328
+
63329
+ Also see separate rule sql_escape_host_variables`,
63330
+ tags: [_irule_1.RuleTag.Upport, _irule_1.RuleTag.Syntax],
63331
+ };
63332
+ }
63333
+ getConfig() {
63334
+ return this.conf;
63335
+ }
63336
+ setConfig(conf) {
63337
+ this.conf = conf;
63338
+ }
63339
+ runParsed(file, obj) {
63340
+ const issues = [];
63341
+ const type = obj.getType();
63342
+ if (type === "INTF" || type === "TYPE") {
63343
+ return [];
63344
+ }
63345
+ if (this.reg.getConfig().getVersion() < version_1.Version.v740sp02
63346
+ && this.reg.getConfig().getVersion() !== version_1.Version.Cloud) {
63347
+ return [];
63348
+ }
63349
+ for (const s of file.getStatements()) {
63350
+ if (s.get() instanceof Statements.Select
63351
+ || s.get() instanceof Statements.SelectLoop) {
63352
+ const expr = s.findDirectExpression(Expressions.Select);
63353
+ const where = expr === null || expr === void 0 ? void 0 : expr.findDirectExpression(Expressions.SQLCond);
63354
+ const into = (expr === null || expr === void 0 ? void 0 : expr.findDirectExpression(Expressions.SQLIntoStructure))
63355
+ || (expr === null || expr === void 0 ? void 0 : expr.findDirectExpression(Expressions.SQLIntoTable));
63356
+ if (into === undefined || where === undefined) {
63357
+ continue;
63358
+ }
63359
+ if (where.getFirstToken().getStart().isBefore(into.getFirstToken().getStart())) {
63360
+ continue;
63361
+ }
63362
+ const message = "INTO/APPENDING must be last in strict SQL";
63363
+ const issue = issue_1.Issue.atToken(file, s.getFirstToken(), message, this.getMetadata().key, this.conf.severity);
63364
+ issues.push(issue);
63365
+ break;
63366
+ }
63367
+ }
63368
+ return issues;
63369
+ }
63370
+ }
63371
+ exports.StrictSQL = StrictSQL;
63372
+ //# sourceMappingURL=strict_sql.js.map
63373
+
63374
+ /***/ }),
63375
+
63192
63376
  /***/ "./node_modules/@abaplint/core/build/src/rules/superclass_final.js":
63193
63377
  /*!*************************************************************************!*\
63194
63378
  !*** ./node_modules/@abaplint/core/build/src/rules/superclass_final.js ***!
@@ -76273,7 +76457,7 @@ class ClassImplementationTranspiler {
76273
76457
  if (isStatic === false) {
76274
76458
  continue;
76275
76459
  }
76276
- ret += clasName + "." + alias.getName().toLowerCase() + " = " + clasName + "." + alias.getComponent().replace("~", "$") + ";\n";
76460
+ ret += traversal_1.Traversal.escapeNamespace(clasName) + "." + alias.getName().toLowerCase() + " = " + traversal_1.Traversal.escapeNamespace(clasName) + "." + traversal_1.Traversal.escapeNamespace(alias.getComponent().replace("~", "$")) + ";\n";
76277
76461
  }
76278
76462
  // this is not correct, ABAP does not invocate the class constructor at require time,
76279
76463
  // but this will probably work
@@ -77365,13 +77549,14 @@ class Traversal {
77365
77549
  return undefined;
77366
77550
  }
77367
77551
  buildAttributes(def) {
77552
+ var _a, _b;
77368
77553
  const attr = [];
77369
77554
  // TODO: visibility is wrong for classes
77370
- for (const a of (def === null || def === void 0 ? void 0 : def.getAttributes().getAll()) || []) {
77555
+ for (const a of ((_a = def === null || def === void 0 ? void 0 : def.getAttributes()) === null || _a === void 0 ? void 0 : _a.getAll()) || []) {
77371
77556
  const type = new transpile_types_1.TranspileTypes().toType(a.getType());
77372
77557
  attr.push(`"${a.getName().toUpperCase()}": {"type": () => {return ${type};}, "visibility": "U", "is_constant": " "}`);
77373
77558
  }
77374
- for (const a of (def === null || def === void 0 ? void 0 : def.getAttributes().getConstants()) || []) {
77559
+ for (const a of ((_b = def === null || def === void 0 ? void 0 : def.getAttributes()) === null || _b === void 0 ? void 0 : _b.getConstants()) || []) {
77375
77560
  const type = new transpile_types_1.TranspileTypes().toType(a.getType());
77376
77561
  attr.push(`"${a.getName().toUpperCase()}": {"type": () => {return ${type};}, "visibility": "U", "is_constant": "X"}`);
77377
77562
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler-cli",
3
- "version": "2.5.71",
3
+ "version": "2.5.73",
4
4
  "description": "Transpiler - Command Line Interface",
5
5
  "bin": {
6
6
  "abap_transpile": "./abap_transpile"
@@ -25,12 +25,12 @@
25
25
  "author": "abaplint",
26
26
  "license": "MIT",
27
27
  "devDependencies": {
28
- "@abaplint/transpiler": "^2.5.71",
28
+ "@abaplint/transpiler": "^2.5.73",
29
29
  "@types/glob": "^7.2.0",
30
30
  "glob": "=7.2.0",
31
31
  "@types/progress": "^2.0.5",
32
32
  "@types/node": "^18.15.11",
33
- "@abaplint/core": "^2.95.51",
33
+ "@abaplint/core": "^2.97.0",
34
34
  "progress": "^2.0.3",
35
35
  "webpack": "^5.77.0",
36
36
  "webpack-cli": "^5.0.1",