@abaplint/cli 2.83.10 → 2.83.14

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/cli.js +12 -12
  2. package/package.json +3 -3
package/build/cli.js CHANGED
@@ -8618,7 +8618,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
8618
8618
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
8619
8619
 
8620
8620
  "use strict";
8621
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.DecFloat16Type = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass DecFloat16Type extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```decfloat16```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"decfloat16\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.TODO_DECFLOAT16\";\r\n }\r\n}\r\nexports.DecFloat16Type = DecFloat16Type;\r\n//# sourceMappingURL=decfloat16_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/decfloat16_type.js?");
8621
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.DecFloat16Type = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass DecFloat16Type extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```decfloat16```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"decfloat16\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.d16n\";\r\n }\r\n}\r\nexports.DecFloat16Type = DecFloat16Type;\r\n//# sourceMappingURL=decfloat16_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/decfloat16_type.js?");
8622
8622
 
8623
8623
  /***/ }),
8624
8624
 
@@ -8629,7 +8629,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
8629
8629
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
8630
8630
 
8631
8631
  "use strict";
8632
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.DecFloat34Type = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass DecFloat34Type extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```decfloat34```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"decfloat34\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.TODO_DECFLOAT34\";\r\n }\r\n}\r\nexports.DecFloat34Type = DecFloat34Type;\r\n//# sourceMappingURL=decfloat34_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/decfloat34_type.js?");
8632
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.DecFloat34Type = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass DecFloat34Type extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```decfloat34```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"decfloat34\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.d34n\";\r\n }\r\n}\r\nexports.DecFloat34Type = DecFloat34Type;\r\n//# sourceMappingURL=decfloat34_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/decfloat34_type.js?");
8633
8633
 
8634
8634
  /***/ }),
8635
8635
 
@@ -8783,7 +8783,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
8783
8783
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
8784
8784
 
8785
8785
  "use strict";
8786
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.StringType = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass StringType extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```string```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"string\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.TODO_STRING\";\r\n }\r\n}\r\nexports.StringType = StringType;\r\n//# sourceMappingURL=string_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/string_type.js?");
8786
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.StringType = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass StringType extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```string```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"string\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.string\";\r\n }\r\n}\r\nexports.StringType = StringType;\r\n//# sourceMappingURL=string_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/string_type.js?");
8787
8787
 
8788
8788
  /***/ }),
8789
8789
 
@@ -8838,7 +8838,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
8838
8838
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
8839
8839
 
8840
8840
  "use strict";
8841
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.UTCLongType = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass UTCLongType extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```utclong```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"utclong\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.TODO_UTCLONG\";\r\n }\r\n}\r\nexports.UTCLongType = UTCLongType;\r\n//# sourceMappingURL=utc_long_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/utc_long_type.js?");
8841
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.UTCLongType = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass UTCLongType extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```utclong```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"utclong\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.utcl\";\r\n }\r\n}\r\nexports.UTCLongType = UTCLongType;\r\n//# sourceMappingURL=utc_long_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/utc_long_type.js?");
8842
8842
 
8843
8843
  /***/ }),
8844
8844
 
@@ -8871,7 +8871,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
8871
8871
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
8872
8872
 
8873
8873
  "use strict";
8874
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.XStringType = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass XStringType extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```xstring```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"xstring\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.TODO_XSTRING\";\r\n }\r\n}\r\nexports.XStringType = XStringType;\r\n//# sourceMappingURL=xstring_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/xstring_type.js?");
8874
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.XStringType = void 0;\r\nconst _abstract_type_1 = __webpack_require__(/*! ./_abstract_type */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/_abstract_type.js\");\r\nclass XStringType extends _abstract_type_1.AbstractType {\r\n toText() {\r\n return \"```xstring```\";\r\n }\r\n isGeneric() {\r\n return false;\r\n }\r\n toABAP() {\r\n return \"xstring\";\r\n }\r\n containsVoid() {\r\n return false;\r\n }\r\n toCDS() {\r\n return \"abap.rawstring\";\r\n }\r\n}\r\nexports.XStringType = XStringType;\r\n//# sourceMappingURL=xstring_type.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/types/basic/xstring_type.js?");
8875
8875
 
8876
8876
  /***/ }),
8877
8877
 
@@ -9091,7 +9091,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
9091
9091
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
9092
9092
 
9093
9093
  "use strict";
9094
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.CDSLexer = void 0;\r\nconst tokens_1 = __webpack_require__(/*! ../abap/1_lexer/tokens */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js\");\r\nconst position_1 = __webpack_require__(/*! ../position */ \"./node_modules/@abaplint/core/build/src/position.js\");\r\n// todo: Keywords must be all uppercase, all lowercase, or in lowercase with an\r\n// uppercase initial letter. Other mixes of uppercase and lowercase are not allowed\r\nclass Stream {\r\n constructor(buffer) {\r\n this.buffer = buffer;\r\n }\r\n takeNext() {\r\n const next = this.buffer.substring(0, 1);\r\n this.buffer = this.buffer.substring(1);\r\n return next;\r\n }\r\n peekNext() {\r\n const next = this.buffer.substring(0, 1);\r\n return next;\r\n }\r\n length() {\r\n return this.buffer.length;\r\n }\r\n}\r\nclass Result {\r\n constructor() {\r\n this.result = [];\r\n }\r\n add(text, row, col) {\r\n if (text.length > 0) {\r\n this.result.push(new tokens_1.Identifier(new position_1.Position(row, col), text));\r\n }\r\n return \"\";\r\n }\r\n get() {\r\n return this.result;\r\n }\r\n}\r\nvar Mode;\r\n(function (Mode) {\r\n Mode[Mode[\"Default\"] = 0] = \"Default\";\r\n Mode[Mode[\"String\"] = 1] = \"String\";\r\n Mode[Mode[\"SingleLineComment\"] = 2] = \"SingleLineComment\";\r\n Mode[Mode[\"MultiLineComment\"] = 3] = \"MultiLineComment\";\r\n})(Mode || (Mode = {}));\r\nclass CDSLexer {\r\n static run(file) {\r\n const result = new Result();\r\n let mode = Mode.Default;\r\n let row = 1;\r\n let col = 1;\r\n let build = \"\";\r\n const stream = new Stream(file.getRaw().replace(/\\r/g, \"\").replace(/\\u00a0/g, \" \"));\r\n let next = \"\";\r\n while (stream.length() > 0) {\r\n const prev = next;\r\n next = stream.takeNext();\r\n const nextNext = stream.peekNext();\r\n col++;\r\n // string handling\r\n if (mode === Mode.String) {\r\n build += next;\r\n if (next === \"'\") {\r\n build = result.add(build, row, col);\r\n mode = Mode.Default;\r\n }\r\n continue;\r\n }\r\n // single line comment handling\r\n if (mode === Mode.SingleLineComment) {\r\n if (next === \"\\n\") {\r\n mode = Mode.Default;\r\n }\r\n else {\r\n continue;\r\n }\r\n }\r\n else if (mode === Mode.Default && next === \"/\" && nextNext === \"/\") {\r\n mode = Mode.SingleLineComment;\r\n build = result.add(build, row, col);\r\n continue;\r\n }\r\n // multi line comment handling\r\n if (mode === Mode.MultiLineComment) {\r\n if (prev === \"*\" && next === \"/\") {\r\n mode = Mode.Default;\r\n }\r\n continue;\r\n }\r\n else if (mode === Mode.Default && next === \"/\" && nextNext === \"*\") {\r\n mode = Mode.MultiLineComment;\r\n build = result.add(build, row, col);\r\n continue;\r\n }\r\n switch (next) {\r\n case \"'\":\r\n mode = Mode.String;\r\n build += next;\r\n break;\r\n case \" \":\r\n build = result.add(build, row, col);\r\n break;\r\n case \"\\n\":\r\n build = result.add(build, row, col);\r\n row++;\r\n col = 0;\r\n break;\r\n case \";\":\r\n case \":\":\r\n case \",\":\r\n case \".\":\r\n case \"{\":\r\n case \"}\":\r\n case \"(\":\r\n case \")\":\r\n case \"[\":\r\n case \"]\":\r\n case \"+\":\r\n case \"-\":\r\n case \"*\":\r\n case \"/\":\r\n build = result.add(build, row, col);\r\n result.add(next, row, col);\r\n break;\r\n default:\r\n build += next;\r\n break;\r\n }\r\n }\r\n result.add(build, row, col);\r\n return result.get();\r\n }\r\n}\r\nexports.CDSLexer = CDSLexer;\r\n//# sourceMappingURL=cds_lexer.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/cds/cds_lexer.js?");
9094
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.CDSLexer = void 0;\r\nconst tokens_1 = __webpack_require__(/*! ../abap/1_lexer/tokens */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js\");\r\nconst position_1 = __webpack_require__(/*! ../position */ \"./node_modules/@abaplint/core/build/src/position.js\");\r\n// todo: Keywords must be all uppercase, all lowercase, or in lowercase with an\r\n// uppercase initial letter. Other mixes of uppercase and lowercase are not allowed\r\nclass Stream {\r\n constructor(buffer) {\r\n this.buffer = buffer;\r\n }\r\n takeNext() {\r\n const next = this.buffer.substring(0, 1);\r\n this.buffer = this.buffer.substring(1);\r\n return next;\r\n }\r\n peekNext() {\r\n const next = this.buffer.substring(0, 1);\r\n return next;\r\n }\r\n length() {\r\n return this.buffer.length;\r\n }\r\n}\r\nclass Result {\r\n constructor() {\r\n this.result = [];\r\n }\r\n add(text, row, col) {\r\n if (text.length > 0) {\r\n this.result.push(new tokens_1.Identifier(new position_1.Position(row, col), text));\r\n }\r\n return \"\";\r\n }\r\n get() {\r\n return this.result;\r\n }\r\n}\r\nvar Mode;\r\n(function (Mode) {\r\n Mode[Mode[\"Default\"] = 0] = \"Default\";\r\n Mode[Mode[\"String\"] = 1] = \"String\";\r\n Mode[Mode[\"SingleLineComment\"] = 2] = \"SingleLineComment\";\r\n Mode[Mode[\"MultiLineComment\"] = 3] = \"MultiLineComment\";\r\n})(Mode || (Mode = {}));\r\nclass CDSLexer {\r\n static run(file) {\r\n const result = new Result();\r\n let mode = Mode.Default;\r\n let row = 1;\r\n let col = 1;\r\n let build = \"\";\r\n const stream = new Stream(file.getRaw().replace(/\\r/g, \"\").replace(/\\u00a0/g, \" \"));\r\n let next = \"\";\r\n while (stream.length() > 0) {\r\n const prev = next;\r\n next = stream.takeNext();\r\n const nextNext = stream.peekNext();\r\n col++;\r\n // string handling\r\n if (mode === Mode.String) {\r\n build += next;\r\n if (next === \"'\") {\r\n build = result.add(build, row, col);\r\n mode = Mode.Default;\r\n }\r\n continue;\r\n }\r\n // single line comment handling\r\n if (mode === Mode.SingleLineComment) {\r\n if (next === \"\\n\") {\r\n mode = Mode.Default;\r\n }\r\n else {\r\n continue;\r\n }\r\n }\r\n else if (mode === Mode.Default && next === \"/\" && nextNext === \"/\") {\r\n mode = Mode.SingleLineComment;\r\n build = result.add(build, row, col);\r\n continue;\r\n }\r\n // multi line comment handling\r\n if (mode === Mode.MultiLineComment) {\r\n if (next === \"\\n\") {\r\n row++;\r\n }\r\n else if (prev === \"*\" && next === \"/\") {\r\n mode = Mode.Default;\r\n }\r\n continue;\r\n }\r\n else if (mode === Mode.Default && next === \"/\" && nextNext === \"*\") {\r\n mode = Mode.MultiLineComment;\r\n build = result.add(build, row, col);\r\n continue;\r\n }\r\n switch (next) {\r\n case \"'\":\r\n mode = Mode.String;\r\n build += next;\r\n break;\r\n case \" \":\r\n build = result.add(build, row, col);\r\n break;\r\n case \"\\n\":\r\n build = result.add(build, row, col);\r\n row++;\r\n col = 0;\r\n break;\r\n case \";\":\r\n case \":\":\r\n case \",\":\r\n case \".\":\r\n case \"{\":\r\n case \"}\":\r\n case \"(\":\r\n case \")\":\r\n case \"[\":\r\n case \"]\":\r\n case \"+\":\r\n case \"-\":\r\n case \"*\":\r\n case \"/\":\r\n build = result.add(build, row, col);\r\n result.add(next, row, col);\r\n break;\r\n default:\r\n build += next;\r\n break;\r\n }\r\n }\r\n result.add(build, row, col);\r\n return result.get();\r\n }\r\n}\r\nexports.CDSLexer = CDSLexer;\r\n//# sourceMappingURL=cds_lexer.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/cds/cds_lexer.js?");
9095
9095
 
9096
9096
  /***/ }),
9097
9097
 
@@ -9443,7 +9443,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
9443
9443
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
9444
9444
 
9445
9445
  "use strict";
