@abaplint/transpiler-cli 2.13.86 → 2.13.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bundle.js +293 -23
- package/package.json +3 -3
package/build/bundle.js
CHANGED
|
@@ -522,6 +522,13 @@ const BUFS = new Set([
|
|
|
522
522
|
CH_DOT, CH_COMMA, CH_COLON, 40 /* ( */, 41 /* ) */, 91 /* [ */,
|
|
523
523
|
93 /* ] */, 43 /* + */, CH_AT
|
|
524
524
|
]);
|
|
525
|
+
// characters that may follow the closing "'", "`" or "|" of a literal, anything else
|
|
526
|
+
// is a syntax error, "There must be a space or equivalent character after ...",
|
|
527
|
+
// note that "(" is allowed, ie. text elements like 'text'(001)
|
|
528
|
+
const AFTER_LITERAL = new Set([
|
|
529
|
+
EOF, CH_SPACE, CH_TAB, CH_NL, CH_DOT, CH_COMMA, CH_COLON, CH_DQUOTE,
|
|
530
|
+
40 /* ( */, 41 /* ) */, 91 /* [ */, 93 /* ] */
|
|
531
|
+
]);
|
|
525
532
|
class Lexer {
|
|
526
533
|
run(file, virtual) {
|
|
527
534
|
this.virtual = virtual;
|
|
@@ -801,7 +808,11 @@ class Lexer {
|
|
|
801
808
|
&& ahead !== CH_BACKTICK
|
|
802
809
|
&& this.buffer.countIsEven(CH_BACKTICK)) {
|
|
803
810
|
// end of ping
|
|
804
|
-
|
|
811
|
+
if (AFTER_LITERAL.has(ahead)) {
|
|
812
|
+
this.add();
|
|
813
|
+
}
|
|
814
|
+
// else: no separator after the literal, keep the buffer so the following
|
|
815
|
+
// characters are glued onto the token, the parser will report the error
|
|
805
816
|
if (ahead === CH_DQUOTE) {
|
|
806
817
|
this.m = ModeComment;
|
|
807
818
|
}
|
|
@@ -814,7 +825,9 @@ class Lexer {
|
|
|
814
825
|
&& (current === CH_PIPE || current === CH_LBRACE)
|
|
815
826
|
&& (stream.prevChar() !== CH_BACKSLASH || (stream.prevPrevChar() === CH_BACKSLASH && stream.prevChar() === CH_BACKSLASH))) {
|
|
816
827
|
// end of template
|
|
817
|
-
|
|
828
|
+
if (current === CH_LBRACE || AFTER_LITERAL.has(ahead)) {
|
|
829
|
+
this.add();
|
|
830
|
+
}
|
|
818
831
|
this.m = ModeNormal;
|
|
819
832
|
}
|
|
820
833
|
else if (this.m === ModeTemplate
|
|
@@ -829,7 +842,9 @@ class Lexer {
|
|
|
829
842
|
&& ahead !== CH_QUOTE
|
|
830
843
|
&& this.buffer.countIsEven(CH_QUOTE)) {
|
|
831
844
|
// end of string
|
|
832
|
-
|
|
845
|
+
if (AFTER_LITERAL.has(ahead)) {
|
|
846
|
+
this.add();
|
|
847
|
+
}
|
|
833
848
|
if (ahead === CH_DQUOTE) {
|
|
834
849
|
this.m = ModeComment;
|
|
835
850
|
}
|
|
@@ -28183,6 +28198,20 @@ class TypeUtils {
|
|
|
28183
28198
|
|| node.findFirstExpression(Expressions.ArithOperator) !== undefined;
|
|
28184
28199
|
return calculated;
|
|
28185
28200
|
}
|
|
28201
|
+
// a character constant is only assignable to a hexadecimal target if it can be
|
|
28202
|
+
// interpreted as a hexadecimal value
|
|
28203
|
+
isHexConstant(node) {
|
|
28204
|
+
const constant = node === null || node === void 0 ? void 0 : node.concatTokens();
|
|
28205
|
+
if (constant === undefined) {
|
|
28206
|
+
return true;
|
|
28207
|
+
}
|
|
28208
|
+
if ((constant.startsWith("'") && constant.endsWith("'"))
|
|
28209
|
+
|| (constant.startsWith("`") && constant.endsWith("`"))) {
|
|
28210
|
+
const value = constant.substring(1, constant.length - 1);
|
|
28211
|
+
return value.length > 0 && /^[0-9A-Fa-f]+$/.test(value);
|
|
28212
|
+
}
|
|
28213
|
+
return true;
|
|
28214
|
+
}
|
|
28186
28215
|
isAssignableNew(source, target, node) {
|
|
28187
28216
|
const calculated = (node === null || node === void 0 ? void 0 : node.findFirstExpression(Expressions.ArithOperator)) !== undefined;
|
|
28188
28217
|
if (calculated && source instanceof basic_1.HexType && target instanceof basic_1.IntegerType) {
|
|
@@ -28248,7 +28277,7 @@ class TypeUtils {
|
|
|
28248
28277
|
}
|
|
28249
28278
|
else if (target instanceof basic_1.XStringType) {
|
|
28250
28279
|
if (((_d = source.getAbstractTypeData()) === null || _d === void 0 ? void 0 : _d.derivedFromConstant) === true) {
|
|
28251
|
-
return (node
|
|
28280
|
+
return this.isHexConstant(node);
|
|
28252
28281
|
}
|
|
28253
28282
|
return false;
|
|
28254
28283
|
}
|
|
@@ -35180,6 +35209,7 @@ class Source {
|
|
|
35180
35209
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
35181
35210
|
}
|
|
35182
35211
|
this.addIfInferred(node, input, foundType);
|
|
35212
|
+
this.traverseRemainingChildren(children, input);
|
|
35183
35213
|
return foundType;
|
|
35184
35214
|
}
|
|
35185
35215
|
case "REF":
|
|
@@ -71018,7 +71048,7 @@ class Registry {
|
|
|
71018
71048
|
}
|
|
71019
71049
|
static abaplintVersion() {
|
|
71020
71050
|
// magic, see build script "version.js"
|
|
71021
|
-
return "2.120.
|
|
71051
|
+
return "2.120.52";
|
|
71022
71052
|
}
|
|
71023
71053
|
getDDICReferences() {
|
|
71024
71054
|
return this.ddicReferences;
|
|
@@ -79155,15 +79185,19 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
|
79155
79185
|
continue;
|
|
79156
79186
|
}
|
|
79157
79187
|
const condition = this.tableCondition(tableExpression);
|
|
79158
|
-
|
|
79188
|
+
// ASSIGNING, not INTO: from v740 a table expression in a read position addresses the
|
|
79189
|
+
// row rather than copying it, so "REF #( tab[ i ]-comp )" and "ASSIGN tab[ i ]-comp"
|
|
79190
|
+
// hand back an address INTO a work area would not preserve. The write path
|
|
79191
|
+
// (moveWithTableTarget) already lowers to ASSIGNING for the same reason.
|
|
79192
|
+
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax, true);
|
|
79159
79193
|
const tabixBackup = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
79160
79194
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
79161
79195
|
const firstToken = high.getFirstToken();
|
|
79162
79196
|
// note that the tabix restore should be done before throwing the exception
|
|
79163
|
-
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `
|
|
79197
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, firstToken.getStart(), `FIELD-SYMBOLS ${uniqueName} LIKE LINE OF ${pre}.
|
|
79164
79198
|
${indentation}DATA ${tabixBackup} LIKE sy-tabix.
|
|
79165
79199
|
${indentation}${tabixBackup} = sy-tabix.
|
|
79166
|
-
${indentation}READ TABLE ${pre} ${condition}
|
|
79200
|
+
${indentation}READ TABLE ${pre} ${condition}ASSIGNING ${uniqueName}.
|
|
79167
79201
|
${indentation}sy-tabix = ${tabixBackup}.
|
|
79168
79202
|
${indentation}IF sy-subrc <> 0.
|
|
79169
79203
|
${indentation} RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
|
|
@@ -79917,8 +79951,7 @@ CONSTANTS: BEGIN OF ${structureName},\n`;
|
|
|
79917
79951
|
if (index === undefined) {
|
|
79918
79952
|
return undefined;
|
|
79919
79953
|
}
|
|
79920
|
-
|
|
79921
|
-
uniqueName = `<${uniqueName}>`;
|
|
79954
|
+
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax, true);
|
|
79922
79955
|
const tName = target.concatTokens().split("[")[0];
|
|
79923
79956
|
const condition = this.tableCondition(tableExpression);
|
|
79924
79957
|
const tabixBackup = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
@@ -80930,12 +80963,16 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80930
80963
|
}
|
|
80931
80964
|
return undefined;
|
|
80932
80965
|
}
|
|
80933
|
-
|
|
80966
|
+
/** a FIELD-SYMBOLS declaration is known to the scope under its bracketed spelling, so
|
|
80967
|
+
* the collision check has to use that spelling too - otherwise a second outline in the
|
|
80968
|
+
* same method is handed a name that is already taken and the result does not compile */
|
|
80969
|
+
uniqueName(position, filename, highSyntax, fieldSymbol = false) {
|
|
80970
|
+
const decorate = (name) => fieldSymbol === true ? `<${name}>` : name;
|
|
80934
80971
|
const spag = highSyntax.spaghetti.lookupPosition(position, filename);
|
|
80935
80972
|
if (spag === undefined) {
|
|
80936
80973
|
const name = "temprr" + this.counter;
|
|
80937
80974
|
this.counter++;
|
|
80938
|
-
return name;
|
|
80975
|
+
return decorate(name);
|
|
80939
80976
|
}
|
|
80940
80977
|
let postfix = "";
|
|
80941
80978
|
if (spag.getIdentifier().stype === _scope_type_1.ScopeType.ClassDefinition) {
|
|
@@ -80944,7 +80981,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80944
80981
|
postfix = "_" + hash.substring(0, 10);
|
|
80945
80982
|
}
|
|
80946
80983
|
while (true) {
|
|
80947
|
-
const name = "temp" + this.counter + postfix;
|
|
80984
|
+
const name = decorate("temp" + this.counter + postfix);
|
|
80948
80985
|
const exists = this.existsRecursive(spag, name);
|
|
80949
80986
|
this.counter++;
|
|
80950
80987
|
if (exists === false) {
|
|
@@ -85426,6 +85463,7 @@ __exportStar(__webpack_require__(/*! ./use_line_exists */ "./node_modules/@abapl
|
|
|
85426
85463
|
__exportStar(__webpack_require__(/*! ./use_new */ "./node_modules/@abaplint/core/build/src/rules/use_new.js"), exports);
|
|
85427
85464
|
__exportStar(__webpack_require__(/*! ./when_others_last */ "./node_modules/@abaplint/core/build/src/rules/when_others_last.js"), exports);
|
|
85428
85465
|
__exportStar(__webpack_require__(/*! ./whitespace_end */ "./node_modules/@abaplint/core/build/src/rules/whitespace_end.js"), exports);
|
|
85466
|
+
__exportStar(__webpack_require__(/*! ./wrong_abapdoc_position */ "./node_modules/@abaplint/core/build/src/rules/wrong_abapdoc_position.js"), exports);
|
|
85429
85467
|
__exportStar(__webpack_require__(/*! ./xml_consistency */ "./node_modules/@abaplint/core/build/src/rules/xml_consistency.js"), exports);
|
|
85430
85468
|
__exportStar(__webpack_require__(/*! ./no_exclamation_escape */ "./node_modules/@abaplint/core/build/src/rules/no_exclamation_escape.js"), exports);
|
|
85431
85469
|
__exportStar(__webpack_require__(/*! ./xml_bom */ "./node_modules/@abaplint/core/build/src/rules/xml_bom.js"), exports);
|
|
@@ -100908,6 +100946,178 @@ exports.WhitespaceEnd = WhitespaceEnd;
|
|
|
100908
100946
|
|
|
100909
100947
|
/***/ },
|
|
100910
100948
|
|
|
100949
|
+
/***/ "./node_modules/@abaplint/core/build/src/rules/wrong_abapdoc_position.js"
|
|
100950
|
+
/*!*******************************************************************************!*\
|
|
100951
|
+
!*** ./node_modules/@abaplint/core/build/src/rules/wrong_abapdoc_position.js ***!
|
|
100952
|
+
\*******************************************************************************/
|
|
100953
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
100954
|
+
|
|
100955
|
+
"use strict";
|
|
100956
|
+
|
|
100957
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
100958
|
+
if (k2 === undefined) k2 = k;
|
|
100959
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
100960
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
100961
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
100962
|
+
}
|
|
100963
|
+
Object.defineProperty(o, k2, desc);
|
|
100964
|
+
}) : (function(o, m, k, k2) {
|
|
100965
|
+
if (k2 === undefined) k2 = k;
|
|
100966
|
+
o[k2] = m[k];
|
|
100967
|
+
}));
|
|
100968
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
100969
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
100970
|
+
}) : function(o, v) {
|
|
100971
|
+
o["default"] = v;
|
|
100972
|
+
});
|
|
100973
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
100974
|
+
var ownKeys = function(o) {
|
|
100975
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
100976
|
+
var ar = [];
|
|
100977
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
100978
|
+
return ar;
|
|
100979
|
+
};
|
|
100980
|
+
return ownKeys(o);
|
|
100981
|
+
};
|
|
100982
|
+
return function (mod) {
|
|
100983
|
+
if (mod && mod.__esModule) return mod;
|
|
100984
|
+
var result = {};
|
|
100985
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
100986
|
+
__setModuleDefault(result, mod);
|
|
100987
|
+
return result;
|
|
100988
|
+
};
|
|
100989
|
+
})();
|
|
100990
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
100991
|
+
exports.WrongAbapdocPosition = exports.WrongAbapdocPositionConf = void 0;
|
|
100992
|
+
const Statements = __importStar(__webpack_require__(/*! ../abap/2_statements/statements */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js"));
|
|
100993
|
+
const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
|
|
100994
|
+
const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
|
|
100995
|
+
const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
|
|
100996
|
+
const _irule_1 = __webpack_require__(/*! ./_irule */ "./node_modules/@abaplint/core/build/src/rules/_irule.js");
|
|
100997
|
+
const _statement_1 = __webpack_require__(/*! ../abap/2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
|
|
100998
|
+
class WrongAbapdocPositionConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
100999
|
+
}
|
|
101000
|
+
exports.WrongAbapdocPositionConf = WrongAbapdocPositionConf;
|
|
101001
|
+
class WrongAbapdocPosition extends _abap_rule_1.ABAPRule {
|
|
101002
|
+
constructor() {
|
|
101003
|
+
super(...arguments);
|
|
101004
|
+
this.conf = new WrongAbapdocPositionConf();
|
|
101005
|
+
}
|
|
101006
|
+
getMetadata() {
|
|
101007
|
+
return {
|
|
101008
|
+
key: "wrong_abapdoc_position",
|
|
101009
|
+
title: "Wrong ABAP Doc position",
|
|
101010
|
+
shortDescription: `ABAP Doc must be placed directly in front of the declaration it documents.`,
|
|
101011
|
+
extendedInformation: `ABAP Doc documents the single declaration following it, an ABAP Doc block placed
|
|
101012
|
+
elsewhere is silently ignored, leaving the declaration undocumented.
|
|
101013
|
+
|
|
101014
|
+
The following positions are reported,
|
|
101015
|
+
* in front of a chained keyword, ie. before "CONSTANTS:" instead of after the colon,
|
|
101016
|
+
* in the middle of a statement, ie. between the parameters of a METHODS definition,
|
|
101017
|
+
* directly in front of ENDCLASS, ENDINTERFACE or a SECTION statement.
|
|
101018
|
+
|
|
101019
|
+
Only checks ABAP Doc inside class definitions and interfaces.`,
|
|
101020
|
+
tags: [_irule_1.RuleTag.SingleFile],
|
|
101021
|
+
badExample: `CLASS zcl_foo DEFINITION PUBLIC.
|
|
101022
|
+
PUBLIC SECTION.
|
|
101023
|
+
"! Navigation modes
|
|
101024
|
+
CONSTANTS:
|
|
101025
|
+
BEGIN OF cs_nav_mode,
|
|
101026
|
+
back TYPE i VALUE 1,
|
|
101027
|
+
END OF cs_nav_mode.
|
|
101028
|
+
ENDCLASS.`,
|
|
101029
|
+
goodExample: `CLASS zcl_foo DEFINITION PUBLIC.
|
|
101030
|
+
PUBLIC SECTION.
|
|
101031
|
+
CONSTANTS:
|
|
101032
|
+
"! Navigation modes
|
|
101033
|
+
BEGIN OF cs_nav_mode,
|
|
101034
|
+
back TYPE i VALUE 1,
|
|
101035
|
+
END OF cs_nav_mode.
|
|
101036
|
+
ENDCLASS.`,
|
|
101037
|
+
};
|
|
101038
|
+
}
|
|
101039
|
+
getConfig() {
|
|
101040
|
+
return this.conf;
|
|
101041
|
+
}
|
|
101042
|
+
setConfig(conf) {
|
|
101043
|
+
this.conf = conf;
|
|
101044
|
+
}
|
|
101045
|
+
runParsed(file) {
|
|
101046
|
+
const issues = [];
|
|
101047
|
+
const statements = file.getStatements();
|
|
101048
|
+
let definition = false;
|
|
101049
|
+
for (let i = 0; i < statements.length; i++) {
|
|
101050
|
+
const statement = statements[i];
|
|
101051
|
+
const type = statement.get();
|
|
101052
|
+
if (type instanceof Statements.ClassDefinition || type instanceof Statements.Interface) {
|
|
101053
|
+
definition = true;
|
|
101054
|
+
continue;
|
|
101055
|
+
}
|
|
101056
|
+
else if (type instanceof Statements.EndClass || type instanceof Statements.EndInterface) {
|
|
101057
|
+
definition = false;
|
|
101058
|
+
continue;
|
|
101059
|
+
}
|
|
101060
|
+
else if (definition === false || this.isAbapdoc(statement) === false) {
|
|
101061
|
+
continue;
|
|
101062
|
+
}
|
|
101063
|
+
else if (this.isAbapdoc(statements[i - 1]) === true
|
|
101064
|
+
&& statements[i - 1].getStart().getRow() + 1 === statement.getStart().getRow()) {
|
|
101065
|
+
continue; // only report the first row of each block
|
|
101066
|
+
}
|
|
101067
|
+
let next = undefined;
|
|
101068
|
+
for (let j = i + 1; j < statements.length; j++) {
|
|
101069
|
+
if (statements[j].get() instanceof _statement_1.Comment) {
|
|
101070
|
+
continue;
|
|
101071
|
+
}
|
|
101072
|
+
next = statements[j];
|
|
101073
|
+
break;
|
|
101074
|
+
}
|
|
101075
|
+
if (next === undefined) {
|
|
101076
|
+
continue;
|
|
101077
|
+
}
|
|
101078
|
+
const message = this.check(statement, next);
|
|
101079
|
+
if (message !== undefined) {
|
|
101080
|
+
issues.push(issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
|
|
101081
|
+
}
|
|
101082
|
+
}
|
|
101083
|
+
return issues;
|
|
101084
|
+
}
|
|
101085
|
+
isAbapdoc(statement) {
|
|
101086
|
+
return (statement === null || statement === void 0 ? void 0 : statement.get()) instanceof _statement_1.Comment
|
|
101087
|
+
&& statement.getFirstToken().getStr().startsWith(`"!`);
|
|
101088
|
+
}
|
|
101089
|
+
check(abapdoc, next) {
|
|
101090
|
+
const type = next.get();
|
|
101091
|
+
if (type instanceof Statements.EndClass
|
|
101092
|
+
|| type instanceof Statements.EndInterface
|
|
101093
|
+
|| type instanceof Statements.Public
|
|
101094
|
+
|| type instanceof Statements.Protected
|
|
101095
|
+
|| type instanceof Statements.Private) {
|
|
101096
|
+
return "ABAP Doc does not document anything, move or delete it";
|
|
101097
|
+
}
|
|
101098
|
+
const position = abapdoc.getStart();
|
|
101099
|
+
const colon = next.getColon();
|
|
101100
|
+
if (colon === undefined) {
|
|
101101
|
+
if (position.isAfter(next.getStart()) === true) {
|
|
101102
|
+
return "ABAP Doc inside statement, move it in front of the statement";
|
|
101103
|
+
}
|
|
101104
|
+
return undefined;
|
|
101105
|
+
}
|
|
101106
|
+
if (position.isBefore(colon.getStart()) === true) {
|
|
101107
|
+
return "ABAP Doc in front of chained statement, move it after the colon";
|
|
101108
|
+
}
|
|
101109
|
+
const member = next.getTokens().find(t => t.getStart().isAfter(colon.getStart()));
|
|
101110
|
+
if (member !== undefined && position.isAfter(member.getStart()) === true) {
|
|
101111
|
+
return "ABAP Doc inside statement, move it in front of the chained declaration";
|
|
101112
|
+
}
|
|
101113
|
+
return undefined;
|
|
101114
|
+
}
|
|
101115
|
+
}
|
|
101116
|
+
exports.WrongAbapdocPosition = WrongAbapdocPosition;
|
|
101117
|
+
//# sourceMappingURL=wrong_abapdoc_position.js.map
|
|
101118
|
+
|
|
101119
|
+
/***/ },
|
|
101120
|
+
|
|
100911
101121
|
/***/ "./node_modules/@abaplint/core/build/src/rules/xml_bom.js"
|
|
100912
101122
|
/*!****************************************************************!*\
|
|
100913
101123
|
!*** ./node_modules/@abaplint/core/build/src/rules/xml_bom.js ***!
|
|
@@ -107087,10 +107297,50 @@ class SourceTranspiler {
|
|
|
107087
107297
|
constructor(addGet = false) {
|
|
107088
107298
|
this.addGet = addGet;
|
|
107089
107299
|
}
|
|
107300
|
+
// the operands of a chain of & / && (the rearranger leaves them as a binary
|
|
107301
|
+
// tree of Source nodes); an empty list when the node is not such a chain
|
|
107302
|
+
concatOperands(node) {
|
|
107303
|
+
const children = node.getChildren();
|
|
107304
|
+
if (children.length !== 3) {
|
|
107305
|
+
return [];
|
|
107306
|
+
}
|
|
107307
|
+
const op = children[1];
|
|
107308
|
+
if (!(op instanceof core_1.Nodes.TokenNode) || (op.getFirstToken().getStr() !== "&&" && op.getFirstToken().getStr() !== "&")) {
|
|
107309
|
+
return [];
|
|
107310
|
+
}
|
|
107311
|
+
const side = (c) => {
|
|
107312
|
+
if (c instanceof core_1.Nodes.ExpressionNode && c.get() instanceof core_1.Expressions.Source) {
|
|
107313
|
+
const inner = this.concatOperands(c);
|
|
107314
|
+
return inner.length > 0 ? inner : [c];
|
|
107315
|
+
}
|
|
107316
|
+
const wrapped = new core_1.Nodes.ExpressionNode(new core_1.Expressions.Source());
|
|
107317
|
+
wrapped.setChildren([c]);
|
|
107318
|
+
return [wrapped];
|
|
107319
|
+
};
|
|
107320
|
+
return [...side(children[0]), ...side(children[2])];
|
|
107321
|
+
}
|
|
107090
107322
|
transpile(node, traversal, context) {
|
|
107091
107323
|
let ret = new chunk_1.Chunk();
|
|
107092
107324
|
const post = new chunk_1.Chunk();
|
|
107093
107325
|
const children = node.getChildren();
|
|
107326
|
+
// a & b & c ... : one flat concat([a, b, c]) instead of one nested
|
|
107327
|
+
// concat( ) per operand (a long chain would otherwise exhaust the stack
|
|
107328
|
+
// of a parser with a small budget, e.g. a service worker's)
|
|
107329
|
+
const operands = this.concatOperands(node);
|
|
107330
|
+
if (operands.length > 2) {
|
|
107331
|
+
const flat = new chunk_1.Chunk().appendString("abap.operators.concat([");
|
|
107332
|
+
for (let i = 0; i < operands.length; i++) {
|
|
107333
|
+
if (i > 0) {
|
|
107334
|
+
flat.appendString(",");
|
|
107335
|
+
}
|
|
107336
|
+
flat.appendChunk(new SourceTranspiler(false).transpile(operands[i], traversal, context));
|
|
107337
|
+
}
|
|
107338
|
+
flat.appendString("])");
|
|
107339
|
+
if (this.addGet) {
|
|
107340
|
+
flat.appendString(".get()");
|
|
107341
|
+
}
|
|
107342
|
+
return flat;
|
|
107343
|
+
}
|
|
107094
107344
|
// Pre-scan for unary prefix +/- tokens (WDashW / WPlusW) before any expression
|
|
107095
107345
|
let prefixNegated = false;
|
|
107096
107346
|
let startIdx = 0;
|
|
@@ -110895,9 +111145,13 @@ exports.DEFAULT_KEYWORDS = new Set([
|
|
|
110895
111145
|
"throw", "throws", "transient", "true",
|
|
110896
111146
|
"try", "typeof", "var", "void",
|
|
110897
111147
|
"delete",
|
|
110898
|
-
"volatile", "while", "yield"
|
|
111148
|
+
"volatile", "while", "yield",
|
|
111149
|
+
// both produce a SyntaxError in the emitted module: they are reserved words
|
|
111150
|
+
// in JavaScript and legal ABAP names. "super" is NOT in this list on purpose -
|
|
111151
|
+
// the emitted code uses the JS `super` for ABAP's `super->method( )`, and
|
|
111152
|
+
// escaping it turns that call into `$super.get().method()`
|
|
111153
|
+
"case", "with"
|
|
110899
111154
|
]);
|
|
110900
|
-
// "with"
|
|
110901
111155
|
//# sourceMappingURL=keywords.js.map
|
|
110902
111156
|
|
|
110903
111157
|
/***/ },
|
|
@@ -111100,7 +111354,23 @@ class Rearranger {
|
|
|
111100
111354
|
return node;
|
|
111101
111355
|
}
|
|
111102
111356
|
const withoutLast = node.getChildren().slice(0, children.length - 1);
|
|
111103
|
-
|
|
111357
|
+
// The nested children come up so that precedence can be decided across
|
|
111358
|
+
// the whole chain, and everything before the nested operator has to
|
|
111359
|
+
// arrive as one operand. For "a * b / c" that is already true, b being a
|
|
111360
|
+
// single Source. For "a * CONV f( b ) / c" it is not: CONV is five
|
|
111361
|
+
// children, and hoisting them one by one puts the type name and the
|
|
111362
|
+
// body beside the arithmetic, where the transpiler reads them as
|
|
111363
|
+
// operands and loses the rest of the expression. So the head is wrapped
|
|
111364
|
+
// back into one Source before it moves.
|
|
111365
|
+
const nested = last.getChildren();
|
|
111366
|
+
const firstOperator = nested.findIndex((c) => c instanceof core_1.Nodes.ExpressionNode && c.get() instanceof core_1.Expressions.ArithOperator);
|
|
111367
|
+
let head = nested.slice(0, firstOperator);
|
|
111368
|
+
if (head.length > 1) {
|
|
111369
|
+
const operand = new core_1.Nodes.ExpressionNode(last.get());
|
|
111370
|
+
operand.setChildren(head);
|
|
111371
|
+
head = [operand];
|
|
111372
|
+
}
|
|
111373
|
+
const flat = withoutLast.concat(head, nested.slice(firstOperator));
|
|
111104
111374
|
node.setChildren(flat);
|
|
111105
111375
|
return node;
|
|
111106
111376
|
}
|
|
@@ -122047,16 +122317,16 @@ class FunctionModuleTranspiler {
|
|
|
122047
122317
|
direction = "importing";
|
|
122048
122318
|
}
|
|
122049
122319
|
// note: all directions are optional
|
|
122050
|
-
|
|
122051
|
-
|
|
122052
|
-
|
|
122053
|
-
|
|
122054
|
-
ret += `let ${
|
|
122320
|
+
const name = p.name.toLowerCase();
|
|
122321
|
+
// a parameter named like a JavaScript keyword, RETURN on every BAPI,
|
|
122322
|
+
// is declared the way the function body refers to it
|
|
122323
|
+
const variable = traversal_1.Traversal.prefixVariable(name);
|
|
122324
|
+
ret += `let ${variable} = INPUT.${direction}?.${name};\n`;
|
|
122055
122325
|
const type = scope?.findVariable(name)?.getType();
|
|
122056
122326
|
if (type !== undefined && p.optional === true) {
|
|
122057
122327
|
// todo, set DEFAULT value
|
|
122058
|
-
ret += `if (${
|
|
122059
|
-
${
|
|
122328
|
+
ret += `if (${variable} === undefined) {
|
|
122329
|
+
${variable} = ${transpile_types_1.TranspileTypes.toType(type)};
|
|
122060
122330
|
}\n`;
|
|
122061
122331
|
}
|
|
122062
122332
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/transpiler-cli",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.87",
|
|
4
4
|
"description": "Transpiler - Command Line Interface",
|
|
5
5
|
"funding": "https://github.com/sponsors/larshp",
|
|
6
6
|
"bin": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"author": "abaplint",
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@abaplint/core": "^2.120.
|
|
31
|
-
"@abaplint/transpiler": "^2.13.
|
|
30
|
+
"@abaplint/core": "^2.120.52",
|
|
31
|
+
"@abaplint/transpiler": "^2.13.87",
|
|
32
32
|
"@types/glob": "^9.0.0",
|
|
33
33
|
"@types/node": "^26.4.1",
|
|
34
34
|
"@types/progress": "^2.0.7",
|