9446
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.DDIC = void 0;\r\nconst Types = __webpack_require__(/*! ./abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nconst basic_1 = __webpack_require__(/*! ./abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nclass DDIC {\r\n constructor(reg) {\r\n this.reg = reg;\r\n }\r\n // the class might be local with a local super class with a global exception class as super\r\n // todo: returns true for both local and global exception classes\r\n isException(def, _obj) {\r\n var _a;\r\n if (def === undefined) {\r\n return false;\r\n }\r\n if (def.name.toUpperCase() === \"CX_ROOT\") {\r\n return true;\r\n }\r\n let superClassName = def.superClassName;\r\n if (superClassName === undefined) {\r\n return false;\r\n }\r\n let i = 0;\r\n // max depth, make sure not to hit cyclic super class defintions\r\n while (i++ < 10 && superClassName !== undefined) {\r\n const found = this.reg.getObject(\"CLAS\", superClassName);\r\n if (found === undefined) {\r\n break;\r\n }\r\n const superDef = (_a = found.getMainABAPFile()) === null || _a === void 0 ? void 0 : _a.getInfo().getClassDefinitionByName(superClassName);\r\n if (superDef === undefined) {\r\n break;\r\n }\r\n if (superDef.superClassName) {\r\n superClassName = superDef.superClassName;\r\n }\r\n else {\r\n break;\r\n }\r\n }\r\n // todo, this should check for \"CX_ROOT\"\r\n const isException = ((superClassName === null || superClassName === void 0 ? void 0 : superClassName.match(/^.?cx_.*$/i)) || (superClassName === null || superClassName === void 0 ? void 0 : superClassName.match(/^\\/.+\\/cx_.*$/i))) ? true : false;\r\n return isException;\r\n }\r\n lookupBuiltinType(name, length, decimals) {\r\n switch (name) {\r\n case \"STRING\":\r\n return new Types.StringType(name);\r\n case \"XSTRING\":\r\n return new Types.XStringType(name);\r\n case \"D\":\r\n return new Types.DateType(name);\r\n case \"T\":\r\n return new Types.TimeType(name);\r\n case \"XSEQUENCE\":\r\n return new Types.XSequenceType();\r\n case \"CLIKE\":\r\n return new Types.CLikeType();\r\n case \"DECFLOAT\":\r\n return new Types.DecFloatType();\r\n case \"ANY\":\r\n return new Types.AnyType();\r\n case \"SIMPLE\":\r\n return new Types.SimpleType();\r\n case \"%_C_POINTER\":\r\n return new Types.HexType(8);\r\n case \"TABLE\":\r\n return new Types.TableType(new Types.AnyType(), { withHeader: false });\r\n case \"DATA\":\r\n return new Types.AnyType();\r\n case \"NUMERIC\":\r\n return new Types.NumericGenericType();\r\n case \"UTCLONG\": // todo, take version into account\r\n return new Types.UTCLongType();\r\n case \"DECFLOAT16\":\r\n return new Types.DecFloat16Type();\r\n case \"DECFLOAT34\":\r\n return new Types.DecFloat34Type();\r\n case \"CSEQUENCE\":\r\n return new Types.CSequenceType();\r\n case \"I\":\r\n case \"INT8\": // todo, take version into account\r\n return new Types.IntegerType(name);\r\n case \"F\":\r\n return new Types.FloatType(name);\r\n case \"P\":\r\n if (length && decimals) {\r\n return new Types.PackedType(length, decimals);\r\n }\r\n else if (length) {\r\n return new Types.PackedType(length, 0);\r\n }\r\n else {\r\n return new Types.PackedType(1, 0);\r\n }\r\n case \"C\":\r\n if (length) {\r\n return new Types.CharacterType(length);\r\n }\r\n else {\r\n return new Types.CharacterType(1);\r\n }\r\n case \"X\":\r\n if (length) {\r\n return new Types.HexType(length);\r\n }\r\n else {\r\n return new Types.HexType(1);\r\n }\r\n case \"N\":\r\n if (length) {\r\n return new Types.NumericType(length);\r\n }\r\n else {\r\n return new Types.NumericType(1);\r\n }\r\n }\r\n return undefined;\r\n }\r\n inErrorNamespace(name) {\r\n if (name === undefined) {\r\n return true;\r\n }\r\n return this.reg.inErrorNamespace(name);\r\n }\r\n lookupObject(name) {\r\n const clas = this.reg.getObject(\"CLAS\", name);\r\n const globalClas = clas === null || clas === void 0 ? void 0 : clas.getIdentifier();\r\n if (globalClas) {\r\n return { type: new basic_1.ObjectReferenceType(globalClas, name), object: clas };\r\n }\r\n const intf = this.reg.getObject(\"INTF\", name);\r\n const globalIntf = intf === null || intf === void 0 ? void 0 : intf.getIdentifier();\r\n if (globalIntf) {\r\n return { type: new basic_1.ObjectReferenceType(globalIntf, name), object: intf };\r\n }\r\n if (this.inErrorNamespace(name) === true) {\r\n return { type: new basic_1.UnknownType(name) };\r\n }\r\n else {\r\n return { type: new basic_1.VoidType(name) };\r\n }\r\n }\r\n lookupNoVoid(name) {\r\n const foundTABL = this.reg.getObject(\"TABL\", name);\r\n if (foundTABL) {\r\n return { type: foundTABL.parseType(this.reg), object: foundTABL };\r\n }\r\n const foundVIEW = this.reg.getObject(\"VIEW\", name);\r\n if (foundVIEW) {\r\n return { type: foundVIEW.parseType(this.reg), object: foundVIEW };\r\n }\r\n const foundTTYP = this.reg.getObject(\"TTYP\", name);\r\n if (foundTTYP) {\r\n return { type: foundTTYP.parseType(this.reg), object: foundTTYP };\r\n }\r\n const foundDDLS = this.reg.getObject(\"DDLS\", name);\r\n if (foundDDLS) {\r\n return { type: foundDDLS.parseType(this.reg), object: foundDDLS };\r\n }\r\n const foundDTEL = this.reg.getObject(\"DTEL\", name);\r\n if (foundDTEL) {\r\n return { type: foundDTEL.parseType(this.reg), object: foundDTEL };\r\n }\r\n const upper = name.toUpperCase();\r\n for (const obj of this.reg.getObjectsByType(\"DDLS\")) {\r\n const ddls = obj;\r\n if (ddls.getSQLViewName() === upper) {\r\n return { type: ddls.parseType(this.reg), object: obj };\r\n }\r\n }\r\n return undefined;\r\n }\r\n /** lookup with voiding and unknown types */\r\n lookup(name) {\r\n const found = this.lookupNoVoid(name);\r\n if (found) {\r\n return found;\r\n }\r\n if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \" not found, lookup\") };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name) };\r\n }\r\n }\r\n lookupDomain(name, parent) {\r\n const found = this.reg.getObject(\"DOMA\", name);\r\n if (found) {\r\n return { type: found.parseType(this.reg, parent), object: found };\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \", lookupDomain\"), object: undefined };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name), object: undefined };\r\n }\r\n }\r\n lookupDataElement(name) {\r\n if (name === undefined) {\r\n return { type: new Types.UnknownType(\"undefined, lookupDataElement\") };\r\n }\r\n const found = this.reg.getObject(\"DTEL\", name);\r\n if (found) {\r\n return { type: found.parseType(this.reg), object: found };\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \" not found, lookupDataElement\") };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name) };\r\n }\r\n }\r\n lookupTableOrView(name) {\r\n if (name === undefined) {\r\n return { type: new Types.UnknownType(\"undefined, lookupTableOrView\") };\r\n }\r\n const foundTABL = this.reg.getObject(\"TABL\", name);\r\n if (foundTABL) {\r\n return { type: foundTABL.parseType(this.reg), object: foundTABL };\r\n }\r\n const foundDDLS = this.reg.getObject(\"DDLS\", name);\r\n if (foundDDLS) {\r\n return { type: foundDDLS.parseType(this.reg), object: foundDDLS };\r\n }\r\n const upper = name.toUpperCase();\r\n for (const obj of this.reg.getObjectsByType(\"DDLS\")) {\r\n const ddls = obj;\r\n if (ddls.getSQLViewName() === upper) {\r\n return { type: ddls.parseType(this.reg), object: ddls };\r\n }\r\n }\r\n return this.lookupView(name);\r\n }\r\n lookupTableOrView2(name) {\r\n if (name === undefined) {\r\n return undefined;\r\n }\r\n const foundTABL = this.reg.getObject(\"TABL\", name);\r\n if (foundTABL) {\r\n return foundTABL;\r\n }\r\n const foundVIEW = this.reg.getObject(\"VIEW\", name);\r\n if (foundVIEW) {\r\n return foundVIEW;\r\n }\r\n const foundDDLS = this.reg.getObject(\"DDLS\", name);\r\n if (foundDDLS) {\r\n return foundDDLS;\r\n }\r\n const upper = name.toUpperCase();\r\n for (const obj of this.reg.getObjectsByType(\"DDLS\")) {\r\n const ddls = obj;\r\n if (ddls.getSQLViewName() === upper) {\r\n return ddls;\r\n }\r\n }\r\n return undefined;\r\n }\r\n lookupTable(name) {\r\n if (name === undefined) {\r\n return new Types.UnknownType(\"undefined, lookupTable\");\r\n }\r\n const found = this.reg.getObject(\"TABL\", name);\r\n if (found) {\r\n return found.parseType(this.reg);\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return new Types.UnknownType(name + \" not found, lookupTable\");\r\n }\r\n else {\r\n return new Types.VoidType(name);\r\n }\r\n }\r\n lookupView(name) {\r\n if (name === undefined) {\r\n return { type: new Types.UnknownType(\"undefined, lookupView\") };\r\n }\r\n const found = this.reg.getObject(\"VIEW\", name);\r\n if (found) {\r\n return { type: found.parseType(this.reg), object: found };\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \" not found, lookupView\") };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name) };\r\n }\r\n }\r\n lookupTableType(name) {\r\n if (name === undefined) {\r\n return { type: new Types.UnknownType(\"undefined, lookupTableType\") };\r\n }\r\n const found = this.reg.getObject(\"TTYP\", name);\r\n if (found) {\r\n return { type: found.parseType(this.reg), object: found };\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \" not found, lookupTableType\") };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name) };\r\n }\r\n }\r\n textToType(text, length, decimals, parent, qualify = true) {\r\n // todo, support short strings, and length of different integers, NUMC vs CHAR, min/max length\r\n const qualified = qualify ? parent : undefined;\r\n switch (text) {\r\n case \"DEC\": // 1 <= len <= 31\r\n case \"D16F\": // 1 <= len <= 31\r\n case \"D34F\": // 1 <= len <= 31\r\n case \"DF16_DEC\": // 1 <= len <= 31\r\n case \"DF34_DEC\": // 1 <= len <= 31\r\n case \"CURR\": // 1 <= len <= 31\r\n case \"QUAN\": // 1 <= len <= 31\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length, \" + parent, parent);\r\n }\r\n else if (decimals === undefined) {\r\n return new Types.PackedType(parseInt(length, 10), 0, qualified);\r\n }\r\n return new Types.PackedType(parseInt(length, 10), parseInt(decimals, 10), qualified);\r\n case \"ACCP\":\r\n return new Types.CharacterType(6, qualified); // YYYYMM\r\n case \"LANG\":\r\n return new Types.CharacterType(1, qualified);\r\n case \"CLNT\":\r\n return new Types.CharacterType(3, qualified);\r\n case \"CUKY\":\r\n return new Types.CharacterType(5, qualified);\r\n case \"UNIT\": // 2 <= len <= 3\r\n return new Types.CharacterType(3, qualified);\r\n case \"UTCLONG\":\r\n return new Types.CharacterType(27, qualified);\r\n case \"NUMC\": // 1 <= len <= 255\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length\", parent);\r\n }\r\n return new Types.NumericType(parseInt(length, 10), qualified);\r\n case \"CHAR\": // 1 <= len <= 30000 (1333 for table fields)\r\n case \"LCHR\": // 256 <= len <= 32000\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length\", parent);\r\n }\r\n return new Types.CharacterType(parseInt(length, 10), qualified);\r\n case \"RAW\": // 1 <= len <= 32000\r\n case \"LRAW\": // 256 <= len <= 32000\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length\", parent);\r\n }\r\n return new Types.HexType(parseInt(length, 10), qualified);\r\n case \"TIMN\": // Native HANA\r\n case \"TIMS\":\r\n return new Types.TimeType(qualified); //HHMMSS\r\n case \"DECFLOAT16\": // len = 16\r\n case \"DECFLOAT34\": // len = 34\r\n case \"D16R\": // len = 16\r\n case \"D34R\": // len = 34\r\n case \"DF16_RAW\": // len = 16\r\n case \"DF34_RAW\": // len = 34\r\n case \"FLTP\": // len = 16\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length\", parent);\r\n }\r\n return new Types.FloatingPointType(parseInt(length, 10), qualified);\r\n case \"DATN\": // Native HANA\r\n case \"DATS\":\r\n return new Types.DateType(qualified); //YYYYMMDD\r\n case \"INT1\":\r\n case \"INT2\":\r\n case \"INT4\":\r\n case \"INT8\":\r\n return new Types.IntegerType(qualified);\r\n case \"SSTR\": // 1 <= len <= 1333\r\n case \"SSTRING\": // 1 <= len <= 1333\r\n case \"STRG\": // 256 <= len\r\n case \"STRING\": // 256 <= len\r\n return new Types.StringType(qualified);\r\n case \"RSTR\": // 256 <= len\r\n case \"RAWSTRING\": // 256 <= len\r\n case \"GEOM_EWKB\":\r\n return new Types.XStringType(qualified);\r\n case \"D16S\":\r\n case \"D34S\":\r\n case \"DF16_SCL\":\r\n case \"DF34_SCL\":\r\n case \"PREC\":\r\n case \"VARC\":\r\n return new Types.UnknownType(text + \" is an obsolete data type\", parent);\r\n default:\r\n return new Types.UnknownType(text + \" unknown\", parent);\r\n }\r\n }\r\n}\r\nexports.DDIC = DDIC;\r\n//# sourceMappingURL=ddic.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/ddic.js?");
9446
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.DDIC = void 0;\r\nconst Types = __webpack_require__(/*! ./abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nconst basic_1 = __webpack_require__(/*! ./abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nclass DDIC {\r\n constructor(reg) {\r\n this.reg = reg;\r\n }\r\n // the class might be local with a local super class with a global exception class as super\r\n // todo: returns true for both local and global exception classes\r\n isException(def, _obj) {\r\n var _a;\r\n if (def === undefined) {\r\n return false;\r\n }\r\n if (def.name.toUpperCase() === \"CX_ROOT\") {\r\n return true;\r\n }\r\n let superClassName = def.superClassName;\r\n if (superClassName === undefined) {\r\n return false;\r\n }\r\n let i = 0;\r\n // max depth, make sure not to hit cyclic super class defintions\r\n while (i++ < 10 && superClassName !== undefined) {\r\n const found = this.reg.getObject(\"CLAS\", superClassName);\r\n if (found === undefined) {\r\n break;\r\n }\r\n const superDef = (_a = found.getMainABAPFile()) === null || _a === void 0 ? void 0 : _a.getInfo().getClassDefinitionByName(superClassName);\r\n if (superDef === undefined) {\r\n break;\r\n }\r\n if (superDef.superClassName) {\r\n superClassName = superDef.superClassName;\r\n }\r\n else {\r\n break;\r\n }\r\n }\r\n // todo, this should check for \"CX_ROOT\"\r\n const isException = ((superClassName === null || superClassName === void 0 ? void 0 : superClassName.match(/^.?cx_.*$/i)) || (superClassName === null || superClassName === void 0 ? void 0 : superClassName.match(/^\\/.+\\/cx_.*$/i))) ? true : false;\r\n return isException;\r\n }\r\n lookupBuiltinType(name, length, decimals) {\r\n switch (name) {\r\n case \"STRING\":\r\n return new Types.StringType(name);\r\n case \"XSTRING\":\r\n return new Types.XStringType(name);\r\n case \"D\":\r\n return new Types.DateType(name);\r\n case \"T\":\r\n return new Types.TimeType(name);\r\n case \"XSEQUENCE\":\r\n return new Types.XSequenceType();\r\n case \"CLIKE\":\r\n return new Types.CLikeType();\r\n case \"DECFLOAT\":\r\n return new Types.DecFloatType();\r\n case \"ANY\":\r\n return new Types.AnyType();\r\n case \"SIMPLE\":\r\n return new Types.SimpleType();\r\n case \"%_C_POINTER\":\r\n return new Types.HexType(8);\r\n case \"TABLE\":\r\n return new Types.TableType(new Types.AnyType(), { withHeader: false });\r\n case \"DATA\":\r\n return new Types.AnyType();\r\n case \"NUMERIC\":\r\n return new Types.NumericGenericType();\r\n case \"UTCLONG\": // todo, take version into account\r\n return new Types.UTCLongType();\r\n case \"DECFLOAT16\":\r\n return new Types.DecFloat16Type();\r\n case \"DECFLOAT34\":\r\n return new Types.DecFloat34Type();\r\n case \"CSEQUENCE\":\r\n return new Types.CSequenceType();\r\n case \"I\":\r\n case \"INT8\": // todo, take version into account\r\n return new Types.IntegerType(name);\r\n case \"F\":\r\n return new Types.FloatType(name);\r\n case \"P\":\r\n if (length && decimals) {\r\n return new Types.PackedType(length, decimals);\r\n }\r\n else if (length) {\r\n return new Types.PackedType(length, 0);\r\n }\r\n else {\r\n return new Types.PackedType(1, 0);\r\n }\r\n case \"C\":\r\n if (length) {\r\n return new Types.CharacterType(length);\r\n }\r\n else {\r\n return new Types.CharacterType(1);\r\n }\r\n case \"X\":\r\n if (length) {\r\n return new Types.HexType(length);\r\n }\r\n else {\r\n return new Types.HexType(1);\r\n }\r\n case \"N\":\r\n if (length) {\r\n return new Types.NumericType(length);\r\n }\r\n else {\r\n return new Types.NumericType(1);\r\n }\r\n }\r\n return undefined;\r\n }\r\n inErrorNamespace(name) {\r\n if (name === undefined) {\r\n return true;\r\n }\r\n return this.reg.inErrorNamespace(name);\r\n }\r\n lookupObject(name) {\r\n const clas = this.reg.getObject(\"CLAS\", name);\r\n const globalClas = clas === null || clas === void 0 ? void 0 : clas.getIdentifier();\r\n if (globalClas) {\r\n return { type: new basic_1.ObjectReferenceType(globalClas, name), object: clas };\r\n }\r\n const intf = this.reg.getObject(\"INTF\", name);\r\n const globalIntf = intf === null || intf === void 0 ? void 0 : intf.getIdentifier();\r\n if (globalIntf) {\r\n return { type: new basic_1.ObjectReferenceType(globalIntf, name), object: intf };\r\n }\r\n if (this.inErrorNamespace(name) === true) {\r\n return { type: new basic_1.UnknownType(name) };\r\n }\r\n else {\r\n return { type: new basic_1.VoidType(name) };\r\n }\r\n }\r\n lookupNoVoid(name) {\r\n var _a;\r\n const foundTABL = this.reg.getObject(\"TABL\", name);\r\n if (foundTABL) {\r\n return { type: foundTABL.parseType(this.reg), object: foundTABL };\r\n }\r\n const foundVIEW = this.reg.getObject(\"VIEW\", name);\r\n if (foundVIEW) {\r\n return { type: foundVIEW.parseType(this.reg), object: foundVIEW };\r\n }\r\n const foundTTYP = this.reg.getObject(\"TTYP\", name);\r\n if (foundTTYP) {\r\n return { type: foundTTYP.parseType(this.reg), object: foundTTYP };\r\n }\r\n const foundDTEL = this.reg.getObject(\"DTEL\", name);\r\n if (foundDTEL) {\r\n return { type: foundDTEL.parseType(this.reg), object: foundDTEL };\r\n }\r\n const upper = name.toUpperCase();\r\n for (const obj of this.reg.getObjectsByType(\"DDLS\")) {\r\n const ddls = obj;\r\n if (ddls.getSQLViewName() === upper || ((_a = ddls.getDefinitionName()) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === upper) {\r\n return { type: ddls.parseType(this.reg), object: obj };\r\n }\r\n }\r\n return undefined;\r\n }\r\n /** lookup with voiding and unknown types */\r\n lookup(name) {\r\n const found = this.lookupNoVoid(name);\r\n if (found) {\r\n return found;\r\n }\r\n if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \" not found, lookup\") };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name) };\r\n }\r\n }\r\n lookupDomain(name, parent) {\r\n const found = this.reg.getObject(\"DOMA\", name);\r\n if (found) {\r\n return { type: found.parseType(this.reg, parent), object: found };\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \", lookupDomain\"), object: undefined };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name), object: undefined };\r\n }\r\n }\r\n lookupDataElement(name) {\r\n if (name === undefined) {\r\n return { type: new Types.UnknownType(\"undefined, lookupDataElement\") };\r\n }\r\n const found = this.reg.getObject(\"DTEL\", name);\r\n if (found) {\r\n return { type: found.parseType(this.reg), object: found };\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \" not found, lookupDataElement\") };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name) };\r\n }\r\n }\r\n lookupTableOrView(name) {\r\n var _a;\r\n if (name === undefined) {\r\n return { type: new Types.UnknownType(\"undefined, lookupTableOrView\") };\r\n }\r\n const foundTABL = this.reg.getObject(\"TABL\", name);\r\n if (foundTABL) {\r\n return { type: foundTABL.parseType(this.reg), object: foundTABL };\r\n }\r\n const upper = name.toUpperCase();\r\n for (const obj of this.reg.getObjectsByType(\"DDLS\")) {\r\n const ddls = obj;\r\n if (ddls.getSQLViewName() === upper || ((_a = ddls.getDefinitionName()) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === upper) {\r\n return { type: ddls.parseType(this.reg), object: ddls };\r\n }\r\n }\r\n return this.lookupView(name);\r\n }\r\n lookupTableOrView2(name) {\r\n var _a;\r\n if (name === undefined) {\r\n return undefined;\r\n }\r\n const foundTABL = this.reg.getObject(\"TABL\", name);\r\n if (foundTABL) {\r\n return foundTABL;\r\n }\r\n const foundVIEW = this.reg.getObject(\"VIEW\", name);\r\n if (foundVIEW) {\r\n return foundVIEW;\r\n }\r\n const upper = name.toUpperCase();\r\n for (const obj of this.reg.getObjectsByType(\"DDLS\")) {\r\n const ddls = obj;\r\n if (ddls.getSQLViewName() === upper || ((_a = ddls.getDefinitionName()) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === upper) {\r\n return ddls;\r\n }\r\n }\r\n return undefined;\r\n }\r\n lookupTable(name) {\r\n if (name === undefined) {\r\n return new Types.UnknownType(\"undefined, lookupTable\");\r\n }\r\n const found = this.reg.getObject(\"TABL\", name);\r\n if (found) {\r\n return found.parseType(this.reg);\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return new Types.UnknownType(name + \" not found, lookupTable\");\r\n }\r\n else {\r\n return new Types.VoidType(name);\r\n }\r\n }\r\n lookupView(name) {\r\n if (name === undefined) {\r\n return { type: new Types.UnknownType(\"undefined, lookupView\") };\r\n }\r\n const found = this.reg.getObject(\"VIEW\", name);\r\n if (found) {\r\n return { type: found.parseType(this.reg), object: found };\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \" not found, lookupView\") };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name) };\r\n }\r\n }\r\n lookupTableType(name) {\r\n if (name === undefined) {\r\n return { type: new Types.UnknownType(\"undefined, lookupTableType\") };\r\n }\r\n const found = this.reg.getObject(\"TTYP\", name);\r\n if (found) {\r\n return { type: found.parseType(this.reg), object: found };\r\n }\r\n else if (this.reg.inErrorNamespace(name)) {\r\n return { type: new Types.UnknownType(name + \" not found, lookupTableType\") };\r\n }\r\n else {\r\n return { type: new Types.VoidType(name) };\r\n }\r\n }\r\n textToType(text, length, decimals, parent, qualify = true) {\r\n // todo, support short strings, and length of different integers, NUMC vs CHAR, min/max length\r\n const qualified = qualify ? parent : undefined;\r\n switch (text) {\r\n case \"DEC\": // 1 <= len <= 31\r\n case \"D16F\": // 1 <= len <= 31\r\n case \"D34F\": // 1 <= len <= 31\r\n case \"DF16_DEC\": // 1 <= len <= 31\r\n case \"DF34_DEC\": // 1 <= len <= 31\r\n case \"CURR\": // 1 <= len <= 31\r\n case \"QUAN\": // 1 <= len <= 31\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length, \" + parent, parent);\r\n }\r\n else if (decimals === undefined) {\r\n return new Types.PackedType(parseInt(length, 10), 0, qualified);\r\n }\r\n return new Types.PackedType(parseInt(length, 10), parseInt(decimals, 10), qualified);\r\n case \"ACCP\":\r\n return new Types.CharacterType(6, qualified); // YYYYMM\r\n case \"LANG\":\r\n return new Types.CharacterType(1, qualified);\r\n case \"CLNT\":\r\n return new Types.CharacterType(3, qualified);\r\n case \"CUKY\":\r\n return new Types.CharacterType(5, qualified);\r\n case \"UNIT\": // 2 <= len <= 3\r\n return new Types.CharacterType(3, qualified);\r\n case \"UTCLONG\":\r\n return new Types.CharacterType(27, qualified);\r\n case \"NUMC\": // 1 <= len <= 255\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length\", parent);\r\n }\r\n return new Types.NumericType(parseInt(length, 10), qualified);\r\n case \"CHAR\": // 1 <= len <= 30000 (1333 for table fields)\r\n case \"LCHR\": // 256 <= len <= 32000\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length\", parent);\r\n }\r\n return new Types.CharacterType(parseInt(length, 10), qualified);\r\n case \"RAW\": // 1 <= len <= 32000\r\n case \"LRAW\": // 256 <= len <= 32000\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length\", parent);\r\n }\r\n return new Types.HexType(parseInt(length, 10), qualified);\r\n case \"TIMN\": // Native HANA\r\n case \"TIMS\":\r\n return new Types.TimeType(qualified); //HHMMSS\r\n case \"DECFLOAT16\": // len = 16\r\n case \"DECFLOAT34\": // len = 34\r\n case \"D16R\": // len = 16\r\n case \"D34R\": // len = 34\r\n case \"DF16_RAW\": // len = 16\r\n case \"DF34_RAW\": // len = 34\r\n case \"FLTP\": // len = 16\r\n if (length === undefined) {\r\n return new Types.UnknownType(text + \" unknown length\", parent);\r\n }\r\n return new Types.FloatingPointType(parseInt(length, 10), qualified);\r\n case \"DATN\": // Native HANA\r\n case \"DATS\":\r\n return new Types.DateType(qualified); //YYYYMMDD\r\n case \"INT1\":\r\n case \"INT2\":\r\n case \"INT4\":\r\n case \"INT8\":\r\n return new Types.IntegerType(qualified);\r\n case \"SSTR\": // 1 <= len <= 1333\r\n case \"SSTRING\": // 1 <= len <= 1333\r\n case \"STRG\": // 256 <= len\r\n case \"STRING\": // 256 <= len\r\n return new Types.StringType(qualified);\r\n case \"RSTR\": // 256 <= len\r\n case \"RAWSTRING\": // 256 <= len\r\n case \"GEOM_EWKB\":\r\n return new Types.XStringType(qualified);\r\n case \"D16S\":\r\n case \"D34S\":\r\n case \"DF16_SCL\":\r\n case \"DF34_SCL\":\r\n case \"PREC\":\r\n case \"VARC\":\r\n return new Types.UnknownType(text + \" is an obsolete data type\", parent);\r\n default:\r\n return new Types.UnknownType(text + \" unknown\", parent);\r\n }\r\n }\r\n}\r\nexports.DDIC = DDIC;\r\n//# sourceMappingURL=ddic.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/ddic.js?");
9447
9447
 
9448
9448
  /***/ }),
9449
9449
 
@@ -10147,7 +10147,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
10147
10147
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
10148
10148
 
10149
10149
  "use strict";
10150
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.DataDefinition = void 0;\r\nconst cds_determine_types_1 = __webpack_require__(/*! ../cds/cds_determine_types */ \"./node_modules/@abaplint/core/build/src/cds/cds_determine_types.js\");\r\nconst cds_parser_1 = __webpack_require__(/*! ../cds/cds_parser */ \"./node_modules/@abaplint/core/build/src/cds/cds_parser.js\");\r\nconst expressions_1 = __webpack_require__(/*! ../cds/expressions */ \"./node_modules/@abaplint/core/build/src/cds/expressions/index.js\");\r\nconst _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ \"./node_modules/@abaplint/core/build/src/objects/_abstract_object.js\");\r\nclass DataDefinition extends _abstract_object_1.AbstractObject {\r\n constructor() {\r\n super(...arguments);\r\n this.parserError = undefined;\r\n this.parsedData = undefined;\r\n }\r\n getType() {\r\n return \"DDLS\";\r\n }\r\n getAllowedNaming() {\r\n return {\r\n maxLength: 40,\r\n allowNamespace: true,\r\n };\r\n }\r\n getSQLViewName() {\r\n var _a;\r\n this.parse();\r\n return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.sqlViewName;\r\n }\r\n getDescription() {\r\n // todo\r\n return undefined;\r\n }\r\n parseType(reg) {\r\n this.parse();\r\n return new cds_determine_types_1.CDSDetermineTypes().parseType(reg, this.parsedData);\r\n }\r\n getParsedData() {\r\n return this.parsedData;\r\n }\r\n listSources() {\r\n var _a;\r\n this.parse();\r\n return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.sources;\r\n }\r\n setDirty() {\r\n this.parsedData = undefined;\r\n this.parserError = undefined;\r\n super.setDirty();\r\n }\r\n findSourceFile() {\r\n return this.getFiles().find(f => f.getFilename().endsWith(\".asddls\"));\r\n }\r\n hasParserError() {\r\n return this.parserError;\r\n }\r\n parse() {\r\n if (this.isDirty() === false) {\r\n return { updated: false, runtime: 0 };\r\n }\r\n const start = Date.now();\r\n this.parsedData = {\r\n sqlViewName: undefined,\r\n fields: [],\r\n sources: [],\r\n relations: [],\r\n associations: [],\r\n tree: undefined,\r\n };\r\n this.findSQLViewName();\r\n this.parsedData.tree = new cds_parser_1.CDSParser().parse(this.findSourceFile());\r\n if (this.parsedData.tree) {\r\n this.findSourcesAndRelations(this.parsedData.tree);\r\n this.findFieldNames(this.parsedData.tree);\r\n }\r\n else {\r\n this.parserError = true;\r\n }\r\n this.dirty = false;\r\n return { updated: true, runtime: Date.now() - start };\r\n }\r\n //////////\r\n findSQLViewName() {\r\n var _a;\r\n const match = (_a = this.findSourceFile()) === null || _a === void 0 ? void 0 : _a.getRaw().match(/@AbapCatalog\\.sqlViewName: '(\\w+)'/);\r\n if (match) {\r\n this.parsedData.sqlViewName = match[1].toUpperCase();\r\n }\r\n }\r\n findFieldNames(tree) {\r\n var _a, _b;\r\n for (const e of tree.findAllExpressions(expressions_1.CDSElement)) {\r\n let found = (_a = e.findDirectExpression(expressions_1.CDSAs)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(expressions_1.CDSName);\r\n if (found === undefined) {\r\n const list = e.findDirectExpressions(expressions_1.CDSName);\r\n found = list[list.length - 1];\r\n }\r\n if (found === undefined) {\r\n continue;\r\n }\r\n const name = found === null || found === void 0 ? void 0 : found.concatTokens();\r\n if ((_b = this.parsedData) === null || _b === void 0 ? void 0 : _b.associations.some(a => { var _a; return a.name.toUpperCase() === name.toUpperCase() || ((_a = a.as) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === name.toUpperCase(); })) {\r\n continue;\r\n }\r\n const annotations = [];\r\n for (const a of e.findDirectExpressions(expressions_1.CDSAnnotation)) {\r\n annotations.push(a.concatTokens());\r\n }\r\n this.parsedData.fields.push({\r\n name: name,\r\n annotations: annotations,\r\n key: e.findDirectTokenByText(\"KEY\") !== undefined,\r\n });\r\n }\r\n }\r\n findSourcesAndRelations(tree) {\r\n var _a, _b, _c, _d, _e, _f;\r\n for (const e of tree.findAllExpressions(expressions_1.CDSSource)) {\r\n const name = e.getFirstToken().getStr();\r\n const as = (_b = (_a = e.findDirectExpression(expressions_1.CDSAs)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(expressions_1.CDSName)) === null || _b === void 0 ? void 0 : _b.getFirstToken().getStr();\r\n this.parsedData.sources.push({ name, as });\r\n }\r\n for (const e of tree.findAllExpressions(expressions_1.CDSRelation)) {\r\n const name = e.getFirstToken().getStr();\r\n const as = (_d = (_c = e.findDirectExpression(expressions_1.CDSAs)) === null || _c === void 0 ? void 0 : _c.findDirectExpression(expressions_1.CDSName)) === null || _d === void 0 ? void 0 : _d.getFirstToken().getStr();\r\n this.parsedData.relations.push({ name, as });\r\n }\r\n for (const e of tree.findAllExpressions(expressions_1.CDSAssociation)) {\r\n const j = e.findDirectExpression(expressions_1.CDSRelation);\r\n if (j === undefined) {\r\n continue;\r\n }\r\n const name = j.getFirstToken().getStr();\r\n const as = (_f = (_e = j.findDirectExpression(expressions_1.CDSAs)) === null || _e === void 0 ? void 0 : _e.findDirectExpression(expressions_1.CDSName)) === null || _f === void 0 ? void 0 : _f.getFirstToken().getStr();\r\n this.parsedData.associations.push({\r\n name: name || \"ERROR\",\r\n as: as,\r\n });\r\n }\r\n }\r\n}\r\nexports.DataDefinition = DataDefinition;\r\n//# sourceMappingURL=data_definition.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/objects/data_definition.js?");
10150
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.DataDefinition = void 0;\r\nconst cds_determine_types_1 = __webpack_require__(/*! ../cds/cds_determine_types */ \"./node_modules/@abaplint/core/build/src/cds/cds_determine_types.js\");\r\nconst cds_parser_1 = __webpack_require__(/*! ../cds/cds_parser */ \"./node_modules/@abaplint/core/build/src/cds/cds_parser.js\");\r\nconst expressions_1 = __webpack_require__(/*! ../cds/expressions */ \"./node_modules/@abaplint/core/build/src/cds/expressions/index.js\");\r\nconst _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ \"./node_modules/@abaplint/core/build/src/objects/_abstract_object.js\");\r\nclass DataDefinition extends _abstract_object_1.AbstractObject {\r\n constructor() {\r\n super(...arguments);\r\n this.parserError = undefined;\r\n this.parsedData = undefined;\r\n }\r\n getType() {\r\n return \"DDLS\";\r\n }\r\n getAllowedNaming() {\r\n return {\r\n maxLength: 40,\r\n allowNamespace: true,\r\n };\r\n }\r\n getSQLViewName() {\r\n var _a;\r\n this.parse();\r\n return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.sqlViewName;\r\n }\r\n getDefinitionName() {\r\n var _a;\r\n this.parse();\r\n return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.definitionName;\r\n }\r\n getDescription() {\r\n // todo\r\n return undefined;\r\n }\r\n parseType(reg) {\r\n this.parse();\r\n return new cds_determine_types_1.CDSDetermineTypes().parseType(reg, this.parsedData);\r\n }\r\n getParsedData() {\r\n return this.parsedData;\r\n }\r\n listSources() {\r\n var _a;\r\n this.parse();\r\n return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.sources;\r\n }\r\n setDirty() {\r\n this.parsedData = undefined;\r\n this.parserError = undefined;\r\n super.setDirty();\r\n }\r\n findSourceFile() {\r\n return this.getFiles().find(f => f.getFilename().endsWith(\".asddls\"));\r\n }\r\n hasParserError() {\r\n return this.parserError;\r\n }\r\n parse() {\r\n var _a, _b;\r\n if (this.isDirty() === false) {\r\n return { updated: false, runtime: 0 };\r\n }\r\n const start = Date.now();\r\n this.parsedData = {\r\n sqlViewName: undefined,\r\n definitionName: undefined,\r\n fields: [],\r\n sources: [],\r\n relations: [],\r\n associations: [],\r\n tree: undefined,\r\n };\r\n this.findSQLViewName();\r\n this.parsedData.tree = new cds_parser_1.CDSParser().parse(this.findSourceFile());\r\n if (this.parsedData.tree) {\r\n this.parsedData.definitionName = (_b = (_a = this.parsedData.tree) === null || _a === void 0 ? void 0 : _a.findFirstExpression(expressions_1.CDSName)) === null || _b === void 0 ? void 0 : _b.getFirstToken().getStr();\r\n this.findSourcesAndRelations(this.parsedData.tree);\r\n this.findFieldNames(this.parsedData.tree);\r\n }\r\n else {\r\n this.parserError = true;\r\n }\r\n this.dirty = false;\r\n return { updated: true, runtime: Date.now() - start };\r\n }\r\n //////////\r\n findSQLViewName() {\r\n var _a;\r\n const match = (_a = this.findSourceFile()) === null || _a === void 0 ? void 0 : _a.getRaw().match(/@AbapCatalog\\.sqlViewName: '(\\w+)'/);\r\n if (match) {\r\n this.parsedData.sqlViewName = match[1].toUpperCase();\r\n }\r\n }\r\n findFieldNames(tree) {\r\n var _a, _b;\r\n for (const e of tree.findAllExpressions(expressions_1.CDSElement)) {\r\n let found = (_a = e.findDirectExpression(expressions_1.CDSAs)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(expressions_1.CDSName);\r\n if (found === undefined) {\r\n const list = e.findDirectExpressions(expressions_1.CDSName);\r\n found = list[list.length - 1];\r\n }\r\n if (found === undefined) {\r\n continue;\r\n }\r\n const name = found === null || found === void 0 ? void 0 : found.concatTokens();\r\n if ((_b = this.parsedData) === null || _b === void 0 ? void 0 : _b.associations.some(a => { var _a; return a.name.toUpperCase() === name.toUpperCase() || ((_a = a.as) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === name.toUpperCase(); })) {\r\n continue;\r\n }\r\n const annotations = [];\r\n for (const a of e.findDirectExpressions(expressions_1.CDSAnnotation)) {\r\n annotations.push(a.concatTokens());\r\n }\r\n this.parsedData.fields.push({\r\n name: name,\r\n annotations: annotations,\r\n key: e.findDirectTokenByText(\"KEY\") !== undefined,\r\n });\r\n }\r\n }\r\n findSourcesAndRelations(tree) {\r\n var _a, _b, _c, _d, _e, _f;\r\n for (const e of tree.findAllExpressions(expressions_1.CDSSource)) {\r\n const name = e.getFirstToken().getStr();\r\n const as = (_b = (_a = e.findDirectExpression(expressions_1.CDSAs)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(expressions_1.CDSName)) === null || _b === void 0 ? void 0 : _b.getFirstToken().getStr();\r\n this.parsedData.sources.push({ name, as });\r\n }\r\n for (const e of tree.findAllExpressions(expressions_1.CDSRelation)) {\r\n const name = e.getFirstToken().getStr();\r\n const as = (_d = (_c = e.findDirectExpression(expressions_1.CDSAs)) === null || _c === void 0 ? void 0 : _c.findDirectExpression(expressions_1.CDSName)) === null || _d === void 0 ? void 0 : _d.getFirstToken().getStr();\r\n this.parsedData.relations.push({ name, as });\r\n }\r\n for (const e of tree.findAllExpressions(expressions_1.CDSAssociation)) {\r\n const j = e.findDirectExpression(expressions_1.CDSRelation);\r\n if (j === undefined) {\r\n continue;\r\n }\r\n const name = j.getFirstToken().getStr();\r\n const as = (_f = (_e = j.findDirectExpression(expressions_1.CDSAs)) === null || _e === void 0 ? void 0 : _e.findDirectExpression(expressions_1.CDSName)) === null || _f === void 0 ? void 0 : _f.getFirstToken().getStr();\r\n this.parsedData.associations.push({\r\n name: name || \"ERROR\",\r\n as: as,\r\n });\r\n }\r\n }\r\n}\r\nexports.DataDefinition = DataDefinition;\r\n//# sourceMappingURL=data_definition.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/objects/data_definition.js?");
10151
10151
 
10152
10152
  /***/ }),
10153
10153
 
@@ -10917,7 +10917,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
10917
10917
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
10918
10918
 
10919
10919
  "use strict";
10920
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.Table = exports.TableCategory = exports.EnhancementCategory = void 0;\r\nconst Types = __webpack_require__(/*! ../abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nconst _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ \"./node_modules/@abaplint/core/build/src/objects/_abstract_object.js\");\r\nconst xml_utils_1 = __webpack_require__(/*! ../xml_utils */ \"./node_modules/@abaplint/core/build/src/xml_utils.js\");\r\nconst ddic_1 = __webpack_require__(/*! ../ddic */ \"./node_modules/@abaplint/core/build/src/ddic.js\");\r\nconst _typed_identifier_1 = __webpack_require__(/*! ../abap/types/_typed_identifier */ \"./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js\");\r\nconst basic_1 = __webpack_require__(/*! ../abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nvar EnhancementCategory;\r\n(function (EnhancementCategory) {\r\n EnhancementCategory[\"NotClassified\"] = \"0\";\r\n EnhancementCategory[\"CannotBeEhanced\"] = \"1\";\r\n EnhancementCategory[\"Character\"] = \"2\";\r\n EnhancementCategory[\"CharacterOrNumeric\"] = \"3\";\r\n EnhancementCategory[\"Deep\"] = \"4\";\r\n})(EnhancementCategory = exports.EnhancementCategory || (exports.EnhancementCategory = {}));\r\nvar TableCategory;\r\n(function (TableCategory) {\r\n TableCategory[\"Transparent\"] = \"TRANSP\";\r\n TableCategory[\"Structure\"] = \"INTTAB\";\r\n TableCategory[\"Cluster\"] = \"CLUSTER\";\r\n TableCategory[\"Pooled\"] = \"POOL\";\r\n TableCategory[\"View\"] = \"VIEW\";\r\n TableCategory[\"Append\"] = \"APPEND\";\r\n})(TableCategory = exports.TableCategory || (exports.TableCategory = {}));\r\nclass Table extends _abstract_object_1.AbstractObject {\r\n getType() {\r\n return \"TABL\";\r\n }\r\n getDescription() {\r\n // todo\r\n return undefined;\r\n }\r\n getAllowedNaming() {\r\n return {\r\n maxLength: 30,\r\n allowNamespace: true,\r\n };\r\n }\r\n setDirty() {\r\n this.parsedData = undefined;\r\n super.setDirty();\r\n }\r\n listKeys() {\r\n if (this.parsedData === undefined) {\r\n this.parseXML();\r\n }\r\n if (this.parsedData === undefined) {\r\n return [];\r\n }\r\n const ret = [];\r\n for (const p of this.parsedData.fields) {\r\n if (p.KEYFLAG === \"X\") {\r\n ret.push(p.FIELDNAME);\r\n }\r\n }\r\n return ret;\r\n }\r\n parseType(reg) {\r\n var _a, _b;\r\n if (this.parsedData === undefined) {\r\n this.parseXML();\r\n if (this.parsedData === undefined) {\r\n return new Types.UnknownType(\"Table, parser error\");\r\n }\r\n }\r\n const references = [];\r\n const components = [];\r\n const ddic = new ddic_1.DDIC(reg);\r\n for (const field of this.parsedData.fields) {\r\n const comptype = field.COMPTYPE ? field.COMPTYPE : \"\";\r\n if (comptype === \"E\") { // data element\r\n const lookup = ddic.lookupDataElement(field.ROLLNAME);\r\n components.push({ name: field.FIELDNAME, type: lookup.type });\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n }\r\n else if (field.FIELDNAME === \".INCLUDE\" || field.FIELDNAME === \".INCLU--AP\") { // incude or append structure\r\n if (field.PRECFIELD === undefined) {\r\n return new Types.UnknownType(\"Table, parser error, PRECFIELD undefined\");\r\n }\r\n const lookup = ddic.lookupTableOrView(field.PRECFIELD);\r\n let found = lookup.type;\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n if (found instanceof _typed_identifier_1.TypedIdentifier) {\r\n found = found.getType();\r\n }\r\n if (found instanceof Types.StructureType) {\r\n for (const c of found.getComponents()) {\r\n components.push({ name: c.name, type: c.type });\r\n }\r\n }\r\n else if ((((_a = field.PRECFIELD) === null || _a === void 0 ? void 0 : _a.startsWith(\"CI_\")) || ((_b = field.PRECFIELD) === null || _b === void 0 ? void 0 : _b.startsWith(\"SI_\")))\r\n && found instanceof Types.UnknownType) {\r\n continue;\r\n }\r\n else if (found instanceof Types.UnknownType) {\r\n return found;\r\n }\r\n else if (found instanceof Types.VoidType) {\r\n // set the full structure to void\r\n return found;\r\n }\r\n else {\r\n components.push({ name: field.FIELDNAME, type: found });\r\n }\r\n }\r\n else if (comptype === \"S\" && field.FIELDNAME.startsWith(\".INCLU-\")) {\r\n const lookup = ddic.lookupTableOrView(field.ROLLNAME);\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n const found = lookup.type;\r\n if (found instanceof Types.VoidType) {\r\n // set the full structure to void\r\n return found;\r\n }\r\n else if (found instanceof Types.StructureType) {\r\n const suffix = field.FIELDNAME.split(\"-\")[1];\r\n for (const c of found.getComponents()) {\r\n components.push({ name: c.name + suffix, type: c.type });\r\n }\r\n }\r\n else if (found instanceof Types.UnknownType) {\r\n return found;\r\n }\r\n }\r\n else if (comptype === \"S\") {\r\n const lookup = ddic.lookupTableOrView(field.ROLLNAME);\r\n components.push({ name: field.FIELDNAME, type: lookup.type });\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n }\r\n else if (comptype === \"R\") {\r\n if (field.ROLLNAME === undefined) {\r\n throw new Error(\"Expected ROLLNAME\");\r\n }\r\n if (field.ROLLNAME === \"DATA\") {\r\n components.push({\r\n name: field.FIELDNAME,\r\n type: new basic_1.DataReference(new basic_1.AnyType())\r\n });\r\n }\r\n else if (field.ROLLNAME === \"OBJECT\") {\r\n components.push({\r\n name: field.FIELDNAME,\r\n type: new basic_1.GenericObjectReferenceType()\r\n });\r\n }\r\n else {\r\n const lookup = ddic.lookupObject(field.ROLLNAME);\r\n components.push({ name: field.FIELDNAME, type: lookup.type });\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n }\r\n }\r\n else if (comptype === \"L\") {\r\n const lookup = ddic.lookupTableType(field.ROLLNAME);\r\n components.push({ name: field.FIELDNAME, type: lookup.type });\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n }\r\n else if (comptype === \"\") { // built in\r\n const datatype = field.DATATYPE;\r\n if (datatype === undefined) {\r\n throw new Error(\"Expected DATATYPE, while parsing TABL \" + this.getName());\r\n }\r\n const length = field.LENG ? field.LENG : field.INTLEN;\r\n components.push({\r\n name: field.FIELDNAME,\r\n type: ddic.textToType(datatype, length, field.DECIMALS, this.getName() + \"-\" + field.FIELDNAME)\r\n });\r\n }\r\n else {\r\n components.push({\r\n name: field.FIELDNAME,\r\n type: new Types.UnknownType(\"Table \" + this.getName() + \", unknown component type \\\"\" + comptype + \"\\\"\")\r\n });\r\n }\r\n }\r\n if (components.length === 0) {\r\n return new Types.UnknownType(\"Table/Structure \" + this.getName() + \" does not contain any components\");\r\n }\r\n reg.getDDICReferences().setUsing(this, references);\r\n return new Types.StructureType(components, this.getName());\r\n }\r\n getTableCategory() {\r\n var _a;\r\n if (this.parsedData === undefined) {\r\n this.parseXML();\r\n }\r\n return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.tableCategory;\r\n }\r\n getEnhancementCategory() {\r\n var _a;\r\n if (this.parsedData === undefined) {\r\n this.parseXML();\r\n }\r\n if (((_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.enhancementCategory) === undefined) {\r\n return EnhancementCategory.NotClassified;\r\n }\r\n return this.parsedData.enhancementCategory;\r\n }\r\n ///////////////\r\n parseXML() {\r\n var _a, _b, _c, _d, _e, _f, _g;\r\n const parsed = super.parseRaw2();\r\n if (parsed === undefined) {\r\n return;\r\n }\r\n this.parsedData = { fields: [] };\r\n if (parsed.abapGit === undefined) {\r\n return;\r\n }\r\n // enhancement category\r\n if (((_b = (_a = parsed.abapGit[\"asx:abap\"][\"asx:values\"]) === null || _a === void 0 ? void 0 : _a.DD02V) === null || _b === void 0 ? void 0 : _b.EXCLASS) === undefined) {\r\n this.parsedData.enhancementCategory = EnhancementCategory.NotClassified;\r\n }\r\n else {\r\n this.parsedData.enhancementCategory = (_d = (_c = parsed.abapGit[\"asx:abap\"][\"asx:values\"]) === null || _c === void 0 ? void 0 : _c.DD02V) === null || _d === void 0 ? void 0 : _d.EXCLASS;\r\n }\r\n // table category\r\n this.parsedData.tableCategory = (_f = (_e = parsed.abapGit[\"asx:abap\"][\"asx:values\"]) === null || _e === void 0 ? void 0 : _e.DD02V) === null || _f === void 0 ? void 0 : _f.TABCLASS;\r\n // fields\r\n const fields = (_g = parsed.abapGit[\"asx:abap\"][\"asx:values\"]) === null || _g === void 0 ? void 0 : _g.DD03P_TABLE;\r\n for (const field of (0, xml_utils_1.xmlToArray)(fields === null || fields === void 0 ? void 0 : fields.DD03P)) {\r\n this.parsedData.fields.push({\r\n FIELDNAME: field.FIELDNAME,\r\n ROLLNAME: field.ROLLNAME,\r\n COMPTYPE: field.COMPTYPE,\r\n PRECFIELD: field.PRECFIELD,\r\n LENG: field.LENG,\r\n INTLEN: field.INTLEN,\r\n DATATYPE: field.DATATYPE,\r\n DECIMALS: field.DECIMALS,\r\n KEYFLAG: field.KEYFLAG,\r\n });\r\n }\r\n }\r\n}\r\nexports.Table = Table;\r\n//# sourceMappingURL=table.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/objects/table.js?");
10920
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.Table = exports.TableCategory = exports.EnhancementCategory = void 0;\r\nconst Types = __webpack_require__(/*! ../abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nconst _abstract_object_1 = __webpack_require__(/*! ./_abstract_object */ \"./node_modules/@abaplint/core/build/src/objects/_abstract_object.js\");\r\nconst xml_utils_1 = __webpack_require__(/*! ../xml_utils */ \"./node_modules/@abaplint/core/build/src/xml_utils.js\");\r\nconst ddic_1 = __webpack_require__(/*! ../ddic */ \"./node_modules/@abaplint/core/build/src/ddic.js\");\r\nconst _typed_identifier_1 = __webpack_require__(/*! ../abap/types/_typed_identifier */ \"./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js\");\r\nconst basic_1 = __webpack_require__(/*! ../abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nvar EnhancementCategory;\r\n(function (EnhancementCategory) {\r\n EnhancementCategory[\"NotClassified\"] = \"0\";\r\n EnhancementCategory[\"CannotBeEhanced\"] = \"1\";\r\n EnhancementCategory[\"Character\"] = \"2\";\r\n EnhancementCategory[\"CharacterOrNumeric\"] = \"3\";\r\n EnhancementCategory[\"Deep\"] = \"4\";\r\n})(EnhancementCategory = exports.EnhancementCategory || (exports.EnhancementCategory = {}));\r\nvar TableCategory;\r\n(function (TableCategory) {\r\n TableCategory[\"Transparent\"] = \"TRANSP\";\r\n TableCategory[\"Structure\"] = \"INTTAB\";\r\n TableCategory[\"Cluster\"] = \"CLUSTER\";\r\n TableCategory[\"Pooled\"] = \"POOL\";\r\n TableCategory[\"View\"] = \"VIEW\";\r\n TableCategory[\"Append\"] = \"APPEND\";\r\n})(TableCategory = exports.TableCategory || (exports.TableCategory = {}));\r\nclass Table extends _abstract_object_1.AbstractObject {\r\n getType() {\r\n return \"TABL\";\r\n }\r\n getDescription() {\r\n // todo\r\n return undefined;\r\n }\r\n getAllowedNaming() {\r\n return {\r\n maxLength: 30,\r\n allowNamespace: true,\r\n };\r\n }\r\n setDirty() {\r\n this.parsedData = undefined;\r\n super.setDirty();\r\n }\r\n listKeys() {\r\n if (this.parsedData === undefined) {\r\n this.parseXML();\r\n }\r\n if (this.parsedData === undefined) {\r\n return [];\r\n }\r\n const ret = [];\r\n for (const p of this.parsedData.fields) {\r\n if (p.KEYFLAG === \"X\") {\r\n ret.push(p.FIELDNAME);\r\n }\r\n }\r\n return ret;\r\n }\r\n parseType(reg) {\r\n var _a, _b;\r\n if (this.parsedData === undefined) {\r\n this.parseXML();\r\n if (this.parsedData === undefined) {\r\n return new Types.UnknownType(\"Table, parser error\");\r\n }\r\n }\r\n const references = [];\r\n const components = [];\r\n const ddic = new ddic_1.DDIC(reg);\r\n for (const field of this.parsedData.fields) {\r\n const comptype = field.COMPTYPE ? field.COMPTYPE : \"\";\r\n if (comptype === \"E\") { // data element\r\n const lookup = ddic.lookupDataElement(field.ROLLNAME);\r\n components.push({ name: field.FIELDNAME, type: lookup.type });\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n }\r\n else if (field.FIELDNAME === \".INCLUDE\" || field.FIELDNAME === \".INCLU--AP\") { // incude or append structure\r\n if (field.PRECFIELD === undefined) {\r\n return new Types.UnknownType(\"Table, parser error, PRECFIELD undefined\");\r\n }\r\n const lookup = ddic.lookupTableOrView(field.PRECFIELD);\r\n let found = lookup.type;\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n if (found instanceof _typed_identifier_1.TypedIdentifier) {\r\n found = found.getType();\r\n }\r\n if (found instanceof Types.StructureType) {\r\n if (field.GROUPNAME !== undefined) {\r\n components.push({ name: field.GROUPNAME, type: found });\r\n }\r\n else {\r\n for (const c of found.getComponents()) {\r\n components.push({ name: c.name, type: c.type });\r\n }\r\n }\r\n }\r\n else if ((((_a = field.PRECFIELD) === null || _a === void 0 ? void 0 : _a.startsWith(\"CI_\")) || ((_b = field.PRECFIELD) === null || _b === void 0 ? void 0 : _b.startsWith(\"SI_\")))\r\n && found instanceof Types.UnknownType) {\r\n continue;\r\n }\r\n else if (found instanceof Types.UnknownType) {\r\n return found;\r\n }\r\n else if (found instanceof Types.VoidType) {\r\n // set the full structure to void\r\n return found;\r\n }\r\n else {\r\n components.push({ name: field.FIELDNAME, type: found });\r\n }\r\n }\r\n else if (comptype === \"S\" && field.FIELDNAME.startsWith(\".INCLU-\")) {\r\n const lookup = ddic.lookupTableOrView(field.ROLLNAME);\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n const found = lookup.type;\r\n if (found instanceof Types.VoidType) {\r\n // set the full structure to void\r\n return found;\r\n }\r\n else if (found instanceof Types.StructureType) {\r\n const suffix = field.FIELDNAME.split(\"-\")[1];\r\n for (const c of found.getComponents()) {\r\n components.push({ name: c.name + suffix, type: c.type });\r\n }\r\n }\r\n else if (found instanceof Types.UnknownType) {\r\n return found;\r\n }\r\n }\r\n else if (comptype === \"S\") {\r\n const lookup = ddic.lookupTableOrView(field.ROLLNAME);\r\n components.push({ name: field.FIELDNAME, type: lookup.type });\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n }\r\n else if (comptype === \"R\") {\r\n if (field.ROLLNAME === undefined) {\r\n throw new Error(\"Expected ROLLNAME\");\r\n }\r\n if (field.ROLLNAME === \"DATA\") {\r\n components.push({\r\n name: field.FIELDNAME,\r\n type: new basic_1.DataReference(new basic_1.AnyType())\r\n });\r\n }\r\n else if (field.ROLLNAME === \"OBJECT\") {\r\n components.push({\r\n name: field.FIELDNAME,\r\n type: new basic_1.GenericObjectReferenceType()\r\n });\r\n }\r\n else {\r\n const lookup = ddic.lookupObject(field.ROLLNAME);\r\n components.push({ name: field.FIELDNAME, type: lookup.type });\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n }\r\n }\r\n else if (comptype === \"L\") {\r\n const lookup = ddic.lookupTableType(field.ROLLNAME);\r\n components.push({ name: field.FIELDNAME, type: lookup.type });\r\n if (lookup.object) {\r\n references.push({ object: lookup.object });\r\n }\r\n }\r\n else if (comptype === \"\") { // built in\r\n const datatype = field.DATATYPE;\r\n if (datatype === undefined) {\r\n throw new Error(\"Expected DATATYPE, while parsing TABL \" + this.getName());\r\n }\r\n const length = field.LENG ? field.LENG : field.INTLEN;\r\n components.push({\r\n name: field.FIELDNAME,\r\n type: ddic.textToType(datatype, length, field.DECIMALS, this.getName() + \"-\" + field.FIELDNAME)\r\n });\r\n }\r\n else {\r\n components.push({\r\n name: field.FIELDNAME,\r\n type: new Types.UnknownType(\"Table \" + this.getName() + \", unknown component type \\\"\" + comptype + \"\\\"\")\r\n });\r\n }\r\n }\r\n if (components.length === 0) {\r\n return new Types.UnknownType(\"Table/Structure \" + this.getName() + \" does not contain any components\");\r\n }\r\n reg.getDDICReferences().setUsing(this, references);\r\n return new Types.StructureType(components, this.getName());\r\n }\r\n getTableCategory() {\r\n var _a;\r\n if (this.parsedData === undefined) {\r\n this.parseXML();\r\n }\r\n return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.tableCategory;\r\n }\r\n getEnhancementCategory() {\r\n var _a;\r\n if (this.parsedData === undefined) {\r\n this.parseXML();\r\n }\r\n if (((_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.enhancementCategory) === undefined) {\r\n return EnhancementCategory.NotClassified;\r\n }\r\n return this.parsedData.enhancementCategory;\r\n }\r\n ///////////////\r\n parseXML() {\r\n var _a, _b, _c, _d, _e, _f, _g;\r\n const parsed = super.parseRaw2();\r\n if (parsed === undefined) {\r\n return;\r\n }\r\n this.parsedData = { fields: [] };\r\n if (parsed.abapGit === undefined) {\r\n return;\r\n }\r\n // enhancement category\r\n if (((_b = (_a = parsed.abapGit[\"asx:abap\"][\"asx:values\"]) === null || _a === void 0 ? void 0 : _a.DD02V) === null || _b === void 0 ? void 0 : _b.EXCLASS) === undefined) {\r\n this.parsedData.enhancementCategory = EnhancementCategory.NotClassified;\r\n }\r\n else {\r\n this.parsedData.enhancementCategory = (_d = (_c = parsed.abapGit[\"asx:abap\"][\"asx:values\"]) === null || _c === void 0 ? void 0 : _c.DD02V) === null || _d === void 0 ? void 0 : _d.EXCLASS;\r\n }\r\n // table category\r\n this.parsedData.tableCategory = (_f = (_e = parsed.abapGit[\"asx:abap\"][\"asx:values\"]) === null || _e === void 0 ? void 0 : _e.DD02V) === null || _f === void 0 ? void 0 : _f.TABCLASS;\r\n // fields\r\n const fields = (_g = parsed.abapGit[\"asx:abap\"][\"asx:values\"]) === null || _g === void 0 ? void 0 : _g.DD03P_TABLE;\r\n for (const field of (0, xml_utils_1.xmlToArray)(fields === null || fields === void 0 ? void 0 : fields.DD03P)) {\r\n this.parsedData.fields.push({\r\n FIELDNAME: field.FIELDNAME,\r\n ROLLNAME: field.ROLLNAME,\r\n COMPTYPE: field.COMPTYPE,\r\n PRECFIELD: field.PRECFIELD,\r\n LENG: field.LENG,\r\n INTLEN: field.INTLEN,\r\n DATATYPE: field.DATATYPE,\r\n DECIMALS: field.DECIMALS,\r\n KEYFLAG: field.KEYFLAG,\r\n GROUPNAME: field.GROUPNAME,\r\n });\r\n }\r\n }\r\n}\r\nexports.Table = Table;\r\n//# sourceMappingURL=table.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/objects/table.js?");
10921
10921
 
10922
10922
  /***/ }),
10923
10923
 
@@ -11137,7 +11137,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
11137
11137
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
11138
11138
 
11139
11139
  "use strict";
11140
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Registry = void 0;\nconst config_1 = __webpack_require__(/*! ./config */ \"./node_modules/@abaplint/core/build/src/config.js\");\nconst artifacts_objects_1 = __webpack_require__(/*! ./artifacts_objects */ \"./node_modules/@abaplint/core/build/src/artifacts_objects.js\");\nconst artifacts_rules_1 = __webpack_require__(/*! ./artifacts_rules */ \"./node_modules/@abaplint/core/build/src/artifacts_rules.js\");\nconst skip_logic_1 = __webpack_require__(/*! ./skip_logic */ \"./node_modules/@abaplint/core/build/src/skip_logic.js\");\nconst _abap_object_1 = __webpack_require__(/*! ./objects/_abap_object */ \"./node_modules/@abaplint/core/build/src/objects/_abap_object.js\");\nconst find_global_definitions_1 = __webpack_require__(/*! ./abap/5_syntax/global_definitions/find_global_definitions */ \"./node_modules/@abaplint/core/build/src/abap/5_syntax/global_definitions/find_global_definitions.js\");\nconst syntax_1 = __webpack_require__(/*! ./abap/5_syntax/syntax */ \"./node_modules/@abaplint/core/build/src/abap/5_syntax/syntax.js\");\nconst excludeHelper_1 = __webpack_require__(/*! ./utils/excludeHelper */ \"./node_modules/@abaplint/core/build/src/utils/excludeHelper.js\");\nconst ddic_references_1 = __webpack_require__(/*! ./ddic_references */ \"./node_modules/@abaplint/core/build/src/ddic_references.js\");\n// todo, this should really be an instance in case there are multiple Registry'ies\nclass ParsingPerformance {\n static clear() {\n this.results = [];\n this.lexing = 0;\n this.statements = 0;\n this.structure = 0;\n }\n static push(obj, result) {\n if (result.runtimeExtra) {\n this.lexing += result.runtimeExtra.lexing;\n this.statements += result.runtimeExtra.statements;\n this.structure += result.runtimeExtra.structure;\n }\n if (result.runtime < 100) {\n return;\n }\n if (this.results === undefined) {\n this.results = [];\n }\n let extra = \"\";\n if (result.runtimeExtra) {\n extra = `\\t(lexing: ${result.runtimeExtra.lexing}ms, statements: ${result.runtimeExtra.statements}ms, structure: ${result.runtimeExtra.structure}ms)`;\n }\n this.results.push({\n runtime: result.runtime,\n extra,\n name: obj.getType() + \" \" + obj.getName(),\n });\n }\n static output() {\n const MAX = 10;\n this.results.sort((a, b) => { return b.runtime - a.runtime; });\n for (let i = 0; i < MAX; i++) {\n const row = this.results[i];\n if (row === undefined) {\n break;\n }\n process.stderr.write(`\\t${row.runtime}ms\\t${row.name} ${row.extra}\\n`);\n }\n process.stderr.write(`\\tTotal lexing: ${this.lexing}ms\\n`);\n process.stderr.write(`\\tTotal statements: ${this.statements}ms\\n`);\n process.stderr.write(`\\tTotal structure: ${this.structure}ms\\n`);\n }\n}\n///////////////////////////////////////////////////////////////////////////////////////////////\nclass Registry {\n constructor(conf) {\n this.objects = {};\n this.objectsByType = {};\n /** object containing filenames of dependencies */\n this.dependencies = {};\n this.issues = [];\n this.conf = conf ? conf : config_1.Config.getDefault();\n this.references = new ddic_references_1.DDICReferences();\n }\n static abaplintVersion() {\n // magic, see build script \"version.sh\"\n return \"2.83.10\";\n }\n getDDICReferences() {\n return this.references;\n }\n *getObjects() {\n for (const name in this.objects) {\n for (const type in this.objects[name]) {\n yield this.objects[name][type];\n }\n }\n }\n *getObjectsByType(type) {\n for (const name in this.objectsByType[type] || []) {\n yield this.objectsByType[type][name];\n }\n }\n *getFiles() {\n for (const obj of this.getObjects()) {\n for (const file of obj.getFiles()) {\n yield file;\n }\n }\n }\n getFirstObject() {\n for (const name in this.objects) {\n for (const type in this.objects[name]) {\n return this.objects[name][type];\n }\n }\n return undefined;\n }\n getObjectCount(skipDependencies = true) {\n let res = 0;\n for (const o of this.getObjects()) {\n if (skipDependencies === true && this.isDependency(o)) {\n continue;\n }\n res = res + 1;\n }\n return res;\n }\n getFileByName(filename) {\n const upper = filename.toUpperCase();\n for (const o of this.getObjects()) {\n for (const f of o.getFiles()) {\n if (f.getFilename().toUpperCase() === upper) {\n return f;\n }\n }\n }\n return undefined;\n }\n getObject(type, name) {\n if (type === undefined || name === undefined) {\n return undefined;\n }\n const searchName = name.toUpperCase();\n if (this.objects[searchName]) {\n return this.objects[searchName][type];\n }\n return undefined;\n }\n getConfig() {\n return this.conf;\n }\n // assumption: Config is immutable, and can only be changed via this method\n setConfig(conf) {\n for (const obj of this.getObjects()) {\n obj.setDirty();\n }\n this.conf = conf;\n return this;\n }\n inErrorNamespace(name) {\n const reg = new RegExp(this.getConfig().getSyntaxSetttings().errorNamespace, \"i\");\n return reg.test(name);\n }\n addFile(file) {\n return this.addFiles([file]);\n }\n updateFile(file) {\n const obj = this.find(file.getObjectName(), file.getObjectType());\n obj.updateFile(file);\n return this;\n }\n removeFile(file) {\n const obj = this.find(file.getObjectName(), file.getObjectType());\n obj.removeFile(file);\n if (obj.getFiles().length === 0) {\n this.references.clear(obj);\n this.removeObject(obj);\n }\n return this;\n }\n addFiles(files) {\n var _a;\n const globalExclude = ((_a = this.conf.getGlobal().exclude) !== null && _a !== void 0 ? _a : [])\n .map(pattern => new RegExp(pattern, \"i\"));\n for (const f of files) {\n const filename = f.getFilename();\n const isNotAbapgitFile = filename.split(\".\").length <= 2;\n if (isNotAbapgitFile || excludeHelper_1.ExcludeHelper.isExcluded(filename, globalExclude)) {\n continue;\n }\n const found = this.findOrCreate(f.getObjectName(), f.getObjectType());\n found.addFile(f);\n }\n return this;\n }\n addDependencies(files) {\n for (const f of files) {\n this.dependencies[f.getFilename().toUpperCase()] = true;\n }\n return this.addFiles(files);\n }\n addDependency(file) {\n this.dependencies[file.getFilename().toUpperCase()] = true;\n this.addFile(file);\n return this;\n }\n isDependency(obj) {\n const filename = obj.getFiles()[0].getFilename().toUpperCase();\n return this.dependencies[filename] === true;\n }\n isFileDependency(filename) {\n return this.dependencies[filename.toUpperCase()] === true;\n }\n // assumption: the file is already in the registry\n findObjectForFile(file) {\n const filename = file.getFilename();\n for (const obj of this.getObjects()) {\n for (const ofile of obj.getFiles()) {\n if (ofile.getFilename() === filename) {\n return obj;\n }\n }\n }\n return undefined;\n }\n // todo, this will be changed to async sometime\n findIssues(input) {\n if (this.isDirty() === true) {\n this.parse();\n }\n return this.runRules(input);\n }\n // todo, this will be changed to async sometime\n findIssuesObject(iobj) {\n if (this.isDirty() === true) {\n this.parse();\n }\n return this.runRules(undefined, iobj);\n }\n // todo, this will be changed to async sometime\n parse() {\n if (this.isDirty() === false) {\n return this;\n }\n ParsingPerformance.clear();\n this.issues = [];\n for (const o of this.getObjects()) {\n this.parsePrivate(o);\n this.issues.push(...o.getParsingIssues());\n }\n new find_global_definitions_1.FindGlobalDefinitions(this).run();\n return this;\n }\n async parseAsync(input) {\n var _a, _b;\n if (this.isDirty() === false) {\n return this;\n }\n ParsingPerformance.clear();\n (_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(this.getObjectCount(false), \"Lexing and parsing\");\n this.issues = [];\n for (const o of this.getObjects()) {\n await ((_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick(\"Lexing and parsing(\" + this.conf.getVersion() + \") - \" + o.getType() + \" \" + o.getName()));\n this.parsePrivate(o);\n this.issues.push(...o.getParsingIssues());\n }\n if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {\n ParsingPerformance.output();\n }\n new find_global_definitions_1.FindGlobalDefinitions(this).run(input === null || input === void 0 ? void 0 : input.progress);\n return this;\n }\n //////////////////////////////////////////\n // todo, refactor, this is a mess, see where-used, a lot of the code should be in this method instead\n parsePrivate(input) {\n const config = this.getConfig();\n const result = input.parse(config.getVersion(), config.getSyntaxSetttings().globalMacros);\n ParsingPerformance.push(input, result);\n }\n isDirty() {\n for (const o of this.getObjects()) {\n const dirty = o.isDirty();\n if (dirty === true) {\n return true;\n }\n }\n return false;\n }\n runRules(input, iobj) {\n var _a, _b, _c, _d, _e, _f;\n const rulePerformance = {};\n const issues = this.issues.slice(0);\n const objects = iobj ? [iobj] : this.getObjects();\n const rules = this.conf.getEnabledRules();\n const skipLogic = new skip_logic_1.SkipLogic(this);\n (_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(iobj ? 1 : this.getObjectCount(false), \"Run Syntax\");\n const check = [];\n for (const obj of objects) {\n (_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick(\"Run Syntax - \" + obj.getName());\n if (skipLogic.skip(obj) || this.isDependency(obj)) {\n continue;\n }\n if (obj instanceof _abap_object_1.ABAPObject) {\n new syntax_1.SyntaxLogic(this, obj).run();\n }\n check.push(obj);\n }\n (_c = input === null || input === void 0 ? void 0 : input.progress) === null || _c === void 0 ? void 0 : _c.set(rules.length, \"Initialize Rules\");\n for (const rule of rules) {\n (_d = input === null || input === void 0 ? void 0 : input.progress) === null || _d === void 0 ? void 0 : _d.tick(\"Initialize Rules - \" + rule.getMetadata().key);\n if (rule.initialize === undefined) {\n throw new Error(rule.getMetadata().key + \" missing initialize method\");\n }\n rule.initialize(this);\n rulePerformance[rule.getMetadata().key] = 0;\n }\n (_e = input === null || input === void 0 ? void 0 : input.progress) === null || _e === void 0 ? void 0 : _e.set(check.length, \"Finding Issues\");\n for (const obj of check) {\n (_f = input === null || input === void 0 ? void 0 : input.progress) === null || _f === void 0 ? void 0 : _f.tick(\"Finding Issues - \" + obj.getType() + \" \" + obj.getName());\n for (const rule of rules) {\n const before = Date.now();\n issues.push(...rule.run(obj));\n const runtime = Date.now() - before;\n rulePerformance[rule.getMetadata().key] = rulePerformance[rule.getMetadata().key] + runtime;\n }\n }\n if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {\n const perf = [];\n for (const p in rulePerformance) {\n if (rulePerformance[p] > 100) { // ignore rules if it takes less than 100ms\n perf.push({ name: p, time: rulePerformance[p] });\n }\n }\n perf.sort((a, b) => { return b.time - a.time; });\n for (const p of perf) {\n process.stderr.write(\"\\t\" + p.time + \"ms\\t\" + p.name + \"\\n\");\n }\n }\n return this.excludeIssues(issues);\n }\n excludeIssues(issues) {\n var _a;\n const ret = issues;\n const globalNoIssues = this.conf.getGlobal().noIssues || [];\n const globalNoIssuesPatterns = globalNoIssues.map(x => new RegExp(x, \"i\"));\n if (globalNoIssuesPatterns.length > 0) {\n for (let i = ret.length - 1; i >= 0; i--) {\n const filename = ret[i].getFilename();\n if (excludeHelper_1.ExcludeHelper.isExcluded(filename, globalNoIssuesPatterns)) {\n ret.splice(i, 1);\n }\n }\n }\n // exclude issues, as now we know both the filename and issue key\n for (const rule of artifacts_rules_1.ArtifactsRules.getRules()) {\n const key = rule.getMetadata().key;\n const ruleExclude = (_a = this.conf.readByKey(key, \"exclude\")) !== null && _a !== void 0 ? _a : [];\n if (ruleExclude.length === 0) {\n continue;\n }\n const ruleExcludePatterns = ruleExclude.map(x => new RegExp(x, \"i\"));\n for (let i = ret.length - 1; i >= 0; i--) {\n if (ret[i].getKey() !== key) {\n continue;\n }\n const filename = ret[i].getFilename();\n if (excludeHelper_1.ExcludeHelper.isExcluded(filename, ruleExcludePatterns)) {\n ret.splice(i, 1);\n }\n }\n }\n return ret;\n }\n findOrCreate(name, type) {\n try {\n return this.find(name, type);\n }\n catch (_a) {\n const newName = name.toUpperCase();\n const newType = type ? type : \"UNKNOWN\";\n const add = artifacts_objects_1.ArtifactsObjects.newObject(newName, newType);\n if (this.objects[newName] === undefined) {\n this.objects[newName] = {};\n }\n this.objects[newName][newType] = add;\n if (this.objectsByType[newType] === undefined) {\n this.objectsByType[newType] = {};\n }\n this.objectsByType[newType][newName] = add;\n return add;\n }\n }\n removeObject(remove) {\n if (remove === undefined) {\n return;\n }\n if (this.objects[remove.getName()][remove.getType()] === undefined) {\n throw new Error(\"removeObject: object not found\");\n }\n if (Object.keys(this.objects[remove.getName()]).length === 1) {\n delete this.objects[remove.getName()];\n }\n else {\n delete this.objects[remove.getName()][remove.getType()];\n }\n if (Object.keys(this.objectsByType[remove.getType()]).length === 1) {\n delete this.objectsByType[remove.getType()];\n }\n else {\n delete this.objectsByType[remove.getType()][remove.getName()];\n }\n }\n find(name, type) {\n const searchType = type ? type : \"UNKNOWN\";\n const searchName = name.toUpperCase();\n if (this.objects[searchName] !== undefined\n && this.objects[searchName][searchType]) {\n return this.objects[searchName][searchType];\n }\n throw new Error(\"find: object not found, \" + type + \" \" + name);\n }\n}\nexports.Registry = Registry;\n//# sourceMappingURL=registry.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/registry.js?");
11140
+ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Registry = void 0;\nconst config_1 = __webpack_require__(/*! ./config */ \"./node_modules/@abaplint/core/build/src/config.js\");\nconst artifacts_objects_1 = __webpack_require__(/*! ./artifacts_objects */ \"./node_modules/@abaplint/core/build/src/artifacts_objects.js\");\nconst artifacts_rules_1 = __webpack_require__(/*! ./artifacts_rules */ \"./node_modules/@abaplint/core/build/src/artifacts_rules.js\");\nconst skip_logic_1 = __webpack_require__(/*! ./skip_logic */ \"./node_modules/@abaplint/core/build/src/skip_logic.js\");\nconst _abap_object_1 = __webpack_require__(/*! ./objects/_abap_object */ \"./node_modules/@abaplint/core/build/src/objects/_abap_object.js\");\nconst find_global_definitions_1 = __webpack_require__(/*! ./abap/5_syntax/global_definitions/find_global_definitions */ \"./node_modules/@abaplint/core/build/src/abap/5_syntax/global_definitions/find_global_definitions.js\");\nconst syntax_1 = __webpack_require__(/*! ./abap/5_syntax/syntax */ \"./node_modules/@abaplint/core/build/src/abap/5_syntax/syntax.js\");\nconst excludeHelper_1 = __webpack_require__(/*! ./utils/excludeHelper */ \"./node_modules/@abaplint/core/build/src/utils/excludeHelper.js\");\nconst ddic_references_1 = __webpack_require__(/*! ./ddic_references */ \"./node_modules/@abaplint/core/build/src/ddic_references.js\");\n// todo, this should really be an instance in case there are multiple Registry'ies\nclass ParsingPerformance {\n static clear() {\n this.results = [];\n this.lexing = 0;\n this.statements = 0;\n this.structure = 0;\n }\n static push(obj, result) {\n if (result.runtimeExtra) {\n this.lexing += result.runtimeExtra.lexing;\n this.statements += result.runtimeExtra.statements;\n this.structure += result.runtimeExtra.structure;\n }\n if (result.runtime < 100) {\n return;\n }\n if (this.results === undefined) {\n this.results = [];\n }\n let extra = \"\";\n if (result.runtimeExtra) {\n extra = `\\t(lexing: ${result.runtimeExtra.lexing}ms, statements: ${result.runtimeExtra.statements}ms, structure: ${result.runtimeExtra.structure}ms)`;\n }\n this.results.push({\n runtime: result.runtime,\n extra,\n name: obj.getType() + \" \" + obj.getName(),\n });\n }\n static output() {\n const MAX = 10;\n this.results.sort((a, b) => { return b.runtime - a.runtime; });\n for (let i = 0; i < MAX; i++) {\n const row = this.results[i];\n if (row === undefined) {\n break;\n }\n process.stderr.write(`\\t${row.runtime}ms\\t${row.name} ${row.extra}\\n`);\n }\n process.stderr.write(`\\tTotal lexing: ${this.lexing}ms\\n`);\n process.stderr.write(`\\tTotal statements: ${this.statements}ms\\n`);\n process.stderr.write(`\\tTotal structure: ${this.structure}ms\\n`);\n }\n}\n///////////////////////////////////////////////////////////////////////////////////////////////\nclass Registry {\n constructor(conf) {\n this.objects = {};\n this.objectsByType = {};\n /** object containing filenames of dependencies */\n this.dependencies = {};\n this.issues = [];\n this.conf = conf ? conf : config_1.Config.getDefault();\n this.references = new ddic_references_1.DDICReferences();\n }\n static abaplintVersion() {\n // magic, see build script \"version.sh\"\n return \"2.83.14\";\n }\n getDDICReferences() {\n return this.references;\n }\n *getObjects() {\n for (const name in this.objects) {\n for (const type in this.objects[name]) {\n yield this.objects[name][type];\n }\n }\n }\n *getObjectsByType(type) {\n for (const name in this.objectsByType[type] || []) {\n yield this.objectsByType[type][name];\n }\n }\n *getFiles() {\n for (const obj of this.getObjects()) {\n for (const file of obj.getFiles()) {\n yield file;\n }\n }\n }\n getFirstObject() {\n for (const name in this.objects) {\n for (const type in this.objects[name]) {\n return this.objects[name][type];\n }\n }\n return undefined;\n }\n getObjectCount(skipDependencies = true) {\n let res = 0;\n for (const o of this.getObjects()) {\n if (skipDependencies === true && this.isDependency(o)) {\n continue;\n }\n res = res + 1;\n }\n return res;\n }\n getFileByName(filename) {\n const upper = filename.toUpperCase();\n for (const o of this.getObjects()) {\n for (const f of o.getFiles()) {\n if (f.getFilename().toUpperCase() === upper) {\n return f;\n }\n }\n }\n return undefined;\n }\n getObject(type, name) {\n if (type === undefined || name === undefined) {\n return undefined;\n }\n const searchName = name.toUpperCase();\n if (this.objects[searchName]) {\n return this.objects[searchName][type];\n }\n return undefined;\n }\n getConfig() {\n return this.conf;\n }\n // assumption: Config is immutable, and can only be changed via this method\n setConfig(conf) {\n for (const obj of this.getObjects()) {\n obj.setDirty();\n }\n this.conf = conf;\n return this;\n }\n inErrorNamespace(name) {\n const reg = new RegExp(this.getConfig().getSyntaxSetttings().errorNamespace, \"i\");\n return reg.test(name);\n }\n addFile(file) {\n return this.addFiles([file]);\n }\n updateFile(file) {\n const obj = this.find(file.getObjectName(), file.getObjectType());\n obj.updateFile(file);\n return this;\n }\n removeFile(file) {\n const obj = this.find(file.getObjectName(), file.getObjectType());\n obj.removeFile(file);\n if (obj.getFiles().length === 0) {\n this.references.clear(obj);\n this.removeObject(obj);\n }\n return this;\n }\n addFiles(files) {\n var _a;\n const globalExclude = ((_a = this.conf.getGlobal().exclude) !== null && _a !== void 0 ? _a : [])\n .map(pattern => new RegExp(pattern, \"i\"));\n for (const f of files) {\n const filename = f.getFilename();\n const isNotAbapgitFile = filename.split(\".\").length <= 2;\n if (isNotAbapgitFile || excludeHelper_1.ExcludeHelper.isExcluded(filename, globalExclude)) {\n continue;\n }\n const found = this.findOrCreate(f.getObjectName(), f.getObjectType());\n found.addFile(f);\n }\n return this;\n }\n addDependencies(files) {\n for (const f of files) {\n this.dependencies[f.getFilename().toUpperCase()] = true;\n }\n return this.addFiles(files);\n }\n addDependency(file) {\n this.dependencies[file.getFilename().toUpperCase()] = true;\n this.addFile(file);\n return this;\n }\n isDependency(obj) {\n const filename = obj.getFiles()[0].getFilename().toUpperCase();\n return this.dependencies[filename] === true;\n }\n isFileDependency(filename) {\n return this.dependencies[filename.toUpperCase()] === true;\n }\n // assumption: the file is already in the registry\n findObjectForFile(file) {\n const filename = file.getFilename();\n for (const obj of this.getObjects()) {\n for (const ofile of obj.getFiles()) {\n if (ofile.getFilename() === filename) {\n return obj;\n }\n }\n }\n return undefined;\n }\n // todo, this will be changed to async sometime\n findIssues(input) {\n if (this.isDirty() === true) {\n this.parse();\n }\n return this.runRules(input);\n }\n // todo, this will be changed to async sometime\n findIssuesObject(iobj) {\n if (this.isDirty() === true) {\n this.parse();\n }\n return this.runRules(undefined, iobj);\n }\n // todo, this will be changed to async sometime\n parse() {\n if (this.isDirty() === false) {\n return this;\n }\n ParsingPerformance.clear();\n this.issues = [];\n for (const o of this.getObjects()) {\n this.parsePrivate(o);\n this.issues.push(...o.getParsingIssues());\n }\n new find_global_definitions_1.FindGlobalDefinitions(this).run();\n return this;\n }\n async parseAsync(input) {\n var _a, _b;\n if (this.isDirty() === false) {\n return this;\n }\n ParsingPerformance.clear();\n (_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(this.getObjectCount(false), \"Lexing and parsing\");\n this.issues = [];\n for (const o of this.getObjects()) {\n await ((_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick(\"Lexing and parsing(\" + this.conf.getVersion() + \") - \" + o.getType() + \" \" + o.getName()));\n this.parsePrivate(o);\n this.issues.push(...o.getParsingIssues());\n }\n if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {\n ParsingPerformance.output();\n }\n new find_global_definitions_1.FindGlobalDefinitions(this).run(input === null || input === void 0 ? void 0 : input.progress);\n return this;\n }\n //////////////////////////////////////////\n // todo, refactor, this is a mess, see where-used, a lot of the code should be in this method instead\n parsePrivate(input) {\n const config = this.getConfig();\n const result = input.parse(config.getVersion(), config.getSyntaxSetttings().globalMacros);\n ParsingPerformance.push(input, result);\n }\n isDirty() {\n for (const o of this.getObjects()) {\n const dirty = o.isDirty();\n if (dirty === true) {\n return true;\n }\n }\n return false;\n }\n runRules(input, iobj) {\n var _a, _b, _c, _d, _e, _f;\n const rulePerformance = {};\n const issues = this.issues.slice(0);\n const objects = iobj ? [iobj] : this.getObjects();\n const rules = this.conf.getEnabledRules();\n const skipLogic = new skip_logic_1.SkipLogic(this);\n (_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(iobj ? 1 : this.getObjectCount(false), \"Run Syntax\");\n const check = [];\n for (const obj of objects) {\n (_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick(\"Run Syntax - \" + obj.getName());\n if (skipLogic.skip(obj) || this.isDependency(obj)) {\n continue;\n }\n if (obj instanceof _abap_object_1.ABAPObject) {\n new syntax_1.SyntaxLogic(this, obj).run();\n }\n check.push(obj);\n }\n (_c = input === null || input === void 0 ? void 0 : input.progress) === null || _c === void 0 ? void 0 : _c.set(rules.length, \"Initialize Rules\");\n for (const rule of rules) {\n (_d = input === null || input === void 0 ? void 0 : input.progress) === null || _d === void 0 ? void 0 : _d.tick(\"Initialize Rules - \" + rule.getMetadata().key);\n if (rule.initialize === undefined) {\n throw new Error(rule.getMetadata().key + \" missing initialize method\");\n }\n rule.initialize(this);\n rulePerformance[rule.getMetadata().key] = 0;\n }\n (_e = input === null || input === void 0 ? void 0 : input.progress) === null || _e === void 0 ? void 0 : _e.set(check.length, \"Finding Issues\");\n for (const obj of check) {\n (_f = input === null || input === void 0 ? void 0 : input.progress) === null || _f === void 0 ? void 0 : _f.tick(\"Finding Issues - \" + obj.getType() + \" \" + obj.getName());\n for (const rule of rules) {\n const before = Date.now();\n issues.push(...rule.run(obj));\n const runtime = Date.now() - before;\n rulePerformance[rule.getMetadata().key] = rulePerformance[rule.getMetadata().key] + runtime;\n }\n }\n if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {\n const perf = [];\n for (const p in rulePerformance) {\n if (rulePerformance[p] > 100) { // ignore rules if it takes less than 100ms\n perf.push({ name: p, time: rulePerformance[p] });\n }\n }\n perf.sort((a, b) => { return b.time - a.time; });\n for (const p of perf) {\n process.stderr.write(\"\\t\" + p.time + \"ms\\t\" + p.name + \"\\n\");\n }\n }\n return this.excludeIssues(issues);\n }\n excludeIssues(issues) {\n var _a;\n const ret = issues;\n const globalNoIssues = this.conf.getGlobal().noIssues || [];\n const globalNoIssuesPatterns = globalNoIssues.map(x => new RegExp(x, \"i\"));\n if (globalNoIssuesPatterns.length > 0) {\n for (let i = ret.length - 1; i >= 0; i--) {\n const filename = ret[i].getFilename();\n if (excludeHelper_1.ExcludeHelper.isExcluded(filename, globalNoIssuesPatterns)) {\n ret.splice(i, 1);\n }\n }\n }\n // exclude issues, as now we know both the filename and issue key\n for (const rule of artifacts_rules_1.ArtifactsRules.getRules()) {\n const key = rule.getMetadata().key;\n const ruleExclude = (_a = this.conf.readByKey(key, \"exclude\")) !== null && _a !== void 0 ? _a : [];\n if (ruleExclude.length === 0) {\n continue;\n }\n const ruleExcludePatterns = ruleExclude.map(x => new RegExp(x, \"i\"));\n for (let i = ret.length - 1; i >= 0; i--) {\n if (ret[i].getKey() !== key) {\n continue;\n }\n const filename = ret[i].getFilename();\n if (excludeHelper_1.ExcludeHelper.isExcluded(filename, ruleExcludePatterns)) {\n ret.splice(i, 1);\n }\n }\n }\n return ret;\n }\n findOrCreate(name, type) {\n try {\n return this.find(name, type);\n }\n catch (_a) {\n const newName = name.toUpperCase();\n const newType = type ? type : \"UNKNOWN\";\n const add = artifacts_objects_1.ArtifactsObjects.newObject(newName, newType);\n if (this.objects[newName] === undefined) {\n this.objects[newName] = {};\n }\n this.objects[newName][newType] = add;\n if (this.objectsByType[newType] === undefined) {\n this.objectsByType[newType] = {};\n }\n this.objectsByType[newType][newName] = add;\n return add;\n }\n }\n removeObject(remove) {\n if (remove === undefined) {\n return;\n }\n if (this.objects[remove.getName()][remove.getType()] === undefined) {\n throw new Error(\"removeObject: object not found\");\n }\n if (Object.keys(this.objects[remove.getName()]).length === 1) {\n delete this.objects[remove.getName()];\n }\n else {\n delete this.objects[remove.getName()][remove.getType()];\n }\n if (Object.keys(this.objectsByType[remove.getType()]).length === 1) {\n delete this.objectsByType[remove.getType()];\n }\n else {\n delete this.objectsByType[remove.getType()][remove.getName()];\n }\n }\n find(name, type) {\n const searchType = type ? type : \"UNKNOWN\";\n const searchName = name.toUpperCase();\n if (this.objects[searchName] !== undefined\n && this.objects[searchName][searchType]) {\n return this.objects[searchName][searchType];\n }\n throw new Error(\"find: object not found, \" + type + \" \" + name);\n }\n}\nexports.Registry = Registry;\n//# sourceMappingURL=registry.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/registry.js?");
11141
11141
 
11142
11142
  /***/ }),
11143
11143
 
@@ -11577,7 +11577,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
11577
11577
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
11578
11578
 
11579
11579
  "use strict";
11580
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.Downport = exports.DownportConf = void 0;\r\nconst _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ \"./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js\");\r\nconst issue_1 = __webpack_require__(/*! ../issue */ \"./node_modules/@abaplint/core/build/src/issue.js\");\r\nconst _irule_1 = __webpack_require__(/*! ./_irule */ \"./node_modules/@abaplint/core/build/src/rules/_irule.js\");\r\nconst _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js\");\r\nconst nodes_1 = __webpack_require__(/*! ../abap/nodes */ \"./node_modules/@abaplint/core/build/src/abap/nodes/index.js\");\r\nconst Statements = __webpack_require__(/*! ../abap/2_statements/statements */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js\");\r\nconst Expressions = __webpack_require__(/*! ../abap/2_statements/expressions */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js\");\r\nconst edit_helper_1 = __webpack_require__(/*! ../edit_helper */ \"./node_modules/@abaplint/core/build/src/edit_helper.js\");\r\nconst position_1 = __webpack_require__(/*! ../position */ \"./node_modules/@abaplint/core/build/src/position.js\");\r\nconst _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ \"./node_modules/@abaplint/core/build/src/objects/_abap_object.js\");\r\nconst version_1 = __webpack_require__(/*! ../version */ \"./node_modules/@abaplint/core/build/src/version.js\");\r\nconst registry_1 = __webpack_require__(/*! ../registry */ \"./node_modules/@abaplint/core/build/src/registry.js\");\r\nconst syntax_1 = __webpack_require__(/*! ../abap/5_syntax/syntax */ \"./node_modules/@abaplint/core/build/src/abap/5_syntax/syntax.js\");\r\nconst _reference_1 = __webpack_require__(/*! ../abap/5_syntax/_reference */ \"./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js\");\r\nconst _typed_identifier_1 = __webpack_require__(/*! ../abap/types/_typed_identifier */ \"./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js\");\r\nconst basic_1 = __webpack_require__(/*! ../abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nconst config_1 = __webpack_require__(/*! ../config */ \"./node_modules/@abaplint/core/build/src/config.js\");\r\nconst tokens_1 = __webpack_require__(/*! ../abap/1_lexer/tokens */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js\");\r\n// todo: refactor each sub-rule to new classes\r\nclass DownportConf extends _basic_rule_config_1.BasicRuleConfig {\r\n}\r\nexports.DownportConf = DownportConf;\r\nclass Downport {\r\n constructor() {\r\n this.conf = new DownportConf();\r\n }\r\n getMetadata() {\r\n return {\r\n key: \"downport\",\r\n title: \"Downport statement\",\r\n shortDescription: `Experimental downport functionality`,\r\n extendedInformation: `Much like the 'commented_code' rule this rule loops through unknown statements and tries parsing with\r\na higher level language version. If successful, various rules are applied to downport the statement.\r\nTarget downport version is always v702, thus rule is only enabled if target version is v702.\r\n\r\nCurrent rules:\r\n* NEW transformed to CREATE OBJECT, opposite of https://rules.abaplint.org/use_new/\r\n* DATA() definitions are outlined, opposite of https://rules.abaplint.org/prefer_inline/\r\n* FIELD-SYMBOL() definitions are outlined\r\n* CONV is outlined\r\n* COND is outlined\r\n* REDUCE is outlined\r\n* EMPTY KEY is changed to DEFAULT KEY, opposite of DEFAULT KEY in https://rules.abaplint.org/avoid_use/\r\n* CAST changed to ?=\r\n* LOOP AT method_call( ) is outlined\r\n* VALUE # with structure fields\r\n* VALUE # with internal table lines\r\n* Table Expressions[ index ] are outlined\r\n* SELECT INTO @DATA definitions are outlined\r\n* Some occurrences of string template formatting option ALPHA changed to function module call\r\n* SELECT/INSERT/MODIFY/DELETE/UPDATE \",\" in field list removed, \"@\" in source/targets removed\r\n\r\nOnly one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,\r\n tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],\r\n };\r\n }\r\n getConfig() {\r\n return this.conf;\r\n }\r\n setConfig(conf) {\r\n this.conf = conf;\r\n }\r\n initialize(reg) {\r\n this.lowReg = reg;\r\n const version = this.lowReg.getConfig().getVersion();\r\n if (version === version_1.Version.v702 || version === version_1.Version.OpenABAP) {\r\n this.initHighReg();\r\n }\r\n return this;\r\n }\r\n run(lowObj) {\r\n const ret = [];\r\n this.counter = 1;\r\n const version = this.lowReg.getConfig().getVersion();\r\n if (version !== version_1.Version.v702 && version !== version_1.Version.OpenABAP) {\r\n return ret;\r\n }\r\n else if (!(lowObj instanceof _abap_object_1.ABAPObject)) {\r\n return ret;\r\n }\r\n const highObj = this.highReg.getObject(lowObj.getType(), lowObj.getName());\r\n if (highObj === undefined || !(highObj instanceof _abap_object_1.ABAPObject)) {\r\n return ret;\r\n }\r\n const highSyntax = new syntax_1.SyntaxLogic(this.highReg, highObj).run();\r\n for (const lowFile of lowObj.getABAPFiles()) {\r\n const highFile = highObj.getABAPFileByName(lowFile.getFilename());\r\n if (highFile === undefined) {\r\n continue;\r\n }\r\n const lowStatements = lowFile.getStatements();\r\n const highStatements = highFile.getStatements();\r\n if (lowStatements.length !== highStatements.length) {\r\n // after applying a fix, there might be more statements in lowFile\r\n // should highReg be initialized again?\r\n /*\r\n const message = \"Internal Error: Statement lengths does not match\";\r\n ret.push(Issue.atStatement(lowFile, lowStatements[0], message, this.getMetadata().key));\r\n */\r\n continue;\r\n }\r\n for (let i = 0; i < lowStatements.length; i++) {\r\n const low = lowStatements[i];\r\n const high = highStatements[i];\r\n if ((low.get() instanceof _statement_1.Unknown && !(high.get() instanceof _statement_1.Unknown))\r\n || high.findFirstExpression(Expressions.InlineData)) {\r\n const issue = this.checkStatement(low, high, lowFile, highSyntax);\r\n if (issue) {\r\n ret.push(issue);\r\n }\r\n }\r\n }\r\n }\r\n return ret;\r\n }\r\n ////////////////////\r\n /** clones the orginal repository into highReg, and parses it with higher language version */\r\n initHighReg() {\r\n // use default configuration, ie. default target version\r\n const highConfig = config_1.Config.getDefault().get();\r\n const lowConfig = this.lowReg.getConfig().get();\r\n highConfig.syntax.errorNamespace = lowConfig.syntax.errorNamespace;\r\n highConfig.syntax.globalConstants = lowConfig.syntax.globalConstants;\r\n highConfig.syntax.globalMacros = lowConfig.syntax.globalMacros;\r\n this.highReg = new registry_1.Registry();\r\n for (const o of this.lowReg.getObjects()) {\r\n for (const f of o.getFiles()) {\r\n if (this.lowReg.isDependency(o) === true) {\r\n this.highReg.addDependency(f);\r\n }\r\n else {\r\n this.highReg.addFile(f);\r\n }\r\n }\r\n }\r\n this.highReg.parse();\r\n }\r\n /** applies one rule at a time, multiple iterations are required to transform complex statements */\r\n checkStatement(low, high, lowFile, highSyntax) {\r\n if (low.getFirstToken().getStart() instanceof position_1.VirtualPosition) {\r\n return undefined;\r\n }\r\n let found = this.emptyKey(high, lowFile);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.stringTemplateAlpha(high, lowFile);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.downportSelectInline(low, high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.downportSQLExtras(low, high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineLoopInput(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineLoopTarget(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineValue(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineReduce(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineCast(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineConv(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineCond(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineDataSimple(high, lowFile);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineData(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineFS(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.newToCreateObject(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.replaceXsdBool(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n // todo, line_exists() should be replaced before this call\r\n found = this.replaceTableExpression(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n // todo, add more rules here\r\n return undefined;\r\n }\r\n //////////////////////////////////////////\r\n downportSQLExtras(low, high, lowFile, _highSyntax) {\r\n if (!(low.get() instanceof _statement_1.Unknown)) {\r\n return undefined;\r\n }\r\n // todo: update + modify + insert + delete + select loop\r\n if (!(high.get() instanceof Statements.Select)) {\r\n return undefined;\r\n }\r\n let fix = undefined;\r\n const addFix = (token) => {\r\n const add = edit_helper_1.EditHelper.deleteToken(lowFile, token);\r\n if (fix === undefined) {\r\n fix = add;\r\n }\r\n else {\r\n fix = edit_helper_1.EditHelper.merge(fix, add);\r\n }\r\n };\r\n const candidates = [high.findAllExpressionsRecursive(Expressions.SQLTarget),\r\n high.findAllExpressionsRecursive(Expressions.SQLSource),\r\n high.findAllExpressionsRecursive(Expressions.SQLSourceSimple)].flat();\r\n for (const c of candidates) {\r\n if (c.getFirstToken() instanceof tokens_1.WAt) {\r\n addFix(c.getFirstToken());\r\n }\r\n }\r\n for (const fieldList of high.findAllExpressionsRecursive(Expressions.SQLFieldList)) {\r\n for (const token of fieldList.getDirectTokens()) {\r\n if (token.getStr() === \",\") {\r\n addFix(token);\r\n }\r\n }\r\n }\r\n if (fix === undefined) {\r\n return undefined;\r\n }\r\n else {\r\n return issue_1.Issue.atToken(lowFile, low.getFirstToken(), \"SQL, remove \\\" and ,\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n }\r\n downportSelectInline(low, high, lowFile, highSyntax) {\r\n if (!(low.get() instanceof _statement_1.Unknown)\r\n || !(high.get() instanceof Statements.Select)) {\r\n return undefined;\r\n }\r\n // as first step outline the @DATA, note that void types are okay, as long the field names are specified\r\n let found = this.downportSelectSingleInline(low, high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.downportSelectTableInline(low, high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n return undefined;\r\n }\r\n downportSelectSingleInline(_low, high, lowFile, _highSyntax) {\r\n var _a, _b, _c;\r\n const targets = ((_a = high.findFirstExpression(Expressions.SQLIntoStructure)) === null || _a === void 0 ? void 0 : _a.findDirectExpressions(Expressions.SQLTarget)) || [];\r\n if (targets.length !== 1) {\r\n return undefined;\r\n }\r\n const inlineData = targets[0].findFirstExpression(Expressions.InlineData);\r\n if (inlineData === undefined) {\r\n return undefined;\r\n }\r\n const sqlFrom = high.findAllExpressions(Expressions.SQLFromSource);\r\n if (sqlFrom.length !== 1) {\r\n return undefined;\r\n }\r\n const tableName = (_b = sqlFrom[0].findDirectExpression(Expressions.DatabaseTable)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n if (tableName === undefined) {\r\n return undefined;\r\n }\r\n const indentation = \" \".repeat(high.getFirstToken().getStart().getCol() - 1);\r\n const fieldList = high.findFirstExpression(Expressions.SQLFieldList);\r\n if (fieldList === undefined) {\r\n return undefined;\r\n }\r\n let fieldDefinition = \"\";\r\n const fields = fieldList.findDirectExpressions(Expressions.SQLFieldName);\r\n const name = ((_c = inlineData.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || \"error\";\r\n if (fields.length === 1) {\r\n fieldDefinition = `DATA ${name} TYPE ${tableName}-${fields[0].concatTokens()}.`;\r\n }\r\n else {\r\n for (const f of fields) {\r\n const fieldName = f.concatTokens();\r\n fieldDefinition += indentation + \" \" + fieldName + \" TYPE \" + tableName + \"-\" + fieldName + \",\\n\";\r\n }\r\n fieldDefinition = `DATA: BEGIN OF ${name},\r\n${fieldDefinition}${indentation} END OF ${name}.`;\r\n }\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `${fieldDefinition}\r\n${indentation}`);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, inlineData.getFirstToken(), \"Outline SELECT @DATA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n downportSelectTableInline(_low, high, lowFile, highSyntax) {\r\n var _a, _b, _c;\r\n const targets = ((_a = high.findFirstExpression(Expressions.SQLIntoTable)) === null || _a === void 0 ? void 0 : _a.findDirectExpressions(Expressions.SQLTarget)) || [];\r\n if (targets.length !== 1) {\r\n return undefined;\r\n }\r\n const inlineData = targets[0].findFirstExpression(Expressions.InlineData);\r\n if (inlineData === undefined) {\r\n return undefined;\r\n }\r\n const sqlFrom = high.findAllExpressions(Expressions.SQLFromSource);\r\n if (sqlFrom.length !== 1) {\r\n return undefined;\r\n }\r\n const tableName = (_b = sqlFrom[0].findDirectExpression(Expressions.DatabaseTable)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n if (tableName === undefined) {\r\n return undefined;\r\n }\r\n const indentation = \" \".repeat(high.getFirstToken().getStart().getCol() - 1);\r\n const fieldList = high.findFirstExpression(Expressions.SQLFieldList);\r\n if (fieldList === undefined) {\r\n return undefined;\r\n }\r\n let fieldDefinitions = \"\";\r\n for (const f of fieldList.findDirectExpressions(Expressions.SQLFieldName)) {\r\n const fieldName = f.concatTokens();\r\n fieldDefinitions += indentation + \" \" + fieldName + \" TYPE \" + tableName + \"-\" + fieldName + \",\\n\";\r\n }\r\n const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const name = ((_c = inlineData.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || \"error\";\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `TYPES: BEGIN OF ${uniqueName},\r\n${fieldDefinitions}${indentation} END OF ${uniqueName}.\r\n${indentation}DATA ${name} TYPE STANDARD TABLE OF ${uniqueName} WITH DEFAULT KEY.\r\n${indentation}`);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, inlineData.getFirstToken(), \"Outline SELECT @DATA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n replaceTableExpression(node, lowFile, highSyntax) {\r\n var _a;\r\n for (const fieldChain of node.findAllExpressionsRecursive(Expressions.FieldChain)) {\r\n const tableExpression = fieldChain.findDirectExpression(Expressions.TableExpression);\r\n if (tableExpression === undefined) {\r\n continue;\r\n }\r\n if (tableExpression.getChildren().length > 3) {\r\n // for now, only support the INDEX scenario\r\n continue;\r\n }\r\n let pre = \"\";\r\n let startToken = undefined;\r\n for (const child of fieldChain.getChildren()) {\r\n if (startToken === undefined) {\r\n startToken = child.getFirstToken();\r\n }\r\n else if (child === tableExpression) {\r\n break;\r\n }\r\n pre += child.concatTokens();\r\n }\r\n if (startToken === undefined) {\r\n continue;\r\n }\r\n const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const firstToken = node.getFirstToken();\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.\r\n${indentation}READ TABLE ${pre} INDEX ${(_a = tableExpression.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens()} INTO ${uniqueName}.\r\n${indentation}IF sy-subrc <> 0.\r\n${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.\r\n${indentation}ENDIF.\r\n${indentation}`);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, startToken.getStart(), tableExpression.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline table expression\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineDataSimple(node, lowFile) {\r\n // outlines \"DATA(ls_msg) = temp1.\", note that this does not need to look at types\r\n var _a, _b, _c;\r\n if (!(node.get() instanceof Statements.Move)) {\r\n return undefined;\r\n }\r\n const target = node.findFirstExpression(Expressions.Target);\r\n if (!(((_a = target === null || target === void 0 ? void 0 : target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.InlineData)) {\r\n return undefined;\r\n }\r\n const source = node.findFirstExpression(Expressions.Source);\r\n if (source === undefined) {\r\n return undefined;\r\n }\r\n else if (source.getChildren().length !== 1) {\r\n return undefined;\r\n }\r\n else if (!(((_b = source.getFirstChild()) === null || _b === void 0 ? void 0 : _b.get()) instanceof Expressions.FieldChain)) {\r\n return undefined;\r\n }\r\n else if (source.findFirstExpression(Expressions.FieldOffset)) {\r\n return undefined;\r\n }\r\n else if (source.findFirstExpression(Expressions.FieldLength)) {\r\n return undefined;\r\n }\r\n const targetName = (_c = target.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens();\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const firstToken = node.getFirstToken();\r\n const lastToken = node.getLastToken();\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${targetName} LIKE ${source.concatTokens()}.\\n${indentation}`);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), lastToken.getEnd(), `${targetName} = ${source.concatTokens()}.`);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline DATA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n emptyKey(node, lowFile) {\r\n for (let i of node.findAllExpressions(Expressions.TypeTable)) {\r\n const key = i.findDirectExpression(Expressions.TypeTableKey);\r\n if (key === undefined) {\r\n continue;\r\n }\r\n i = key;\r\n const concat = i.concatTokens();\r\n if (concat.toUpperCase().includes(\"WITH EMPTY KEY\") === false) {\r\n continue;\r\n }\r\n const token = i.findDirectTokenByText(\"EMPTY\");\r\n if (token === undefined) {\r\n continue;\r\n }\r\n const fix = edit_helper_1.EditHelper.replaceToken(lowFile, token, \"DEFAULT\");\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Downport EMPTY KEY\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n // must be very simple string templates, like \"|{ ls_line-no ALPHA = IN }|\"\r\n stringTemplateAlpha(node, lowFile) {\r\n var _a, _b, _c;\r\n if (!(node.get() instanceof Statements.Move)) {\r\n return undefined;\r\n }\r\n const topSource = node.findDirectExpression(Expressions.Source);\r\n if (topSource === undefined || topSource.getChildren().length !== 1) {\r\n return undefined;\r\n }\r\n const child = topSource.getFirstChild();\r\n if (!(child.get() instanceof Expressions.StringTemplate)) {\r\n return undefined;\r\n }\r\n const templateTokens = child.getChildren();\r\n if (templateTokens.length !== 3\r\n || templateTokens[0].getFirstToken().getStr() !== \"|{\"\r\n || templateTokens[2].getFirstToken().getStr() !== \"}|\") {\r\n return undefined;\r\n }\r\n const templateSource = child.findDirectExpression(Expressions.StringTemplateSource);\r\n const formatting = (_a = templateSource === null || templateSource === void 0 ? void 0 : templateSource.findDirectExpression(Expressions.StringTemplateFormatting)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n let functionName = \"\";\r\n switch (formatting) {\r\n case \"ALPHA = IN\":\r\n functionName = \"CONVERSION_EXIT_ALPHA_INPUT\";\r\n break;\r\n case \"ALPHA = OUT\":\r\n functionName = \"CONVERSION_EXIT_ALPHA_OUTPUT\";\r\n break;\r\n default:\r\n return undefined;\r\n }\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const source = (_b = templateSource === null || templateSource === void 0 ? void 0 : templateSource.findDirectExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n const topTarget = (_c = node.findDirectExpression(Expressions.Target)) === null || _c === void 0 ? void 0 : _c.concatTokens();\r\n const code = `CALL FUNCTION '${functionName}'\r\n${indentation} EXPORTING\r\n${indentation} input = ${source}\r\n${indentation} IMPORTING\r\n${indentation} output = ${topTarget}.`;\r\n const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), code);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Downport ALPHA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n outlineLoopInput(node, lowFile, highSyntax) {\r\n if (!(node.get() instanceof Statements.Loop)) {\r\n return undefined;\r\n }\r\n else if (node.findDirectExpression(Expressions.SimpleSource2)) {\r\n return undefined;\r\n }\r\n // the first Source must be outlined\r\n const s = node.findDirectExpression(Expressions.Source);\r\n if (s === undefined) {\r\n return undefined;\r\n }\r\n const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const code = `DATA(${uniqueName}) = ${s.concatTokens()}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, s.getFirstToken().getStart(), s.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline LOOP input\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n outlineLoopTarget(node, lowFile, _highSyntax) {\r\n var _a, _b, _c, _d, _e;\r\n // also allows outlining of voided types\r\n if (!(node.get() instanceof Statements.Loop)) {\r\n return undefined;\r\n }\r\n const sourceName = (_a = node.findDirectExpression(Expressions.SimpleSource2)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n if (sourceName === undefined) {\r\n return undefined;\r\n }\r\n const concat = node.concatTokens();\r\n if (concat.includes(\" REFERENCE INTO \")) {\r\n return undefined;\r\n }\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const dataTarget = (_b = node.findDirectExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.findDirectExpression(Expressions.InlineData);\r\n if (dataTarget) {\r\n const targetName = ((_c = dataTarget.findDirectExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || \"DOWNPORT_ERROR\";\r\n const code = `DATA ${targetName} LIKE LINE OF ${sourceName}.\\n${indentation}`;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, dataTarget.getFirstToken().getStart(), dataTarget.getLastToken().getEnd(), targetName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline LOOP data target\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n const fsTarget = (_d = node.findDirectExpression(Expressions.FSTarget)) === null || _d === void 0 ? void 0 : _d.findDirectExpression(Expressions.InlineFS);\r\n if (fsTarget) {\r\n const targetName = ((_e = fsTarget.findDirectExpression(Expressions.TargetFieldSymbol)) === null || _e === void 0 ? void 0 : _e.concatTokens()) || \"DOWNPORT_ERROR\";\r\n const code = `FIELD-SYMBOLS ${targetName} LIKE LINE OF ${sourceName}.\\n${indentation}`;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, fsTarget.getFirstToken().getStart(), fsTarget.getLastToken().getEnd(), targetName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline LOOP fs target\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineReduce(node, lowFile, highSyntax) {\r\n var _a, _b, _c, _d;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {\r\n const firstToken = i.getFirstToken();\r\n if (firstToken.getStr().toUpperCase() !== \"REDUCE\") {\r\n continue;\r\n }\r\n const type = this.findType(i, lowFile, highSyntax);\r\n if (type === undefined) {\r\n continue;\r\n }\r\n const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n let body = \"\";\r\n let name = \"\";\r\n const reduceBody = i.findDirectExpression(Expressions.ReduceBody);\r\n if (reduceBody === undefined) {\r\n continue;\r\n }\r\n for (const init of reduceBody.findDirectExpressions(Expressions.InlineFieldDefinition)) {\r\n name = init.getFirstToken().getStr();\r\n body += indentation + `DATA(${name}) = ${(_a = reduceBody.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens()}.\\n`;\r\n }\r\n const loop = reduceBody.findFirstExpression(Expressions.InlineLoopDefinition);\r\n if (loop === undefined) {\r\n continue;\r\n }\r\n const loopSource = (_b = loop.findFirstExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n const loopTargetField = (_c = loop.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens();\r\n if (loopTargetField) {\r\n body += indentation + `LOOP AT ${loopSource} INTO DATA(${loopTargetField}).\\n`;\r\n }\r\n if (loopTargetField === undefined) {\r\n const loopTargetFieldSymbol = (_d = loop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _d === void 0 ? void 0 : _d.concatTokens();\r\n body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol}).\\n`;\r\n }\r\n const next = reduceBody.findDirectExpression(Expressions.ReduceNext);\r\n if (next === undefined) {\r\n continue;\r\n }\r\n for (const n of next.getChildren()) {\r\n if (n.concatTokens().toUpperCase() === \"NEXT\") {\r\n continue;\r\n }\r\n else if (n.concatTokens() === \"=\") {\r\n body += \" = \";\r\n }\r\n else if (n.get() instanceof Expressions.Field) {\r\n body += indentation + \" \" + n.concatTokens();\r\n }\r\n else if (n.get() instanceof Expressions.Source) {\r\n body += n.concatTokens() + \".\\n\";\r\n }\r\n }\r\n body += indentation + `ENDLOOP.\\n`;\r\n body += indentation + `${uniqueName} = ${name}.\\n`;\r\n const abap = `DATA ${uniqueName} TYPE ${type}.\\n` +\r\n body +\r\n indentation;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, firstToken, \"Downport REDUCE\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineValue(node, lowFile, highSyntax) {\r\n var _a, _b;\r\n const allSources = node.findAllExpressionsRecursive(Expressions.Source);\r\n for (const i of allSources) {\r\n const firstToken = i.getFirstToken();\r\n if (firstToken.getStr().toUpperCase() !== \"VALUE\") {\r\n continue;\r\n }\r\n const type = this.findType(i, lowFile, highSyntax);\r\n if (type === undefined) {\r\n continue;\r\n }\r\n const valueBody = i.findDirectExpression(Expressions.ValueBody);\r\n const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);\r\n let indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n let body = \"\";\r\n const loop = valueBody === null || valueBody === void 0 ? void 0 : valueBody.findFirstExpression(Expressions.InlineLoopDefinition);\r\n if (loop) {\r\n const loopSource = (_a = loop.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n const loopTargetFieldSymbol = (_b = loop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol}).\\n`;\r\n indentation += \" \";\r\n }\r\n let structureName = uniqueName;\r\n let added = false;\r\n let data = \"\";\r\n for (const b of (valueBody === null || valueBody === void 0 ? void 0 : valueBody.getChildren()) || []) {\r\n if (b.concatTokens() === \"(\" && added === false) {\r\n structureName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);\r\n data = indentation + `DATA ${structureName} LIKE LINE OF ${uniqueName}.\\n`;\r\n }\r\n if (b.get() instanceof Expressions.FieldAssignment) {\r\n if (added === false) {\r\n body += data;\r\n added = true;\r\n }\r\n body += indentation + structureName + \"-\" + b.concatTokens() + \".\\n\";\r\n }\r\n else if (b.get() instanceof Expressions.Source) {\r\n structureName = b.concatTokens();\r\n }\r\n else if (b instanceof nodes_1.ExpressionNode && b.get() instanceof Expressions.Let) {\r\n body += this.outlineLet(b, indentation, highSyntax, lowFile);\r\n }\r\n else if (b.concatTokens() === \")\") {\r\n body += indentation + `APPEND ${structureName} TO ${uniqueName}.\\n`;\r\n }\r\n }\r\n if (loop) {\r\n indentation = indentation.substr(2);\r\n body += indentation + `ENDLOOP.\\n`;\r\n }\r\n const abap = `DATA ${uniqueName} TYPE ${type}.\\n` +\r\n body +\r\n indentation;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, firstToken, \"Downport VALUE\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineLet(node, indentation, highSyntax, lowFile) {\r\n var _a;\r\n let ret = \"\";\r\n for (const f of node.findDirectExpressions(Expressions.InlineFieldDefinition)) {\r\n const c = f.getFirstChild();\r\n if (c === undefined) {\r\n continue;\r\n }\r\n const name = c.concatTokens().toLowerCase();\r\n const spag = highSyntax.spaghetti.lookupPosition(c.getFirstToken().getStart(), lowFile.getFilename());\r\n if (spag === undefined) {\r\n continue;\r\n }\r\n const found = spag.findVariable(name);\r\n if (found === undefined) {\r\n continue;\r\n }\r\n const type = found.getType().getQualifiedName() ? (_a = found.getType().getQualifiedName()) === null || _a === void 0 ? void 0 : _a.toLowerCase() : found.getType().toABAP();\r\n ret += indentation + \"DATA \" + name + ` TYPE ${type}.\\n`;\r\n const source = f.findFirstExpression(Expressions.Source);\r\n if (source) {\r\n ret += indentation + name + ` = ${source.concatTokens()}.\\n`;\r\n }\r\n }\r\n return ret;\r\n }\r\n findType(i, lowFile, highSyntax) {\r\n var _a;\r\n const expr = i.findDirectExpression(Expressions.TypeNameOrInfer);\r\n if (expr === undefined) {\r\n return undefined;\r\n }\r\n const firstToken = expr.getFirstToken();\r\n const concat = expr.concatTokens().toLowerCase();\r\n if (concat !== \"#\") {\r\n return concat;\r\n }\r\n const spag = highSyntax.spaghetti.lookupPosition(firstToken.getStart(), lowFile.getFilename());\r\n if (spag === undefined) {\r\n return undefined;\r\n }\r\n let inferred = undefined;\r\n for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {\r\n if (r.referenceType === _reference_1.ReferenceType.InferredType\r\n && r.resolved\r\n && r.position.getStart().equals(firstToken.getStart())\r\n && r.resolved instanceof _typed_identifier_1.TypedIdentifier) {\r\n inferred = r.resolved;\r\n break;\r\n }\r\n }\r\n if (inferred === undefined) {\r\n return undefined;\r\n }\r\n return (_a = inferred.getType().getQualifiedName()) === null || _a === void 0 ? void 0 : _a.toLowerCase();\r\n }\r\n outlineFS(node, lowFile, highSyntax) {\r\n var _a, _b;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.InlineFS)) {\r\n const nameToken = (_a = i.findDirectExpression(Expressions.TargetFieldSymbol)) === null || _a === void 0 ? void 0 : _a.getFirstToken();\r\n if (nameToken === undefined) {\r\n continue;\r\n }\r\n const name = nameToken.getStr();\r\n const spag = highSyntax.spaghetti.lookupPosition(nameToken.getStart(), lowFile.getFilename());\r\n if (spag === undefined) {\r\n continue;\r\n }\r\n const found = spag.findVariable(name);\r\n if (found === undefined) {\r\n continue;\r\n }\r\n else if (found.getType() instanceof basic_1.VoidType) {\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Error outlining voided type\", this.getMetadata().key, this.conf.severity);\r\n }\r\n const type = found.getType().getQualifiedName() ? (_b = found.getType().getQualifiedName()) === null || _b === void 0 ? void 0 : _b.toLowerCase() : found.getType().toABAP();\r\n const code = `FIELD-SYMBOLS ${name} TYPE ${type}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), name);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Outline FIELD-SYMBOL\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineData(node, lowFile, highSyntax) {\r\n var _a, _b;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.InlineData)) {\r\n const nameToken = (_a = i.findDirectExpression(Expressions.TargetField)) === null || _a === void 0 ? void 0 : _a.getFirstToken();\r\n if (nameToken === undefined) {\r\n continue;\r\n }\r\n const name = nameToken.getStr();\r\n const spag = highSyntax.spaghetti.lookupPosition(nameToken.getStart(), lowFile.getFilename());\r\n if (spag === undefined) {\r\n continue;\r\n }\r\n const found = spag.findVariable(name);\r\n if (found === undefined) {\r\n continue;\r\n }\r\n else if (found.getType() instanceof basic_1.VoidType) {\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Error outlining voided type\", this.getMetadata().key, this.conf.severity);\r\n }\r\n const type = found.getType().getQualifiedName() ? (_b = found.getType().getQualifiedName()) === null || _b === void 0 ? void 0 : _b.toLowerCase() : found.getType().toABAP();\r\n const code = `DATA ${name} TYPE ${type}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), name);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Outline DATA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineCond(node, lowFile, highSyntax) {\r\n for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {\r\n if (i.getFirstToken().getStr().toUpperCase() !== \"COND\") {\r\n continue;\r\n }\r\n const body = i.findDirectExpression(Expressions.CondBody);\r\n if (body === undefined) {\r\n continue;\r\n }\r\n const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const type = this.findType(i, lowFile, highSyntax);\r\n const indent = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const bodyCode = this.buildCondBody(body, uniqueName, indent);\r\n const abap = `DATA ${uniqueName} TYPE ${type}.\\n` + bodyCode;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Downport COND\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n buildCondBody(body, uniqueName, indent) {\r\n let code = indent;\r\n for (const c of body.getChildren()) {\r\n if (c instanceof nodes_1.TokenNode) {\r\n switch (c.getFirstToken().getStr().toUpperCase()) {\r\n case \"WHEN\":\r\n code += \"IF \";\r\n break;\r\n case \"THEN\":\r\n code += \".\\n\";\r\n break;\r\n case \"ELSE\":\r\n code += indent + \"ELSE.\\n\";\r\n break;\r\n default:\r\n throw \"buildCondBody, unexpected token\";\r\n }\r\n }\r\n else if (c.get() instanceof Expressions.Cond) {\r\n code += c.concatTokens();\r\n }\r\n else if (c.get() instanceof Expressions.Source) {\r\n code += indent + \" \" + uniqueName + \" = \" + c.concatTokens() + \".\\n\";\r\n }\r\n else {\r\n throw \"buildCondBody, unexpected expression\";\r\n }\r\n }\r\n code += indent + \"ENDIF.\\n\";\r\n code += indent;\r\n return code;\r\n }\r\n outlineConv(node, lowFile, highSyntax) {\r\n var _a;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {\r\n if (i.getFirstToken().getStr().toUpperCase() !== \"CONV\") {\r\n continue;\r\n }\r\n const body = (_a = i.findDirectExpression(Expressions.ConvBody)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n if (body === undefined) {\r\n continue;\r\n }\r\n const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const type = this.findType(i, lowFile, highSyntax);\r\n const indent = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const abap = `DATA ${uniqueName} TYPE ${type}.\\n` +\r\n indent + `${uniqueName} = ${body}.\\n` +\r\n indent;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Downport CONV\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n // \"CAST\" to \"?=\"\r\n outlineCast(node, lowFile, highSyntax) {\r\n var _a;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.Cast)) {\r\n const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const type = this.findType(i, lowFile, highSyntax);\r\n const body = (_a = i.findDirectExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n const abap = `DATA ${uniqueName} TYPE REF TO ${type}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1) +\r\n `${uniqueName} ?= ${body}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Downport CAST\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n uniqueName(position, filename, highSyntax) {\r\n const spag = highSyntax.spaghetti.lookupPosition(position, filename);\r\n if (spag === undefined) {\r\n return \"uniqueErrorSpag\";\r\n }\r\n while (true) {\r\n const name = \"temp\" + this.counter;\r\n const found = spag.findVariable(name);\r\n this.counter++;\r\n if (found === undefined) {\r\n return name;\r\n }\r\n }\r\n }\r\n replaceXsdBool(node, lowFile, highSyntax) {\r\n const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());\r\n for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {\r\n if (r.referenceType === _reference_1.ReferenceType.BuiltinMethodReference\r\n && r.position.getName().toUpperCase() === \"XSDBOOL\") {\r\n const token = r.position.getToken();\r\n const fix = edit_helper_1.EditHelper.replaceRange(lowFile, token.getStart(), token.getEnd(), \"boolc\");\r\n return issue_1.Issue.atToken(lowFile, token, \"Use BOOLC\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n }\r\n return undefined;\r\n }\r\n newToCreateObject(node, lowFile, highSyntax) {\r\n const source = node.findDirectExpression(Expressions.Source);\r\n let fix = undefined;\r\n if (node.get() instanceof Statements.Move\r\n && source\r\n && source.getFirstToken().getStr().toUpperCase() === \"NEW\") {\r\n const target = node.findDirectExpression(Expressions.Target);\r\n const found = source === null || source === void 0 ? void 0 : source.findFirstExpression(Expressions.NewObject);\r\n // must be at top level of the source for quickfix to work(todo: handle more scenarios)\r\n // todo, assumption: the target is not an inline definition\r\n if (target && found && source.concatTokens() === found.concatTokens()) {\r\n const abap = this.newParameters(found, target.concatTokens(), highSyntax, lowFile);\r\n if (abap !== undefined) {\r\n fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), abap);\r\n }\r\n }\r\n }\r\n if (fix === undefined && node.findAllExpressions(Expressions.NewObject)) {\r\n const found = node.findFirstExpression(Expressions.NewObject);\r\n if (found === undefined) {\r\n return undefined;\r\n }\r\n const name = this.uniqueName(found.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const abap = this.newParameters(found, name, highSyntax, lowFile);\r\n if (abap === undefined) {\r\n return undefined;\r\n }\r\n const type = this.findType(found, lowFile, highSyntax);\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const data = `DATA ${name} TYPE REF TO ${type}.\\n` +\r\n indentation + abap + \"\\n\" +\r\n indentation;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), data);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, found.getFirstToken().getStart(), found.getLastToken().getEnd(), name);\r\n fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n }\r\n if (fix) {\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Use CREATE OBJECT instead of NEW\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n else {\r\n return undefined;\r\n }\r\n }\r\n newParameters(found, name, highSyntax, lowFile) {\r\n var _a, _b, _c;\r\n const typeToken = (_a = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _a === void 0 ? void 0 : _a.getFirstToken();\r\n let extra = (typeToken === null || typeToken === void 0 ? void 0 : typeToken.getStr()) === \"#\" ? \"\" : \" TYPE \" + (typeToken === null || typeToken === void 0 ? void 0 : typeToken.getStr());\r\n const parameters = found.findFirstExpression(Expressions.ParameterListS);\r\n if (parameters) {\r\n extra = parameters ? extra + \" EXPORTING \" + parameters.concatTokens() : extra;\r\n }\r\n else if (typeToken) {\r\n const source = (_b = found.findDirectExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n if (source) {\r\n // find the default parameter name for the constructor\r\n const spag = highSyntax.spaghetti.lookupPosition(typeToken === null || typeToken === void 0 ? void 0 : typeToken.getStart(), lowFile.getFilename());\r\n let cdef = undefined;\r\n for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {\r\n if ((r.referenceType === _reference_1.ReferenceType.InferredType\r\n || r.referenceType === _reference_1.ReferenceType.ObjectOrientedReference)\r\n && r.resolved && r.position.getStart().equals(typeToken.getStart())) {\r\n cdef = r.resolved;\r\n }\r\n }\r\n if (cdef && cdef.getMethodDefinitions === undefined) {\r\n return undefined; // something wrong\r\n }\r\n const importing = (_c = cdef === null || cdef === void 0 ? void 0 : cdef.getMethodDefinitions().getByName(\"CONSTRUCTOR\")) === null || _c === void 0 ? void 0 : _c.getParameters().getDefaultImporting();\r\n if (importing) {\r\n extra += \" EXPORTING \" + importing + \" = \" + source;\r\n }\r\n else if (spag === undefined) {\r\n extra += \" SpagUndefined\";\r\n }\r\n else if (cdef === undefined) {\r\n extra += \" ClassDefinitionNotFound\";\r\n }\r\n else {\r\n extra += \" SomeError\";\r\n }\r\n }\r\n }\r\n const abap = `CREATE OBJECT ${name}${extra}.`;\r\n return abap;\r\n }\r\n}\r\nexports.Downport = Downport;\r\n//# sourceMappingURL=downport.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/rules/downport.js?");
11580
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.Downport = exports.DownportConf = void 0;\r\nconst _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ \"./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js\");\r\nconst issue_1 = __webpack_require__(/*! ../issue */ \"./node_modules/@abaplint/core/build/src/issue.js\");\r\nconst _irule_1 = __webpack_require__(/*! ./_irule */ \"./node_modules/@abaplint/core/build/src/rules/_irule.js\");\r\nconst _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js\");\r\nconst nodes_1 = __webpack_require__(/*! ../abap/nodes */ \"./node_modules/@abaplint/core/build/src/abap/nodes/index.js\");\r\nconst Statements = __webpack_require__(/*! ../abap/2_statements/statements */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js\");\r\nconst Expressions = __webpack_require__(/*! ../abap/2_statements/expressions */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js\");\r\nconst edit_helper_1 = __webpack_require__(/*! ../edit_helper */ \"./node_modules/@abaplint/core/build/src/edit_helper.js\");\r\nconst position_1 = __webpack_require__(/*! ../position */ \"./node_modules/@abaplint/core/build/src/position.js\");\r\nconst _abap_object_1 = __webpack_require__(/*! ../objects/_abap_object */ \"./node_modules/@abaplint/core/build/src/objects/_abap_object.js\");\r\nconst version_1 = __webpack_require__(/*! ../version */ \"./node_modules/@abaplint/core/build/src/version.js\");\r\nconst registry_1 = __webpack_require__(/*! ../registry */ \"./node_modules/@abaplint/core/build/src/registry.js\");\r\nconst syntax_1 = __webpack_require__(/*! ../abap/5_syntax/syntax */ \"./node_modules/@abaplint/core/build/src/abap/5_syntax/syntax.js\");\r\nconst _reference_1 = __webpack_require__(/*! ../abap/5_syntax/_reference */ \"./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js\");\r\nconst _typed_identifier_1 = __webpack_require__(/*! ../abap/types/_typed_identifier */ \"./node_modules/@abaplint/core/build/src/abap/types/_typed_identifier.js\");\r\nconst basic_1 = __webpack_require__(/*! ../abap/types/basic */ \"./node_modules/@abaplint/core/build/src/abap/types/basic/index.js\");\r\nconst config_1 = __webpack_require__(/*! ../config */ \"./node_modules/@abaplint/core/build/src/config.js\");\r\nconst tokens_1 = __webpack_require__(/*! ../abap/1_lexer/tokens */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js\");\r\n// todo: refactor each sub-rule to new classes?\r\nclass DownportConf extends _basic_rule_config_1.BasicRuleConfig {\r\n}\r\nexports.DownportConf = DownportConf;\r\nclass Downport {\r\n constructor() {\r\n this.conf = new DownportConf();\r\n }\r\n getMetadata() {\r\n return {\r\n key: \"downport\",\r\n title: \"Downport statement\",\r\n shortDescription: `Experimental downport functionality`,\r\n extendedInformation: `Much like the 'commented_code' rule this rule loops through unknown statements and tries parsing with\r\na higher level language version. If successful, various rules are applied to downport the statement.\r\nTarget downport version is always v702, thus rule is only enabled if target version is v702.\r\n\r\nCurrent rules:\r\n* NEW transformed to CREATE OBJECT, opposite of https://rules.abaplint.org/use_new/\r\n* DATA() definitions are outlined, opposite of https://rules.abaplint.org/prefer_inline/\r\n* FIELD-SYMBOL() definitions are outlined\r\n* CONV is outlined\r\n* COND is outlined\r\n* REDUCE is outlined\r\n* EMPTY KEY is changed to DEFAULT KEY, opposite of DEFAULT KEY in https://rules.abaplint.org/avoid_use/\r\n* CAST changed to ?=\r\n* LOOP AT method_call( ) is outlined\r\n* VALUE # with structure fields\r\n* VALUE # with internal table lines\r\n* Table Expressions[ index ] are outlined\r\n* SELECT INTO @DATA definitions are outlined\r\n* Some occurrences of string template formatting option ALPHA changed to function module call\r\n* SELECT/INSERT/MODIFY/DELETE/UPDATE \",\" in field list removed, \"@\" in source/targets removed\r\n* PARTIALLY IMPLEMENTED removed, it can be quick fixed via rule implement_methods\r\n\r\nOnly one transformation is applied to a statement at a time, so multiple steps might be required to do the full downport.`,\r\n tags: [_irule_1.RuleTag.Experimental, _irule_1.RuleTag.Downport, _irule_1.RuleTag.Quickfix],\r\n };\r\n }\r\n getConfig() {\r\n return this.conf;\r\n }\r\n setConfig(conf) {\r\n this.conf = conf;\r\n }\r\n initialize(reg) {\r\n this.lowReg = reg;\r\n const version = this.lowReg.getConfig().getVersion();\r\n if (version === version_1.Version.v702 || version === version_1.Version.OpenABAP) {\r\n this.initHighReg();\r\n }\r\n return this;\r\n }\r\n run(lowObj) {\r\n const ret = [];\r\n this.counter = 1;\r\n const version = this.lowReg.getConfig().getVersion();\r\n if (version !== version_1.Version.v702 && version !== version_1.Version.OpenABAP) {\r\n return ret;\r\n }\r\n else if (!(lowObj instanceof _abap_object_1.ABAPObject)) {\r\n return ret;\r\n }\r\n const highObj = this.highReg.getObject(lowObj.getType(), lowObj.getName());\r\n if (highObj === undefined || !(highObj instanceof _abap_object_1.ABAPObject)) {\r\n return ret;\r\n }\r\n const highSyntax = new syntax_1.SyntaxLogic(this.highReg, highObj).run();\r\n for (const lowFile of lowObj.getABAPFiles()) {\r\n const highFile = highObj.getABAPFileByName(lowFile.getFilename());\r\n if (highFile === undefined) {\r\n continue;\r\n }\r\n const lowStatements = lowFile.getStatements();\r\n const highStatements = highFile.getStatements();\r\n if (lowStatements.length !== highStatements.length) {\r\n // after applying a fix, there might be more statements in lowFile\r\n // should highReg be initialized again?\r\n /*\r\n const message = \"Internal Error: Statement lengths does not match\";\r\n ret.push(Issue.atStatement(lowFile, lowStatements[0], message, this.getMetadata().key));\r\n */\r\n continue;\r\n }\r\n for (let i = 0; i < lowStatements.length; i++) {\r\n const low = lowStatements[i];\r\n const high = highStatements[i];\r\n if ((low.get() instanceof _statement_1.Unknown && !(high.get() instanceof _statement_1.Unknown))\r\n || high.findFirstExpression(Expressions.InlineData)) {\r\n const issue = this.checkStatement(low, high, lowFile, highSyntax);\r\n if (issue) {\r\n ret.push(issue);\r\n }\r\n }\r\n }\r\n }\r\n return ret;\r\n }\r\n ////////////////////\r\n /** clones the orginal repository into highReg, and parses it with higher language version */\r\n initHighReg() {\r\n // use default configuration, ie. default target version\r\n const highConfig = config_1.Config.getDefault().get();\r\n const lowConfig = this.lowReg.getConfig().get();\r\n highConfig.syntax.errorNamespace = lowConfig.syntax.errorNamespace;\r\n highConfig.syntax.globalConstants = lowConfig.syntax.globalConstants;\r\n highConfig.syntax.globalMacros = lowConfig.syntax.globalMacros;\r\n this.highReg = new registry_1.Registry();\r\n for (const o of this.lowReg.getObjects()) {\r\n for (const f of o.getFiles()) {\r\n if (this.lowReg.isDependency(o) === true) {\r\n this.highReg.addDependency(f);\r\n }\r\n else {\r\n this.highReg.addFile(f);\r\n }\r\n }\r\n }\r\n this.highReg.parse();\r\n }\r\n /** applies one rule at a time, multiple iterations are required to transform complex statements */\r\n checkStatement(low, high, lowFile, highSyntax) {\r\n if (low.getFirstToken().getStart() instanceof position_1.VirtualPosition) {\r\n return undefined;\r\n }\r\n let found = this.partiallyImplemented(high, lowFile);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.emptyKey(high, lowFile);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.stringTemplateAlpha(high, lowFile);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.downportSelectInline(low, high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.downportSQLExtras(low, high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineLoopInput(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineLoopTarget(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineValue(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineReduce(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineCast(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineConv(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineCond(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineDataSimple(high, lowFile);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineData(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.outlineFS(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.newToCreateObject(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.replaceXsdBool(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n // todo, line_exists() should be replaced before this call\r\n found = this.replaceTableExpression(high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n // todo, add more rules here\r\n return undefined;\r\n }\r\n //////////////////////////////////////////\r\n downportSQLExtras(low, high, lowFile, _highSyntax) {\r\n if (!(low.get() instanceof _statement_1.Unknown)) {\r\n return undefined;\r\n }\r\n // todo: update + modify + insert + delete + select loop\r\n if (!(high.get() instanceof Statements.Select)) {\r\n return undefined;\r\n }\r\n let fix = undefined;\r\n const addFix = (token) => {\r\n const add = edit_helper_1.EditHelper.deleteToken(lowFile, token);\r\n if (fix === undefined) {\r\n fix = add;\r\n }\r\n else {\r\n fix = edit_helper_1.EditHelper.merge(fix, add);\r\n }\r\n };\r\n const candidates = [high.findAllExpressionsRecursive(Expressions.SQLTarget),\r\n high.findAllExpressionsRecursive(Expressions.SQLSource),\r\n high.findAllExpressionsRecursive(Expressions.SQLSourceSimple)].flat();\r\n for (const c of candidates) {\r\n if (c.getFirstToken() instanceof tokens_1.WAt) {\r\n addFix(c.getFirstToken());\r\n }\r\n }\r\n for (const fieldList of high.findAllExpressionsRecursive(Expressions.SQLFieldList)) {\r\n for (const token of fieldList.getDirectTokens()) {\r\n if (token.getStr() === \",\") {\r\n addFix(token);\r\n }\r\n }\r\n }\r\n if (fix === undefined) {\r\n return undefined;\r\n }\r\n else {\r\n return issue_1.Issue.atToken(lowFile, low.getFirstToken(), \"SQL, remove \\\" and ,\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n }\r\n downportSelectInline(low, high, lowFile, highSyntax) {\r\n if (!(low.get() instanceof _statement_1.Unknown)\r\n || !(high.get() instanceof Statements.Select)) {\r\n return undefined;\r\n }\r\n // as first step outline the @DATA, note that void types are okay, as long the field names are specified\r\n let found = this.downportSelectSingleInline(low, high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n found = this.downportSelectTableInline(low, high, lowFile, highSyntax);\r\n if (found) {\r\n return found;\r\n }\r\n return undefined;\r\n }\r\n downportSelectSingleInline(_low, high, lowFile, _highSyntax) {\r\n var _a, _b, _c;\r\n const targets = ((_a = high.findFirstExpression(Expressions.SQLIntoStructure)) === null || _a === void 0 ? void 0 : _a.findDirectExpressions(Expressions.SQLTarget)) || [];\r\n if (targets.length !== 1) {\r\n return undefined;\r\n }\r\n const inlineData = targets[0].findFirstExpression(Expressions.InlineData);\r\n if (inlineData === undefined) {\r\n return undefined;\r\n }\r\n const sqlFrom = high.findAllExpressions(Expressions.SQLFromSource);\r\n if (sqlFrom.length !== 1) {\r\n return undefined;\r\n }\r\n const tableName = (_b = sqlFrom[0].findDirectExpression(Expressions.DatabaseTable)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n if (tableName === undefined) {\r\n return undefined;\r\n }\r\n const indentation = \" \".repeat(high.getFirstToken().getStart().getCol() - 1);\r\n const fieldList = high.findFirstExpression(Expressions.SQLFieldList);\r\n if (fieldList === undefined) {\r\n return undefined;\r\n }\r\n let fieldDefinition = \"\";\r\n const fields = fieldList.findDirectExpressions(Expressions.SQLFieldName);\r\n const name = ((_c = inlineData.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || \"error\";\r\n if (fields.length === 1) {\r\n fieldDefinition = `DATA ${name} TYPE ${tableName}-${fields[0].concatTokens()}.`;\r\n }\r\n else {\r\n for (const f of fields) {\r\n const fieldName = f.concatTokens();\r\n fieldDefinition += indentation + \" \" + fieldName + \" TYPE \" + tableName + \"-\" + fieldName + \",\\n\";\r\n }\r\n fieldDefinition = `DATA: BEGIN OF ${name},\r\n${fieldDefinition}${indentation} END OF ${name}.`;\r\n }\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `${fieldDefinition}\r\n${indentation}`);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, inlineData.getFirstToken(), \"Outline SELECT @DATA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n downportSelectTableInline(_low, high, lowFile, highSyntax) {\r\n var _a, _b, _c;\r\n const targets = ((_a = high.findFirstExpression(Expressions.SQLIntoTable)) === null || _a === void 0 ? void 0 : _a.findDirectExpressions(Expressions.SQLTarget)) || [];\r\n if (targets.length !== 1) {\r\n return undefined;\r\n }\r\n const inlineData = targets[0].findFirstExpression(Expressions.InlineData);\r\n if (inlineData === undefined) {\r\n return undefined;\r\n }\r\n const sqlFrom = high.findAllExpressions(Expressions.SQLFromSource);\r\n if (sqlFrom.length !== 1) {\r\n return undefined;\r\n }\r\n const tableName = (_b = sqlFrom[0].findDirectExpression(Expressions.DatabaseTable)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n if (tableName === undefined) {\r\n return undefined;\r\n }\r\n const indentation = \" \".repeat(high.getFirstToken().getStart().getCol() - 1);\r\n const fieldList = high.findFirstExpression(Expressions.SQLFieldList);\r\n if (fieldList === undefined) {\r\n return undefined;\r\n }\r\n let fieldDefinitions = \"\";\r\n for (const f of fieldList.findDirectExpressions(Expressions.SQLFieldName)) {\r\n const fieldName = f.concatTokens();\r\n fieldDefinitions += indentation + \" \" + fieldName + \" TYPE \" + tableName + \"-\" + fieldName + \",\\n\";\r\n }\r\n const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const name = ((_c = inlineData.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || \"error\";\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, high.getStart(), `TYPES: BEGIN OF ${uniqueName},\r\n${fieldDefinitions}${indentation} END OF ${uniqueName}.\r\n${indentation}DATA ${name} TYPE STANDARD TABLE OF ${uniqueName} WITH DEFAULT KEY.\r\n${indentation}`);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inlineData.getFirstToken().getStart(), inlineData.getLastToken().getEnd(), name);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, inlineData.getFirstToken(), \"Outline SELECT @DATA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n replaceTableExpression(node, lowFile, highSyntax) {\r\n var _a;\r\n for (const fieldChain of node.findAllExpressionsRecursive(Expressions.FieldChain)) {\r\n const tableExpression = fieldChain.findDirectExpression(Expressions.TableExpression);\r\n if (tableExpression === undefined) {\r\n continue;\r\n }\r\n if (tableExpression.getChildren().length > 3) {\r\n // for now, only support the INDEX scenario\r\n continue;\r\n }\r\n let pre = \"\";\r\n let startToken = undefined;\r\n for (const child of fieldChain.getChildren()) {\r\n if (startToken === undefined) {\r\n startToken = child.getFirstToken();\r\n }\r\n else if (child === tableExpression) {\r\n break;\r\n }\r\n pre += child.concatTokens();\r\n }\r\n if (startToken === undefined) {\r\n continue;\r\n }\r\n const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const firstToken = node.getFirstToken();\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${uniqueName} LIKE LINE OF ${pre}.\r\n${indentation}READ TABLE ${pre} INDEX ${(_a = tableExpression.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens()} INTO ${uniqueName}.\r\n${indentation}IF sy-subrc <> 0.\r\n${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.\r\n${indentation}ENDIF.\r\n${indentation}`);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, startToken.getStart(), tableExpression.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline table expression\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineDataSimple(node, lowFile) {\r\n // outlines \"DATA(ls_msg) = temp1.\", note that this does not need to look at types\r\n var _a, _b, _c;\r\n if (!(node.get() instanceof Statements.Move)) {\r\n return undefined;\r\n }\r\n const target = node.findFirstExpression(Expressions.Target);\r\n if (!(((_a = target === null || target === void 0 ? void 0 : target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.InlineData)) {\r\n return undefined;\r\n }\r\n const source = node.findFirstExpression(Expressions.Source);\r\n if (source === undefined) {\r\n return undefined;\r\n }\r\n else if (source.getChildren().length !== 1) {\r\n return undefined;\r\n }\r\n else if (!(((_b = source.getFirstChild()) === null || _b === void 0 ? void 0 : _b.get()) instanceof Expressions.FieldChain)) {\r\n return undefined;\r\n }\r\n else if (source.findFirstExpression(Expressions.FieldOffset)) {\r\n return undefined;\r\n }\r\n else if (source.findFirstExpression(Expressions.FieldLength)) {\r\n return undefined;\r\n }\r\n const targetName = (_c = target.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens();\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const firstToken = node.getFirstToken();\r\n const lastToken = node.getLastToken();\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `DATA ${targetName} LIKE ${source.concatTokens()}.\\n${indentation}`);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), lastToken.getEnd(), `${targetName} = ${source.concatTokens()}.`);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline DATA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n partiallyImplemented(node, lowFile) {\r\n if (node.get() instanceof Statements.InterfaceDef) {\r\n const partially = node.findDirectTokenByText(\"PARTIALLY\");\r\n if (partially === undefined) {\r\n return undefined;\r\n }\r\n const implemented = node.findDirectTokenByText(\"IMPLEMENTED\");\r\n if (implemented === undefined) {\r\n return undefined;\r\n }\r\n const fix = edit_helper_1.EditHelper.deleteRange(lowFile, partially.getStart(), implemented.getEnd());\r\n return issue_1.Issue.atToken(lowFile, partially, \"Downport PARTIALLY IMPLEMENTED\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n emptyKey(node, lowFile) {\r\n for (let i of node.findAllExpressions(Expressions.TypeTable)) {\r\n const key = i.findDirectExpression(Expressions.TypeTableKey);\r\n if (key === undefined) {\r\n continue;\r\n }\r\n i = key;\r\n const concat = i.concatTokens();\r\n if (concat.toUpperCase().includes(\"WITH EMPTY KEY\") === false) {\r\n continue;\r\n }\r\n const token = i.findDirectTokenByText(\"EMPTY\");\r\n if (token === undefined) {\r\n continue;\r\n }\r\n const fix = edit_helper_1.EditHelper.replaceToken(lowFile, token, \"DEFAULT\");\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Downport EMPTY KEY\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n // must be very simple string templates, like \"|{ ls_line-no ALPHA = IN }|\"\r\n stringTemplateAlpha(node, lowFile) {\r\n var _a, _b, _c;\r\n if (!(node.get() instanceof Statements.Move)) {\r\n return undefined;\r\n }\r\n const topSource = node.findDirectExpression(Expressions.Source);\r\n if (topSource === undefined || topSource.getChildren().length !== 1) {\r\n return undefined;\r\n }\r\n const child = topSource.getFirstChild();\r\n if (!(child.get() instanceof Expressions.StringTemplate)) {\r\n return undefined;\r\n }\r\n const templateTokens = child.getChildren();\r\n if (templateTokens.length !== 3\r\n || templateTokens[0].getFirstToken().getStr() !== \"|{\"\r\n || templateTokens[2].getFirstToken().getStr() !== \"}|\") {\r\n return undefined;\r\n }\r\n const templateSource = child.findDirectExpression(Expressions.StringTemplateSource);\r\n const formatting = (_a = templateSource === null || templateSource === void 0 ? void 0 : templateSource.findDirectExpression(Expressions.StringTemplateFormatting)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n let functionName = \"\";\r\n switch (formatting) {\r\n case \"ALPHA = IN\":\r\n functionName = \"CONVERSION_EXIT_ALPHA_INPUT\";\r\n break;\r\n case \"ALPHA = OUT\":\r\n functionName = \"CONVERSION_EXIT_ALPHA_OUTPUT\";\r\n break;\r\n default:\r\n return undefined;\r\n }\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const source = (_b = templateSource === null || templateSource === void 0 ? void 0 : templateSource.findDirectExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n const topTarget = (_c = node.findDirectExpression(Expressions.Target)) === null || _c === void 0 ? void 0 : _c.concatTokens();\r\n const code = `CALL FUNCTION '${functionName}'\r\n${indentation} EXPORTING\r\n${indentation} input = ${source}\r\n${indentation} IMPORTING\r\n${indentation} output = ${topTarget}.`;\r\n const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), code);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Downport ALPHA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n outlineLoopInput(node, lowFile, highSyntax) {\r\n if (!(node.get() instanceof Statements.Loop)) {\r\n return undefined;\r\n }\r\n else if (node.findDirectExpression(Expressions.SimpleSource2)) {\r\n return undefined;\r\n }\r\n // the first Source must be outlined\r\n const s = node.findDirectExpression(Expressions.Source);\r\n if (s === undefined) {\r\n return undefined;\r\n }\r\n const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const code = `DATA(${uniqueName}) = ${s.concatTokens()}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, s.getFirstToken().getStart(), s.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline LOOP input\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n outlineLoopTarget(node, lowFile, _highSyntax) {\r\n var _a, _b, _c, _d, _e;\r\n // also allows outlining of voided types\r\n if (!(node.get() instanceof Statements.Loop)) {\r\n return undefined;\r\n }\r\n const sourceName = (_a = node.findDirectExpression(Expressions.SimpleSource2)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n if (sourceName === undefined) {\r\n return undefined;\r\n }\r\n const concat = node.concatTokens();\r\n if (concat.includes(\" REFERENCE INTO \")) {\r\n return undefined;\r\n }\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const dataTarget = (_b = node.findDirectExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.findDirectExpression(Expressions.InlineData);\r\n if (dataTarget) {\r\n const targetName = ((_c = dataTarget.findDirectExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens()) || \"DOWNPORT_ERROR\";\r\n const code = `DATA ${targetName} LIKE LINE OF ${sourceName}.\\n${indentation}`;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, dataTarget.getFirstToken().getStart(), dataTarget.getLastToken().getEnd(), targetName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline LOOP data target\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n const fsTarget = (_d = node.findDirectExpression(Expressions.FSTarget)) === null || _d === void 0 ? void 0 : _d.findDirectExpression(Expressions.InlineFS);\r\n if (fsTarget) {\r\n const targetName = ((_e = fsTarget.findDirectExpression(Expressions.TargetFieldSymbol)) === null || _e === void 0 ? void 0 : _e.concatTokens()) || \"DOWNPORT_ERROR\";\r\n const code = `FIELD-SYMBOLS ${targetName} LIKE LINE OF ${sourceName}.\\n${indentation}`;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, fsTarget.getFirstToken().getStart(), fsTarget.getLastToken().getEnd(), targetName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Outline LOOP fs target\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineReduce(node, lowFile, highSyntax) {\r\n var _a, _b, _c, _d;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {\r\n const firstToken = i.getFirstToken();\r\n if (firstToken.getStr().toUpperCase() !== \"REDUCE\") {\r\n continue;\r\n }\r\n const type = this.findType(i, lowFile, highSyntax);\r\n if (type === undefined) {\r\n continue;\r\n }\r\n const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n let body = \"\";\r\n let name = \"\";\r\n const reduceBody = i.findDirectExpression(Expressions.ReduceBody);\r\n if (reduceBody === undefined) {\r\n continue;\r\n }\r\n for (const init of reduceBody.findDirectExpressions(Expressions.InlineFieldDefinition)) {\r\n name = init.getFirstToken().getStr();\r\n body += indentation + `DATA(${name}) = ${(_a = reduceBody.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens()}.\\n`;\r\n }\r\n const loop = reduceBody.findFirstExpression(Expressions.InlineLoopDefinition);\r\n if (loop === undefined) {\r\n continue;\r\n }\r\n const loopSource = (_b = loop.findFirstExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n const loopTargetField = (_c = loop.findFirstExpression(Expressions.TargetField)) === null || _c === void 0 ? void 0 : _c.concatTokens();\r\n if (loopTargetField) {\r\n body += indentation + `LOOP AT ${loopSource} INTO DATA(${loopTargetField}).\\n`;\r\n }\r\n if (loopTargetField === undefined) {\r\n const loopTargetFieldSymbol = (_d = loop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _d === void 0 ? void 0 : _d.concatTokens();\r\n body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol}).\\n`;\r\n }\r\n const next = reduceBody.findDirectExpression(Expressions.ReduceNext);\r\n if (next === undefined) {\r\n continue;\r\n }\r\n for (const n of next.getChildren()) {\r\n if (n.concatTokens().toUpperCase() === \"NEXT\") {\r\n continue;\r\n }\r\n else if (n.concatTokens() === \"=\") {\r\n body += \" = \";\r\n }\r\n else if (n.get() instanceof Expressions.Field) {\r\n body += indentation + \" \" + n.concatTokens();\r\n }\r\n else if (n.get() instanceof Expressions.Source) {\r\n body += n.concatTokens() + \".\\n\";\r\n }\r\n }\r\n body += indentation + `ENDLOOP.\\n`;\r\n body += indentation + `${uniqueName} = ${name}.\\n`;\r\n const abap = `DATA ${uniqueName} TYPE ${type}.\\n` +\r\n body +\r\n indentation;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, firstToken, \"Downport REDUCE\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineValue(node, lowFile, highSyntax) {\r\n var _a, _b;\r\n const allSources = node.findAllExpressionsRecursive(Expressions.Source);\r\n for (const i of allSources) {\r\n const firstToken = i.getFirstToken();\r\n if (firstToken.getStr().toUpperCase() !== \"VALUE\") {\r\n continue;\r\n }\r\n const type = this.findType(i, lowFile, highSyntax);\r\n if (type === undefined) {\r\n continue;\r\n }\r\n const valueBody = i.findDirectExpression(Expressions.ValueBody);\r\n const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);\r\n let indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n let body = \"\";\r\n const loop = valueBody === null || valueBody === void 0 ? void 0 : valueBody.findFirstExpression(Expressions.InlineLoopDefinition);\r\n if (loop) {\r\n const loopSource = (_a = loop.findFirstExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n const loopTargetFieldSymbol = (_b = loop.findFirstExpression(Expressions.TargetFieldSymbol)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n body += indentation + `LOOP AT ${loopSource} ASSIGNING FIELD-SYMBOL(${loopTargetFieldSymbol}).\\n`;\r\n indentation += \" \";\r\n }\r\n let structureName = uniqueName;\r\n let added = false;\r\n let data = \"\";\r\n for (const b of (valueBody === null || valueBody === void 0 ? void 0 : valueBody.getChildren()) || []) {\r\n if (b.concatTokens() === \"(\" && added === false) {\r\n structureName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);\r\n data = indentation + `DATA ${structureName} LIKE LINE OF ${uniqueName}.\\n`;\r\n }\r\n if (b.get() instanceof Expressions.FieldAssignment) {\r\n if (added === false) {\r\n body += data;\r\n added = true;\r\n }\r\n body += indentation + structureName + \"-\" + b.concatTokens() + \".\\n\";\r\n }\r\n else if (b.get() instanceof Expressions.Source) {\r\n structureName = b.concatTokens();\r\n }\r\n else if (b instanceof nodes_1.ExpressionNode && b.get() instanceof Expressions.Let) {\r\n body += this.outlineLet(b, indentation, highSyntax, lowFile);\r\n }\r\n else if (b.concatTokens() === \")\") {\r\n body += indentation + `APPEND ${structureName} TO ${uniqueName}.\\n`;\r\n }\r\n }\r\n if (loop) {\r\n indentation = indentation.substr(2);\r\n body += indentation + `ENDLOOP.\\n`;\r\n }\r\n const abap = `DATA ${uniqueName} TYPE ${type}.\\n` +\r\n body +\r\n indentation;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, firstToken, \"Downport VALUE\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineLet(node, indentation, highSyntax, lowFile) {\r\n var _a;\r\n let ret = \"\";\r\n for (const f of node.findDirectExpressions(Expressions.InlineFieldDefinition)) {\r\n const c = f.getFirstChild();\r\n if (c === undefined) {\r\n continue;\r\n }\r\n const name = c.concatTokens().toLowerCase();\r\n const spag = highSyntax.spaghetti.lookupPosition(c.getFirstToken().getStart(), lowFile.getFilename());\r\n if (spag === undefined) {\r\n continue;\r\n }\r\n const found = spag.findVariable(name);\r\n if (found === undefined) {\r\n continue;\r\n }\r\n const type = found.getType().getQualifiedName() ? (_a = found.getType().getQualifiedName()) === null || _a === void 0 ? void 0 : _a.toLowerCase() : found.getType().toABAP();\r\n ret += indentation + \"DATA \" + name + ` TYPE ${type}.\\n`;\r\n const source = f.findFirstExpression(Expressions.Source);\r\n if (source) {\r\n ret += indentation + name + ` = ${source.concatTokens()}.\\n`;\r\n }\r\n }\r\n return ret;\r\n }\r\n findType(i, lowFile, highSyntax) {\r\n var _a;\r\n const expr = i.findDirectExpression(Expressions.TypeNameOrInfer);\r\n if (expr === undefined) {\r\n return undefined;\r\n }\r\n const firstToken = expr.getFirstToken();\r\n const concat = expr.concatTokens().toLowerCase();\r\n if (concat !== \"#\") {\r\n return concat;\r\n }\r\n const spag = highSyntax.spaghetti.lookupPosition(firstToken.getStart(), lowFile.getFilename());\r\n if (spag === undefined) {\r\n return undefined;\r\n }\r\n let inferred = undefined;\r\n for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {\r\n if (r.referenceType === _reference_1.ReferenceType.InferredType\r\n && r.resolved\r\n && r.position.getStart().equals(firstToken.getStart())\r\n && r.resolved instanceof _typed_identifier_1.TypedIdentifier) {\r\n inferred = r.resolved;\r\n break;\r\n }\r\n }\r\n if (inferred === undefined) {\r\n return undefined;\r\n }\r\n return (_a = inferred.getType().getQualifiedName()) === null || _a === void 0 ? void 0 : _a.toLowerCase();\r\n }\r\n outlineFS(node, lowFile, highSyntax) {\r\n var _a, _b;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.InlineFS)) {\r\n const nameToken = (_a = i.findDirectExpression(Expressions.TargetFieldSymbol)) === null || _a === void 0 ? void 0 : _a.getFirstToken();\r\n if (nameToken === undefined) {\r\n continue;\r\n }\r\n const name = nameToken.getStr();\r\n const spag = highSyntax.spaghetti.lookupPosition(nameToken.getStart(), lowFile.getFilename());\r\n if (spag === undefined) {\r\n continue;\r\n }\r\n const found = spag.findVariable(name);\r\n if (found === undefined) {\r\n continue;\r\n }\r\n else if (found.getType() instanceof basic_1.VoidType) {\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Error outlining voided type\", this.getMetadata().key, this.conf.severity);\r\n }\r\n const type = found.getType().getQualifiedName() ? (_b = found.getType().getQualifiedName()) === null || _b === void 0 ? void 0 : _b.toLowerCase() : found.getType().toABAP();\r\n const code = `FIELD-SYMBOLS ${name} TYPE ${type}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), name);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Outline FIELD-SYMBOL\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineData(node, lowFile, highSyntax) {\r\n var _a, _b;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.InlineData)) {\r\n const nameToken = (_a = i.findDirectExpression(Expressions.TargetField)) === null || _a === void 0 ? void 0 : _a.getFirstToken();\r\n if (nameToken === undefined) {\r\n continue;\r\n }\r\n const name = nameToken.getStr();\r\n const spag = highSyntax.spaghetti.lookupPosition(nameToken.getStart(), lowFile.getFilename());\r\n if (spag === undefined) {\r\n continue;\r\n }\r\n const found = spag.findVariable(name);\r\n if (found === undefined) {\r\n continue;\r\n }\r\n else if (found.getType() instanceof basic_1.VoidType) {\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Error outlining voided type\", this.getMetadata().key, this.conf.severity);\r\n }\r\n const type = found.getType().getQualifiedName() ? (_b = found.getType().getQualifiedName()) === null || _b === void 0 ? void 0 : _b.toLowerCase() : found.getType().toABAP();\r\n const code = `DATA ${name} TYPE ${type}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), name);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Outline DATA\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n outlineCond(node, lowFile, highSyntax) {\r\n for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {\r\n if (i.getFirstToken().getStr().toUpperCase() !== \"COND\") {\r\n continue;\r\n }\r\n const body = i.findDirectExpression(Expressions.CondBody);\r\n if (body === undefined) {\r\n continue;\r\n }\r\n const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const type = this.findType(i, lowFile, highSyntax);\r\n const indent = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const bodyCode = this.buildCondBody(body, uniqueName, indent);\r\n const abap = `DATA ${uniqueName} TYPE ${type}.\\n` + bodyCode;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Downport COND\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n buildCondBody(body, uniqueName, indent) {\r\n let code = indent;\r\n for (const c of body.getChildren()) {\r\n if (c instanceof nodes_1.TokenNode) {\r\n switch (c.getFirstToken().getStr().toUpperCase()) {\r\n case \"WHEN\":\r\n code += \"IF \";\r\n break;\r\n case \"THEN\":\r\n code += \".\\n\";\r\n break;\r\n case \"ELSE\":\r\n code += indent + \"ELSE.\\n\";\r\n break;\r\n default:\r\n throw \"buildCondBody, unexpected token\";\r\n }\r\n }\r\n else if (c.get() instanceof Expressions.Cond) {\r\n code += c.concatTokens();\r\n }\r\n else if (c.get() instanceof Expressions.Source) {\r\n code += indent + \" \" + uniqueName + \" = \" + c.concatTokens() + \".\\n\";\r\n }\r\n else {\r\n throw \"buildCondBody, unexpected expression\";\r\n }\r\n }\r\n code += indent + \"ENDIF.\\n\";\r\n code += indent;\r\n return code;\r\n }\r\n outlineConv(node, lowFile, highSyntax) {\r\n var _a;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.Source)) {\r\n if (i.getFirstToken().getStr().toUpperCase() !== \"CONV\") {\r\n continue;\r\n }\r\n const body = (_a = i.findDirectExpression(Expressions.ConvBody)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n if (body === undefined) {\r\n continue;\r\n }\r\n const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const type = this.findType(i, lowFile, highSyntax);\r\n const indent = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const abap = `DATA ${uniqueName} TYPE ${type}.\\n` +\r\n indent + `${uniqueName} = ${body}.\\n` +\r\n indent;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Downport CONV\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n // \"CAST\" to \"?=\"\r\n outlineCast(node, lowFile, highSyntax) {\r\n var _a;\r\n for (const i of node.findAllExpressionsRecursive(Expressions.Cast)) {\r\n const uniqueName = this.uniqueName(i.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const type = this.findType(i, lowFile, highSyntax);\r\n const body = (_a = i.findDirectExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n const abap = `DATA ${uniqueName} TYPE REF TO ${type}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1) +\r\n `${uniqueName} ?= ${body}.\\n` +\r\n \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), abap);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, i.getFirstToken().getStart(), i.getLastToken().getEnd(), uniqueName);\r\n const fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n return issue_1.Issue.atToken(lowFile, i.getFirstToken(), \"Downport CAST\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n return undefined;\r\n }\r\n uniqueName(position, filename, highSyntax) {\r\n const spag = highSyntax.spaghetti.lookupPosition(position, filename);\r\n if (spag === undefined) {\r\n return \"uniqueErrorSpag\";\r\n }\r\n while (true) {\r\n const name = \"temp\" + this.counter;\r\n const found = spag.findVariable(name);\r\n this.counter++;\r\n if (found === undefined) {\r\n return name;\r\n }\r\n }\r\n }\r\n replaceXsdBool(node, lowFile, highSyntax) {\r\n const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());\r\n for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {\r\n if (r.referenceType === _reference_1.ReferenceType.BuiltinMethodReference\r\n && r.position.getName().toUpperCase() === \"XSDBOOL\") {\r\n const token = r.position.getToken();\r\n const fix = edit_helper_1.EditHelper.replaceRange(lowFile, token.getStart(), token.getEnd(), \"boolc\");\r\n return issue_1.Issue.atToken(lowFile, token, \"Use BOOLC\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n }\r\n return undefined;\r\n }\r\n newToCreateObject(node, lowFile, highSyntax) {\r\n const source = node.findDirectExpression(Expressions.Source);\r\n let fix = undefined;\r\n if (node.get() instanceof Statements.Move\r\n && source\r\n && source.getFirstToken().getStr().toUpperCase() === \"NEW\") {\r\n const target = node.findDirectExpression(Expressions.Target);\r\n const found = source === null || source === void 0 ? void 0 : source.findFirstExpression(Expressions.NewObject);\r\n // must be at top level of the source for quickfix to work(todo: handle more scenarios)\r\n // todo, assumption: the target is not an inline definition\r\n if (target && found && source.concatTokens() === found.concatTokens()) {\r\n const abap = this.newParameters(found, target.concatTokens(), highSyntax, lowFile);\r\n if (abap !== undefined) {\r\n fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getFirstToken().getStart(), node.getLastToken().getEnd(), abap);\r\n }\r\n }\r\n }\r\n if (fix === undefined && node.findAllExpressions(Expressions.NewObject)) {\r\n const found = node.findFirstExpression(Expressions.NewObject);\r\n if (found === undefined) {\r\n return undefined;\r\n }\r\n const name = this.uniqueName(found.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);\r\n const abap = this.newParameters(found, name, highSyntax, lowFile);\r\n if (abap === undefined) {\r\n return undefined;\r\n }\r\n const type = this.findType(found, lowFile, highSyntax);\r\n const indentation = \" \".repeat(node.getFirstToken().getStart().getCol() - 1);\r\n const data = `DATA ${name} TYPE REF TO ${type}.\\n` +\r\n indentation + abap + \"\\n\" +\r\n indentation;\r\n const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), data);\r\n const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, found.getFirstToken().getStart(), found.getLastToken().getEnd(), name);\r\n fix = edit_helper_1.EditHelper.merge(fix2, fix1);\r\n }\r\n if (fix) {\r\n return issue_1.Issue.atToken(lowFile, node.getFirstToken(), \"Use CREATE OBJECT instead of NEW\", this.getMetadata().key, this.conf.severity, fix);\r\n }\r\n else {\r\n return undefined;\r\n }\r\n }\r\n newParameters(found, name, highSyntax, lowFile) {\r\n var _a, _b, _c;\r\n const typeToken = (_a = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _a === void 0 ? void 0 : _a.getFirstToken();\r\n let extra = (typeToken === null || typeToken === void 0 ? void 0 : typeToken.getStr()) === \"#\" ? \"\" : \" TYPE \" + (typeToken === null || typeToken === void 0 ? void 0 : typeToken.getStr());\r\n const parameters = found.findFirstExpression(Expressions.ParameterListS);\r\n if (parameters) {\r\n extra = parameters ? extra + \" EXPORTING \" + parameters.concatTokens() : extra;\r\n }\r\n else if (typeToken) {\r\n const source = (_b = found.findDirectExpression(Expressions.Source)) === null || _b === void 0 ? void 0 : _b.concatTokens();\r\n if (source) {\r\n // find the default parameter name for the constructor\r\n const spag = highSyntax.spaghetti.lookupPosition(typeToken === null || typeToken === void 0 ? void 0 : typeToken.getStart(), lowFile.getFilename());\r\n let cdef = undefined;\r\n for (const r of (spag === null || spag === void 0 ? void 0 : spag.getData().references) || []) {\r\n if ((r.referenceType === _reference_1.ReferenceType.InferredType\r\n || r.referenceType === _reference_1.ReferenceType.ObjectOrientedReference)\r\n && r.resolved && r.position.getStart().equals(typeToken.getStart())) {\r\n cdef = r.resolved;\r\n }\r\n }\r\n if (cdef && cdef.getMethodDefinitions === undefined) {\r\n return undefined; // something wrong\r\n }\r\n const importing = (_c = cdef === null || cdef === void 0 ? void 0 : cdef.getMethodDefinitions().getByName(\"CONSTRUCTOR\")) === null || _c === void 0 ? void 0 : _c.getParameters().getDefaultImporting();\r\n if (importing) {\r\n extra += \" EXPORTING \" + importing + \" = \" + source;\r\n }\r\n else if (spag === undefined) {\r\n extra += \" SpagUndefined\";\r\n }\r\n else if (cdef === undefined) {\r\n extra += \" ClassDefinitionNotFound\";\r\n }\r\n else {\r\n extra += \" SomeError\";\r\n }\r\n }\r\n }\r\n const abap = `CREATE OBJECT ${name}${extra}.`;\r\n return abap;\r\n }\r\n}\r\nexports.Downport = Downport;\r\n//# sourceMappingURL=downport.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/rules/downport.js?");
11581
11581
 
11582
11582
  /***/ }),
11583
11583
 
@@ -12589,7 +12589,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
12589
12589
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
12590
12590
 
12591
12591
  "use strict";
12592
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.UnnecessaryChaining = exports.UnnecessaryChainingConf = void 0;\r\nconst issue_1 = __webpack_require__(/*! ../issue */ \"./node_modules/@abaplint/core/build/src/issue.js\");\r\nconst _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ \"./node_modules/@abaplint/core/build/src/rules/_abap_rule.js\");\r\nconst _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ \"./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js\");\r\nconst _irule_1 = __webpack_require__(/*! ./_irule */ \"./node_modules/@abaplint/core/build/src/rules/_irule.js\");\r\nconst edit_helper_1 = __webpack_require__(/*! ../edit_helper */ \"./node_modules/@abaplint/core/build/src/edit_helper.js\");\r\nconst _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js\");\r\nclass UnnecessaryChainingConf extends _basic_rule_config_1.BasicRuleConfig {\r\n}\r\nexports.UnnecessaryChainingConf = UnnecessaryChainingConf;\r\nclass UnnecessaryChaining extends _abap_rule_1.ABAPRule {\r\n constructor() {\r\n super(...arguments);\r\n this.conf = new UnnecessaryChainingConf();\r\n }\r\n getMetadata() {\r\n return {\r\n key: \"unnecessary_chaining\",\r\n title: \"Unnecessary Chaining\",\r\n shortDescription: `Find unnecessary chaining, all statements are checked`,\r\n extendedInformation: ``,\r\n tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],\r\n badExample: `WRITE: bar.`,\r\n goodExample: `WRITE bar.`,\r\n };\r\n }\r\n getConfig() {\r\n return this.conf;\r\n }\r\n setConfig(conf) {\r\n this.conf = conf;\r\n }\r\n runParsed(file) {\r\n var _a;\r\n const issues = [];\r\n const statements = file.getStatements();\r\n for (let i = 0; i < statements.length; i++) {\r\n const colon = statements[i].getColon();\r\n if (colon === undefined) {\r\n continue;\r\n }\r\n // find the next non Comment statement\r\n let j = 1;\r\n let nextStatement = statements[i + j];\r\n while ((nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.get()) instanceof _statement_1.Comment) {\r\n j++;\r\n nextStatement = statements[i + j];\r\n }\r\n const next = nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.getColon();\r\n const prev = (_a = statements[i - 1]) === null || _a === void 0 ? void 0 : _a.getColon();\r\n if (next !== undefined && colon.getStart().equals(next.getStart())) {\r\n continue;\r\n }\r\n else if (prev !== undefined && colon.getStart().equals(prev.getStart())) {\r\n continue;\r\n }\r\n const fix = edit_helper_1.EditHelper.deleteRange(file, colon.getStart(), colon.getEnd());\r\n const message = \"Unnecessary chaining\";\r\n const issue = issue_1.Issue.atStatement(file, statements[i], message, this.getMetadata().key, this.conf.severity, fix);\r\n issues.push(issue);\r\n }\r\n return issues;\r\n }\r\n}\r\nexports.UnnecessaryChaining = UnnecessaryChaining;\r\n//# sourceMappingURL=unnecessary_chaining.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/rules/unnecessary_chaining.js?");
12592
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.UnnecessaryChaining = exports.UnnecessaryChainingConf = void 0;\r\nconst issue_1 = __webpack_require__(/*! ../issue */ \"./node_modules/@abaplint/core/build/src/issue.js\");\r\nconst _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ \"./node_modules/@abaplint/core/build/src/rules/_abap_rule.js\");\r\nconst _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ \"./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js\");\r\nconst _irule_1 = __webpack_require__(/*! ./_irule */ \"./node_modules/@abaplint/core/build/src/rules/_irule.js\");\r\nconst edit_helper_1 = __webpack_require__(/*! ../edit_helper */ \"./node_modules/@abaplint/core/build/src/edit_helper.js\");\r\nconst _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js\");\r\nclass UnnecessaryChainingConf extends _basic_rule_config_1.BasicRuleConfig {\r\n}\r\nexports.UnnecessaryChainingConf = UnnecessaryChainingConf;\r\nclass UnnecessaryChaining extends _abap_rule_1.ABAPRule {\r\n constructor() {\r\n super(...arguments);\r\n this.conf = new UnnecessaryChainingConf();\r\n }\r\n getMetadata() {\r\n return {\r\n key: \"unnecessary_chaining\",\r\n title: \"Unnecessary Chaining\",\r\n shortDescription: `Find unnecessary chaining, all statements are checked`,\r\n extendedInformation: ``,\r\n tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Quickfix],\r\n badExample: `WRITE: bar.`,\r\n goodExample: `WRITE bar.`,\r\n };\r\n }\r\n getConfig() {\r\n return this.conf;\r\n }\r\n setConfig(conf) {\r\n this.conf = conf;\r\n }\r\n runParsed(file) {\r\n var _a;\r\n const issues = [];\r\n const statements = file.getStatements();\r\n for (let i = 0; i < statements.length; i++) {\r\n const colon = statements[i].getColon();\r\n if (colon === undefined) {\r\n continue;\r\n }\r\n // find the next non Comment statement\r\n let j = 1;\r\n let nextStatement = statements[i + j];\r\n while ((nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.get()) instanceof _statement_1.Comment) {\r\n j++;\r\n nextStatement = statements[i + j];\r\n }\r\n const next = nextStatement === null || nextStatement === void 0 ? void 0 : nextStatement.getColon();\r\n const prev = (_a = statements[i - 1]) === null || _a === void 0 ? void 0 : _a.getColon();\r\n if (next !== undefined && colon.getStart().equals(next.getStart())) {\r\n continue;\r\n }\r\n else if (prev !== undefined && colon.getStart().equals(prev.getStart())) {\r\n continue;\r\n }\r\n const fix = edit_helper_1.EditHelper.deleteRange(file, colon.getStart(), colon.getEnd());\r\n const message = \"Unnecessary chaining\";\r\n const issue = issue_1.Issue.atToken(file, colon, message, this.getMetadata().key, this.conf.severity, fix);\r\n issues.push(issue);\r\n }\r\n return issues;\r\n }\r\n}\r\nexports.UnnecessaryChaining = UnnecessaryChaining;\r\n//# sourceMappingURL=unnecessary_chaining.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/rules/unnecessary_chaining.js?");
12593
12593
 
12594
12594
  /***/ }),
12595
12595
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.83.10",
3
+ "version": "2.83.14",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "bin": {
6
6
  "abaplint": "./abaplint"
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "homepage": "https://abaplint.org",
41
41
  "devDependencies": {
42
- "@abaplint/core": "^2.83.10",
42
+ "@abaplint/core": "^2.83.14",
43
43
  "@types/chai": "^4.3.0",
44
44
  "@types/glob": "^7.2.0",
45
45
  "@types/minimist": "^1.2.2",
@@ -51,7 +51,7 @@
51
51
  "eslint": "^8.5.0",
52
52
  "glob": "^7.2.0",
53
53
  "json5": "^2.2.0",
54
- "memfs": "^3.4.0",
54
+ "memfs": "^3.4.1",
55
55
  "minimist": "^1.2.5",
56
56
  "mocha": "^9.1.3",
57
57
  "progress": "^2.0.3",