@abaplint/cli 2.95.0 → 2.95.2

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 +4 -4
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -390,7 +390,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
390
390
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
391
391
 
392
392
  "use strict";
393
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.ExpandMacros = void 0;\r\nconst Statements = __webpack_require__(/*! ./statements */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js\");\r\nconst Expressions = __webpack_require__(/*! ./expressions */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js\");\r\nconst Tokens = __webpack_require__(/*! ../1_lexer/tokens */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js\");\r\nconst _statement_1 = __webpack_require__(/*! ./statements/_statement */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js\");\r\nconst statement_node_1 = __webpack_require__(/*! ../nodes/statement_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/statement_node.js\");\r\nconst token_node_1 = __webpack_require__(/*! ../nodes/token_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/token_node.js\");\r\nconst statement_parser_1 = __webpack_require__(/*! ./statement_parser */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statement_parser.js\");\r\nconst memory_file_1 = __webpack_require__(/*! ../../files/memory_file */ \"./node_modules/@abaplint/core/build/src/files/memory_file.js\");\r\nconst lexer_1 = __webpack_require__(/*! ../1_lexer/lexer */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/lexer.js\");\r\nconst position_1 = __webpack_require__(/*! ../../position */ \"./node_modules/@abaplint/core/build/src/position.js\");\r\nclass Macros {\r\n constructor(globalMacros) {\r\n this.macros = {};\r\n for (const m of globalMacros) {\r\n this.macros[m.toUpperCase()] = [];\r\n }\r\n }\r\n addMacro(name, contents) {\r\n if (this.isMacro(name)) {\r\n return;\r\n }\r\n this.macros[name.toUpperCase()] = contents;\r\n }\r\n getContents(name) {\r\n return this.macros[name.toUpperCase()];\r\n }\r\n listMacroNames() {\r\n return Object.keys(this.macros);\r\n }\r\n isMacro(name) {\r\n if (this.macros[name.toUpperCase()]) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n}\r\nclass ExpandMacros {\r\n // \"reg\" must be supplied if there are cross object macros via INCLUDE\r\n constructor(globalMacros, version, reg) {\r\n this.macros = new Macros(globalMacros);\r\n this.version = version;\r\n this.globalMacros = globalMacros;\r\n this.reg = reg;\r\n }\r\n find(statements) {\r\n var _a, _b;\r\n let name = undefined;\r\n let contents = [];\r\n for (let i = 0; i < statements.length; i++) {\r\n const statement = statements[i];\r\n const type = statement.get();\r\n if (type instanceof Statements.Define) {\r\n // todo, will this break if first token is a pragma?\r\n name = statement.getTokens()[1].getStr();\r\n contents = [];\r\n }\r\n else if (type instanceof Statements.Include) {\r\n const includeName = (_a = statement.findDirectExpression(Expressions.IncludeName)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n // todo, this does not take function module includes into account\r\n const prog = (_b = this.reg) === null || _b === void 0 ? void 0 : _b.getObject(\"PROG\", includeName);\r\n if (prog) {\r\n prog.parse(this.version, this.globalMacros, this.reg);\r\n const main = prog.getMainABAPFile();\r\n if (main) {\r\n // slow, this copies everything,\r\n this.find([...main.getStatements()]);\r\n }\r\n }\r\n }\r\n else if (name) {\r\n if (type instanceof Statements.EndOfDefinition) {\r\n this.macros.addMacro(name, contents);\r\n name = undefined;\r\n }\r\n else if (!(type instanceof _statement_1.Comment)) {\r\n statements[i] = new statement_node_1.StatementNode(new _statement_1.MacroContent()).setChildren(this.tokensToNodes(statement.getTokens()));\r\n contents.push(statements[i]);\r\n }\r\n }\r\n }\r\n }\r\n handleMacros(statements) {\r\n const result = [];\r\n let containsUnknown = false;\r\n for (const statement of statements) {\r\n const type = statement.get();\r\n if (type instanceof _statement_1.Unknown || type instanceof _statement_1.MacroCall) {\r\n const macroName = this.findName(statement.getTokens());\r\n if (macroName && this.macros.isMacro(macroName)) {\r\n result.push(new statement_node_1.StatementNode(new _statement_1.MacroCall()).setChildren(this.tokensToNodes(statement.getTokens())));\r\n const expanded = this.expandContents(macroName, statement);\r\n const handled = this.handleMacros(expanded);\r\n for (const e of handled.statements) {\r\n result.push(e);\r\n }\r\n if (handled.containsUnknown === true) {\r\n containsUnknown = true;\r\n }\r\n continue;\r\n }\r\n else {\r\n containsUnknown = true;\r\n }\r\n }\r\n result.push(statement);\r\n }\r\n return { statements: result, containsUnknown };\r\n }\r\n //////////////\r\n expandContents(name, statement) {\r\n const contents = this.macros.getContents(name);\r\n if (contents === undefined || contents.length === 0) {\r\n return [];\r\n }\r\n let str = \"\";\r\n for (const c of contents) {\r\n let concat = c.concatTokens();\r\n if (c.getTerminator() === \",\") {\r\n // workaround for chained statements\r\n concat = concat.replace(/,$/, \".\");\r\n }\r\n str += concat + \"\\n\";\r\n }\r\n const inputs = this.buildInput(statement);\r\n let i = 1;\r\n for (const input of inputs) {\r\n const search = \"&\" + i;\r\n const reg = new RegExp(search, \"g\");\r\n str = str.replace(reg, input);\r\n i++;\r\n }\r\n const file = new memory_file_1.MemoryFile(\"expand_macros.abap.prog\", str);\r\n const lexerResult = new lexer_1.Lexer().run(file, statement.getFirstToken().getStart());\r\n const result = new statement_parser_1.StatementParser(this.version, this.reg).run([lexerResult], this.macros.listMacroNames());\r\n return result[0].statements;\r\n }\r\n buildInput(statement) {\r\n const result = [];\r\n const tokens = statement.getTokens();\r\n let build = \"\";\r\n for (let i = 1; i < tokens.length - 1; i++) {\r\n const now = tokens[i];\r\n let next = tokens[i + 1];\r\n if (i + 2 === tokens.length) {\r\n next = undefined; // dont take the punctuation\r\n }\r\n // argh, macros is a nightmare\r\n let end = now.getStart();\r\n if (end instanceof position_1.VirtualPosition) {\r\n end = new position_1.VirtualPosition(end, end.vrow, end.vcol + now.getStr().length);\r\n }\r\n else {\r\n end = now.getEnd();\r\n }\r\n if (next && next.getStart().equals(end)) {\r\n build += now.getStr();\r\n }\r\n else {\r\n build += now.getStr();\r\n result.push(build);\r\n build = \"\";\r\n }\r\n }\r\n return result;\r\n }\r\n findName(tokens) {\r\n let macroName = undefined;\r\n let previous = undefined;\r\n for (const i of tokens) {\r\n if (previous && (previous === null || previous === void 0 ? void 0 : previous.getEnd().getCol()) !== i.getStart().getCol()) {\r\n break;\r\n }\r\n else if (i instanceof Tokens.Identifier || i.getStr() === \"-\") {\r\n if (macroName === undefined) {\r\n macroName = i.getStr();\r\n }\r\n else {\r\n macroName += i.getStr();\r\n }\r\n }\r\n else if (i instanceof Tokens.Pragma) {\r\n continue;\r\n }\r\n else {\r\n break;\r\n }\r\n previous = i;\r\n }\r\n return macroName;\r\n }\r\n tokensToNodes(tokens) {\r\n const ret = [];\r\n for (const t of tokens) {\r\n ret.push(new token_node_1.TokenNode(t));\r\n }\r\n return ret;\r\n }\r\n}\r\nexports.ExpandMacros = ExpandMacros;\r\n//# sourceMappingURL=expand_macros.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/2_statements/expand_macros.js?");
393
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.ExpandMacros = void 0;\r\nconst Statements = __webpack_require__(/*! ./statements */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/index.js\");\r\nconst Expressions = __webpack_require__(/*! ./expressions */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js\");\r\nconst Tokens = __webpack_require__(/*! ../1_lexer/tokens */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/index.js\");\r\nconst _statement_1 = __webpack_require__(/*! ./statements/_statement */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js\");\r\nconst statement_node_1 = __webpack_require__(/*! ../nodes/statement_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/statement_node.js\");\r\nconst token_node_1 = __webpack_require__(/*! ../nodes/token_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/token_node.js\");\r\nconst statement_parser_1 = __webpack_require__(/*! ./statement_parser */ \"./node_modules/@abaplint/core/build/src/abap/2_statements/statement_parser.js\");\r\nconst memory_file_1 = __webpack_require__(/*! ../../files/memory_file */ \"./node_modules/@abaplint/core/build/src/files/memory_file.js\");\r\nconst lexer_1 = __webpack_require__(/*! ../1_lexer/lexer */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/lexer.js\");\r\nconst position_1 = __webpack_require__(/*! ../../position */ \"./node_modules/@abaplint/core/build/src/position.js\");\r\nclass Macros {\r\n constructor(globalMacros) {\r\n this.macros = {};\r\n for (const m of globalMacros) {\r\n this.macros[m.toUpperCase()] = [];\r\n }\r\n }\r\n addMacro(name, contents) {\r\n if (this.isMacro(name)) {\r\n return;\r\n }\r\n this.macros[name.toUpperCase()] = contents;\r\n }\r\n getContents(name) {\r\n return this.macros[name.toUpperCase()];\r\n }\r\n listMacroNames() {\r\n return Object.keys(this.macros);\r\n }\r\n isMacro(name) {\r\n if (this.macros[name.toUpperCase()]) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n}\r\nclass ExpandMacros {\r\n // \"reg\" must be supplied if there are cross object macros via INCLUDE\r\n constructor(globalMacros, version, reg) {\r\n this.macros = new Macros(globalMacros);\r\n this.version = version;\r\n this.globalMacros = globalMacros;\r\n this.reg = reg;\r\n }\r\n find(statements) {\r\n var _a, _b;\r\n let name = undefined;\r\n let contents = [];\r\n for (let i = 0; i < statements.length; i++) {\r\n const statement = statements[i];\r\n const type = statement.get();\r\n if (type instanceof Statements.Define) {\r\n // todo, will this break if first token is a pragma?\r\n name = statement.getTokens()[1].getStr();\r\n contents = [];\r\n }\r\n else if (type instanceof Statements.Include) {\r\n const includeName = (_a = statement.findDirectExpression(Expressions.IncludeName)) === null || _a === void 0 ? void 0 : _a.concatTokens();\r\n // todo, this does not take function module includes into account\r\n const prog = (_b = this.reg) === null || _b === void 0 ? void 0 : _b.getObject(\"PROG\", includeName);\r\n if (prog) {\r\n prog.parse(this.version, this.globalMacros, this.reg);\r\n const main = prog.getMainABAPFile();\r\n if (main) {\r\n // slow, this copies everything,\r\n this.find([...main.getStatements()]);\r\n }\r\n }\r\n }\r\n else if (name) {\r\n if (type instanceof Statements.EndOfDefinition) {\r\n this.macros.addMacro(name, contents);\r\n name = undefined;\r\n }\r\n else if (!(type instanceof _statement_1.Comment)) {\r\n statements[i] = new statement_node_1.StatementNode(new _statement_1.MacroContent()).setChildren(this.tokensToNodes(statement.getTokens()));\r\n contents.push(statements[i]);\r\n }\r\n }\r\n }\r\n }\r\n handleMacros(statements) {\r\n const result = [];\r\n let containsUnknown = false;\r\n for (const statement of statements) {\r\n const type = statement.get();\r\n if (type instanceof _statement_1.Unknown || type instanceof _statement_1.MacroCall) {\r\n const macroName = this.findName(statement.getTokens());\r\n if (macroName && this.macros.isMacro(macroName)) {\r\n result.push(new statement_node_1.StatementNode(new _statement_1.MacroCall(), statement.getColon()).setChildren(this.tokensToNodes(statement.getTokens())));\r\n const expanded = this.expandContents(macroName, statement);\r\n const handled = this.handleMacros(expanded);\r\n for (const e of handled.statements) {\r\n result.push(e);\r\n }\r\n if (handled.containsUnknown === true) {\r\n containsUnknown = true;\r\n }\r\n continue;\r\n }\r\n else {\r\n containsUnknown = true;\r\n }\r\n }\r\n result.push(statement);\r\n }\r\n return { statements: result, containsUnknown };\r\n }\r\n //////////////\r\n expandContents(name, statement) {\r\n const contents = this.macros.getContents(name);\r\n if (contents === undefined || contents.length === 0) {\r\n return [];\r\n }\r\n let str = \"\";\r\n for (const c of contents) {\r\n let concat = c.concatTokens();\r\n if (c.getTerminator() === \",\") {\r\n // workaround for chained statements\r\n concat = concat.replace(/,$/, \".\");\r\n }\r\n str += concat + \"\\n\";\r\n }\r\n const inputs = this.buildInput(statement);\r\n let i = 1;\r\n for (const input of inputs) {\r\n const search = \"&\" + i;\r\n const reg = new RegExp(search, \"g\");\r\n str = str.replace(reg, input);\r\n i++;\r\n }\r\n const file = new memory_file_1.MemoryFile(\"expand_macros.abap.prog\", str);\r\n const lexerResult = new lexer_1.Lexer().run(file, statement.getFirstToken().getStart());\r\n const result = new statement_parser_1.StatementParser(this.version, this.reg).run([lexerResult], this.macros.listMacroNames());\r\n return result[0].statements;\r\n }\r\n buildInput(statement) {\r\n const result = [];\r\n const tokens = statement.getTokens();\r\n let build = \"\";\r\n for (let i = 1; i < tokens.length - 1; i++) {\r\n const now = tokens[i];\r\n let next = tokens[i + 1];\r\n if (i + 2 === tokens.length) {\r\n next = undefined; // dont take the punctuation\r\n }\r\n // argh, macros is a nightmare\r\n let end = now.getStart();\r\n if (end instanceof position_1.VirtualPosition) {\r\n end = new position_1.VirtualPosition(end, end.vrow, end.vcol + now.getStr().length);\r\n }\r\n else {\r\n end = now.getEnd();\r\n }\r\n if (next && next.getStart().equals(end)) {\r\n build += now.getStr();\r\n }\r\n else {\r\n build += now.getStr();\r\n result.push(build);\r\n build = \"\";\r\n }\r\n }\r\n return result;\r\n }\r\n findName(tokens) {\r\n let macroName = undefined;\r\n let previous = undefined;\r\n for (const i of tokens) {\r\n if (previous && (previous === null || previous === void 0 ? void 0 : previous.getEnd().getCol()) !== i.getStart().getCol()) {\r\n break;\r\n }\r\n else if (i instanceof Tokens.Identifier || i.getStr() === \"-\") {\r\n if (macroName === undefined) {\r\n macroName = i.getStr();\r\n }\r\n else {\r\n macroName += i.getStr();\r\n }\r\n }\r\n else if (i instanceof Tokens.Pragma) {\r\n continue;\r\n }\r\n else {\r\n break;\r\n }\r\n previous = i;\r\n }\r\n return macroName;\r\n }\r\n tokensToNodes(tokens) {\r\n const ret = [];\r\n for (const t of tokens) {\r\n ret.push(new token_node_1.TokenNode(t));\r\n }\r\n return ret;\r\n }\r\n}\r\nexports.ExpandMacros = ExpandMacros;\r\n//# sourceMappingURL=expand_macros.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/2_statements/expand_macros.js?");
394
394
 
395
395
  /***/ }),
396
396
 
@@ -8948,7 +8948,7 @@ eval("\r\nvar __createBinding = (this && this.__createBinding) || (Object.create
8948
8948
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
8949
8949
 
8950
8950
  "use strict";
8951
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.StatementNode = void 0;\r\nconst _abstract_node_1 = __webpack_require__(/*! ./_abstract_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/_abstract_node.js\");\r\nconst token_node_1 = __webpack_require__(/*! ./token_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/token_node.js\");\r\nconst expression_node_1 = __webpack_require__(/*! ./expression_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/expression_node.js\");\r\nconst comment_1 = __webpack_require__(/*! ../1_lexer/tokens/comment */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/comment.js\");\r\nconst pragma_1 = __webpack_require__(/*! ../1_lexer/tokens/pragma */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/pragma.js\");\r\nconst string_1 = __webpack_require__(/*! ../1_lexer/tokens/string */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/string.js\");\r\nclass StatementNode extends _abstract_node_1.AbstractNode {\r\n constructor(statement, colon, pragmas) {\r\n super();\r\n this.statement = statement;\r\n this.colon = colon;\r\n if (pragmas) {\r\n this.pragmas = pragmas;\r\n }\r\n else {\r\n this.pragmas = [];\r\n }\r\n }\r\n get() {\r\n return this.statement;\r\n }\r\n getColon() {\r\n return this.colon;\r\n }\r\n getPragmas() {\r\n return this.pragmas;\r\n }\r\n setChildren(children) {\r\n if (children.length === 0) {\r\n throw new Error(\"statement: zero children\");\r\n }\r\n this.children = children;\r\n return this;\r\n }\r\n getStart() {\r\n return this.getFirstToken().getStart();\r\n }\r\n getEnd() {\r\n const last = this.getLastToken();\r\n return last.getEnd();\r\n }\r\n getTokens() {\r\n const tokens = [];\r\n for (const c of this.getChildren()) {\r\n tokens.push(...this.toTokens(c));\r\n }\r\n return tokens;\r\n }\r\n includesToken(search) {\r\n for (const t of this.getTokens()) {\r\n if (t.getStart().equals(search.getStart())) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n getTokenNodes() {\r\n const tokens = [];\r\n for (const c of this.getChildren()) {\r\n tokens.push(...this.toTokenNodess(c));\r\n }\r\n return tokens;\r\n }\r\n concatTokens() {\r\n let str = \"\";\r\n let prev;\r\n for (const token of this.getTokens()) {\r\n if (token instanceof pragma_1.Pragma) {\r\n continue;\r\n }\r\n if (str === \"\") {\r\n str = token.getStr();\r\n }\r\n else if (prev && prev.getStr().length + prev.getCol() === token.getCol()\r\n && prev.getRow() === token.getRow()) {\r\n str = str + token.getStr();\r\n }\r\n else {\r\n str = str + \" \" + token.getStr();\r\n }\r\n prev = token;\r\n }\r\n return str;\r\n }\r\n concatTokensWithoutStringsAndComments() {\r\n let str = \"\";\r\n let prev;\r\n for (const token of this.getTokens()) {\r\n if (token instanceof comment_1.Comment\r\n || token instanceof string_1.StringToken\r\n || token instanceof string_1.StringTemplate\r\n || token instanceof string_1.StringTemplateBegin\r\n || token instanceof string_1.StringTemplateMiddle\r\n || token instanceof string_1.StringTemplateEnd) {\r\n continue;\r\n }\r\n if (str === \"\") {\r\n str = token.getStr();\r\n }\r\n else if (prev && prev.getStr().length + prev.getCol() === token.getCol()\r\n && prev.getRow() === token.getRow()) {\r\n str = str + token.getStr();\r\n }\r\n else {\r\n str = str + \" \" + token.getStr();\r\n }\r\n prev = token;\r\n }\r\n return str;\r\n }\r\n getTerminator() {\r\n return this.getLastToken().getStr();\r\n }\r\n getFirstToken() {\r\n for (const child of this.getChildren()) {\r\n return child.getFirstToken();\r\n }\r\n throw new Error(\"StatementNode, getFirstToken, no children, \" + this.get().constructor.name);\r\n }\r\n getLastToken() {\r\n const child = this.getLastChild();\r\n if (child !== undefined) {\r\n return child.getLastToken();\r\n }\r\n throw new Error(\"StatementNode, getLastToken, no children\");\r\n }\r\n findDirectExpression(type) {\r\n for (const child of this.getChildren()) {\r\n if (child instanceof expression_node_1.ExpressionNode && child.get() instanceof type) {\r\n return child;\r\n }\r\n }\r\n return undefined;\r\n }\r\n findDirectExpressions(type) {\r\n const ret = [];\r\n for (const child of this.getChildren()) {\r\n if (child instanceof expression_node_1.ExpressionNode && child.get() instanceof type) {\r\n ret.push(child);\r\n }\r\n }\r\n return ret;\r\n }\r\n findDirectTokenByText(text) {\r\n const upper = text.toUpperCase();\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode && child.get().getStr().toUpperCase() === upper) {\r\n return child.get();\r\n }\r\n }\r\n return undefined;\r\n }\r\n findFirstExpression(type) {\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode) {\r\n continue;\r\n }\r\n else if (child.get() instanceof type) {\r\n return child;\r\n }\r\n else {\r\n const res = child.findFirstExpression(type);\r\n if (res) {\r\n return res;\r\n }\r\n }\r\n }\r\n return undefined;\r\n }\r\n findAllExpressions(type) {\r\n const ret = [];\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode) {\r\n continue;\r\n }\r\n else if (child.get() instanceof type) {\r\n ret.push(child);\r\n }\r\n else {\r\n ret.push(...child.findAllExpressions(type));\r\n }\r\n }\r\n return ret;\r\n }\r\n findAllExpressionsRecursive(type) {\r\n const ret = [];\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode) {\r\n continue;\r\n }\r\n else if (child.get() instanceof type) {\r\n ret.push(child);\r\n }\r\n ret.push(...child.findAllExpressionsRecursive(type));\r\n }\r\n return ret;\r\n }\r\n findAllExpressionsMulti(type, recursive = false) {\r\n const ret = [];\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode) {\r\n continue;\r\n }\r\n const before = ret.length;\r\n for (const t of type) {\r\n if (child.get() instanceof t) {\r\n ret.push(child);\r\n }\r\n }\r\n if (before === ret.length || recursive === true) {\r\n ret.push(...child.findAllExpressionsMulti(type, recursive));\r\n }\r\n }\r\n return ret;\r\n }\r\n /**\r\n * Returns the Position of the first token if the sequence is found,\r\n * otherwise undefined. Strings and Comments are ignored in this search.\r\n * @param first - Text of the first Token\r\n * @param second - Text of the second Token\r\n */\r\n findTokenSequencePosition(first, second) {\r\n let prev;\r\n for (const token of this.getTokens()) {\r\n if (token instanceof comment_1.Comment\r\n || token instanceof string_1.StringToken\r\n || token instanceof string_1.StringTemplate\r\n || token instanceof string_1.StringTemplateBegin\r\n || token instanceof string_1.StringTemplateMiddle\r\n || token instanceof string_1.StringTemplateEnd) {\r\n continue;\r\n }\r\n if (prev && token.getStr().toUpperCase() === second && (prev === null || prev === void 0 ? void 0 : prev.getStr().toUpperCase()) === first.toUpperCase()) {\r\n return prev.getStart();\r\n }\r\n else {\r\n prev = token;\r\n }\r\n }\r\n return undefined;\r\n }\r\n findExpressionAfterToken(text) {\r\n const children = this.getChildren();\r\n for (let i = 0; i < children.length - 1; i++) {\r\n const c = children[i];\r\n const next = children[i + 1];\r\n if (c instanceof token_node_1.TokenNode\r\n && c.get().getStr().toUpperCase() === text.toUpperCase()\r\n && next instanceof expression_node_1.ExpressionNode) {\r\n return next;\r\n }\r\n }\r\n return undefined;\r\n }\r\n findExpressionsAfterToken(text) {\r\n const children = this.getChildren();\r\n const ret = [];\r\n for (let i = 0; i < children.length - 1; i++) {\r\n const c = children[i];\r\n const next = children[i + 1];\r\n if (c instanceof token_node_1.TokenNode\r\n && c.get().getStr().toUpperCase() === text.toUpperCase()\r\n && next instanceof expression_node_1.ExpressionNode) {\r\n ret.push(next);\r\n }\r\n }\r\n return ret;\r\n }\r\n ////////////////////////////////\r\n toTokens(b) {\r\n const tokens = [];\r\n if (b instanceof token_node_1.TokenNode) {\r\n tokens.push(b.get());\r\n return tokens;\r\n }\r\n for (const c of b.getChildren()) {\r\n if (c instanceof token_node_1.TokenNode) {\r\n tokens.push(c.get());\r\n }\r\n else {\r\n tokens.push(...this.toTokens(c));\r\n }\r\n }\r\n return tokens;\r\n }\r\n toTokenNodess(b) {\r\n const tokens = [];\r\n if (b instanceof token_node_1.TokenNode) {\r\n tokens.push(b);\r\n return tokens;\r\n }\r\n for (const c of b.getChildren()) {\r\n if (c instanceof token_node_1.TokenNode) {\r\n tokens.push(c);\r\n }\r\n else {\r\n tokens.push(...this.toTokenNodess(c));\r\n }\r\n }\r\n return tokens;\r\n }\r\n}\r\nexports.StatementNode = StatementNode;\r\n//# sourceMappingURL=statement_node.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/nodes/statement_node.js?");
8951
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.StatementNode = void 0;\r\nconst _abstract_node_1 = __webpack_require__(/*! ./_abstract_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/_abstract_node.js\");\r\nconst token_node_1 = __webpack_require__(/*! ./token_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/token_node.js\");\r\nconst expression_node_1 = __webpack_require__(/*! ./expression_node */ \"./node_modules/@abaplint/core/build/src/abap/nodes/expression_node.js\");\r\nconst comment_1 = __webpack_require__(/*! ../1_lexer/tokens/comment */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/comment.js\");\r\nconst pragma_1 = __webpack_require__(/*! ../1_lexer/tokens/pragma */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/pragma.js\");\r\nconst string_1 = __webpack_require__(/*! ../1_lexer/tokens/string */ \"./node_modules/@abaplint/core/build/src/abap/1_lexer/tokens/string.js\");\r\nclass StatementNode extends _abstract_node_1.AbstractNode {\r\n constructor(statement, colon, pragmas) {\r\n super();\r\n this.statement = statement;\r\n this.colon = colon;\r\n if (pragmas) {\r\n this.pragmas = pragmas;\r\n }\r\n else {\r\n this.pragmas = [];\r\n }\r\n }\r\n get() {\r\n return this.statement;\r\n }\r\n getColon() {\r\n return this.colon;\r\n }\r\n getPragmas() {\r\n return this.pragmas;\r\n }\r\n setChildren(children) {\r\n if (children.length === 0) {\r\n throw new Error(\"statement: zero children\");\r\n }\r\n this.children = children;\r\n return this;\r\n }\r\n getStart() {\r\n return this.getFirstToken().getStart();\r\n }\r\n getEnd() {\r\n const last = this.getLastToken();\r\n return last.getEnd();\r\n }\r\n getTokens() {\r\n const tokens = [];\r\n for (const c of this.getChildren()) {\r\n tokens.push(...this.toTokens(c));\r\n }\r\n return tokens;\r\n }\r\n includesToken(search) {\r\n for (const t of this.getTokens()) {\r\n if (t.getStart().equals(search.getStart())) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n getTokenNodes() {\r\n const tokens = [];\r\n for (const c of this.getChildren()) {\r\n tokens.push(...this.toTokenNodess(c));\r\n }\r\n return tokens;\r\n }\r\n concatTokens() {\r\n let str = \"\";\r\n let prev;\r\n for (const token of this.getTokens()) {\r\n if (token instanceof pragma_1.Pragma) {\r\n continue;\r\n }\r\n if (str === \"\") {\r\n str = token.getStr();\r\n }\r\n else if (prev && prev.getStr().length + prev.getCol() === token.getCol()\r\n && prev.getRow() === token.getRow()) {\r\n str = str + token.getStr();\r\n }\r\n else {\r\n str = str + \" \" + token.getStr();\r\n }\r\n prev = token;\r\n }\r\n return str;\r\n }\r\n concatTokensVirtual() {\r\n let str = \"\";\r\n let prev;\r\n for (const token of this.getTokens()) {\r\n if (token instanceof pragma_1.Pragma) {\r\n continue;\r\n }\r\n const vprev = prev === null || prev === void 0 ? void 0 : prev.getStart();\r\n const vtoke = token === null || token === void 0 ? void 0 : token.getStart();\r\n if (str === \"\") {\r\n str = token.getStr();\r\n }\r\n else if (prev && vprev && vtoke\r\n && prev.getStr().length + vprev.vcol === vtoke.vcol\r\n && vprev.vrow === vtoke.vrow) {\r\n str = str + token.getStr();\r\n }\r\n else {\r\n str = str + \" \" + token.getStr();\r\n }\r\n prev = token;\r\n }\r\n return str;\r\n }\r\n concatTokensWithoutStringsAndComments() {\r\n let str = \"\";\r\n let prev;\r\n for (const token of this.getTokens()) {\r\n if (token instanceof comment_1.Comment\r\n || token instanceof string_1.StringToken\r\n || token instanceof string_1.StringTemplate\r\n || token instanceof string_1.StringTemplateBegin\r\n || token instanceof string_1.StringTemplateMiddle\r\n || token instanceof string_1.StringTemplateEnd) {\r\n continue;\r\n }\r\n if (str === \"\") {\r\n str = token.getStr();\r\n }\r\n else if (prev && prev.getStr().length + prev.getCol() === token.getCol()\r\n && prev.getRow() === token.getRow()) {\r\n str = str + token.getStr();\r\n }\r\n else {\r\n str = str + \" \" + token.getStr();\r\n }\r\n prev = token;\r\n }\r\n return str;\r\n }\r\n getTerminator() {\r\n return this.getLastToken().getStr();\r\n }\r\n getFirstToken() {\r\n for (const child of this.getChildren()) {\r\n return child.getFirstToken();\r\n }\r\n throw new Error(\"StatementNode, getFirstToken, no children, \" + this.get().constructor.name);\r\n }\r\n getLastToken() {\r\n const child = this.getLastChild();\r\n if (child !== undefined) {\r\n return child.getLastToken();\r\n }\r\n throw new Error(\"StatementNode, getLastToken, no children\");\r\n }\r\n findDirectExpression(type) {\r\n for (const child of this.getChildren()) {\r\n if (child instanceof expression_node_1.ExpressionNode && child.get() instanceof type) {\r\n return child;\r\n }\r\n }\r\n return undefined;\r\n }\r\n findDirectExpressions(type) {\r\n const ret = [];\r\n for (const child of this.getChildren()) {\r\n if (child instanceof expression_node_1.ExpressionNode && child.get() instanceof type) {\r\n ret.push(child);\r\n }\r\n }\r\n return ret;\r\n }\r\n findDirectTokenByText(text) {\r\n const upper = text.toUpperCase();\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode && child.get().getStr().toUpperCase() === upper) {\r\n return child.get();\r\n }\r\n }\r\n return undefined;\r\n }\r\n findFirstExpression(type) {\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode) {\r\n continue;\r\n }\r\n else if (child.get() instanceof type) {\r\n return child;\r\n }\r\n else {\r\n const res = child.findFirstExpression(type);\r\n if (res) {\r\n return res;\r\n }\r\n }\r\n }\r\n return undefined;\r\n }\r\n findAllExpressions(type) {\r\n const ret = [];\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode) {\r\n continue;\r\n }\r\n else if (child.get() instanceof type) {\r\n ret.push(child);\r\n }\r\n else {\r\n ret.push(...child.findAllExpressions(type));\r\n }\r\n }\r\n return ret;\r\n }\r\n findAllExpressionsRecursive(type) {\r\n const ret = [];\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode) {\r\n continue;\r\n }\r\n else if (child.get() instanceof type) {\r\n ret.push(child);\r\n }\r\n ret.push(...child.findAllExpressionsRecursive(type));\r\n }\r\n return ret;\r\n }\r\n findAllExpressionsMulti(type, recursive = false) {\r\n const ret = [];\r\n for (const child of this.getChildren()) {\r\n if (child instanceof token_node_1.TokenNode) {\r\n continue;\r\n }\r\n const before = ret.length;\r\n for (const t of type) {\r\n if (child.get() instanceof t) {\r\n ret.push(child);\r\n }\r\n }\r\n if (before === ret.length || recursive === true) {\r\n ret.push(...child.findAllExpressionsMulti(type, recursive));\r\n }\r\n }\r\n return ret;\r\n }\r\n /**\r\n * Returns the Position of the first token if the sequence is found,\r\n * otherwise undefined. Strings and Comments are ignored in this search.\r\n * @param first - Text of the first Token\r\n * @param second - Text of the second Token\r\n */\r\n findTokenSequencePosition(first, second) {\r\n let prev;\r\n for (const token of this.getTokens()) {\r\n if (token instanceof comment_1.Comment\r\n || token instanceof string_1.StringToken\r\n || token instanceof string_1.StringTemplate\r\n || token instanceof string_1.StringTemplateBegin\r\n || token instanceof string_1.StringTemplateMiddle\r\n || token instanceof string_1.StringTemplateEnd) {\r\n continue;\r\n }\r\n if (prev && token.getStr().toUpperCase() === second && (prev === null || prev === void 0 ? void 0 : prev.getStr().toUpperCase()) === first.toUpperCase()) {\r\n return prev.getStart();\r\n }\r\n else {\r\n prev = token;\r\n }\r\n }\r\n return undefined;\r\n }\r\n findExpressionAfterToken(text) {\r\n const children = this.getChildren();\r\n for (let i = 0; i < children.length - 1; i++) {\r\n const c = children[i];\r\n const next = children[i + 1];\r\n if (c instanceof token_node_1.TokenNode\r\n && c.get().getStr().toUpperCase() === text.toUpperCase()\r\n && next instanceof expression_node_1.ExpressionNode) {\r\n return next;\r\n }\r\n }\r\n return undefined;\r\n }\r\n findExpressionsAfterToken(text) {\r\n const children = this.getChildren();\r\n const ret = [];\r\n for (let i = 0; i < children.length - 1; i++) {\r\n const c = children[i];\r\n const next = children[i + 1];\r\n if (c instanceof token_node_1.TokenNode\r\n && c.get().getStr().toUpperCase() === text.toUpperCase()\r\n && next instanceof expression_node_1.ExpressionNode) {\r\n ret.push(next);\r\n }\r\n }\r\n return ret;\r\n }\r\n ////////////////////////////////\r\n toTokens(b) {\r\n const tokens = [];\r\n if (b instanceof token_node_1.TokenNode) {\r\n tokens.push(b.get());\r\n return tokens;\r\n }\r\n for (const c of b.getChildren()) {\r\n if (c instanceof token_node_1.TokenNode) {\r\n tokens.push(c.get());\r\n }\r\n else {\r\n tokens.push(...this.toTokens(c));\r\n }\r\n }\r\n return tokens;\r\n }\r\n toTokenNodess(b) {\r\n const tokens = [];\r\n if (b instanceof token_node_1.TokenNode) {\r\n tokens.push(b);\r\n return tokens;\r\n }\r\n for (const c of b.getChildren()) {\r\n if (c instanceof token_node_1.TokenNode) {\r\n tokens.push(c);\r\n }\r\n else {\r\n tokens.push(...this.toTokenNodess(c));\r\n }\r\n }\r\n return tokens;\r\n }\r\n}\r\nexports.StatementNode = StatementNode;\r\n//# sourceMappingURL=statement_node.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/abap/nodes/statement_node.js?");
8952
8952
 
8953
8953
  /***/ }),
8954
8954
 
@@ -11786,7 +11786,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
11786
11786
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
11787
11787
 
11788
11788
  "use strict";
11789
- 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 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 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\");\nconst rules_runner_1 = __webpack_require__(/*! ./rules_runner */ \"./node_modules/@abaplint/core/build/src/rules_runner.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 this.dependencies = {};\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.95.0\";\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 // todo: performance? cache regexp?\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, dependency) {\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 let found = this.findOrCreate(f.getObjectName(), f.getObjectType());\n if (dependency === false && found && this.isDependency(found)) {\n this.removeDependency(found);\n found = this.findOrCreate(f.getObjectName(), f.getObjectType());\n }\n found.addFile(f);\n }\n return this;\n }\n addFiles(files) {\n this._addFiles(files, false);\n return this;\n }\n addDependencies(files) {\n for (const f of files) {\n this.addDependency(f);\n }\n return this;\n }\n addDependency(file) {\n var _a;\n const type = (_a = file.getObjectType()) === null || _a === void 0 ? void 0 : _a.toUpperCase();\n if (type === undefined) {\n return this;\n }\n const name = file.getObjectName().toUpperCase();\n if (this.dependencies[type] === undefined) {\n this.dependencies[type] = {};\n }\n this.dependencies[type][name] = true;\n this._addFiles([file], true);\n return this;\n }\n removeDependency(obj) {\n var _a;\n (_a = this.dependencies[obj.getType()]) === null || _a === void 0 ? true : delete _a[obj.getName()];\n this.removeObject(obj);\n }\n isDependency(obj) {\n var _a;\n return ((_a = this.dependencies[obj.getType()]) === null || _a === void 0 ? void 0 : _a[obj.getName()]) === true;\n }\n isFileDependency(filename) {\n var _a, _b;\n const f = this.getFileByName(filename);\n if (f === undefined) {\n return false;\n }\n const type = (_a = f.getObjectType()) === null || _a === void 0 ? void 0 : _a.toUpperCase();\n if (type === undefined) {\n return false;\n }\n const name = f.getObjectName().toUpperCase();\n return ((_b = this.dependencies[type]) === null || _b === void 0 ? void 0 : _b[name]) === 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 new rules_runner_1.RulesRunner(this).runRules(this.getObjects(), 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 new rules_runner_1.RulesRunner(this).runRules([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 for (const o of this.getObjects()) {\n this.parsePrivate(o);\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 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 }\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, this);\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 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?");
11789
+ 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 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 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\");\nconst rules_runner_1 = __webpack_require__(/*! ./rules_runner */ \"./node_modules/@abaplint/core/build/src/rules_runner.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 this.dependencies = {};\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.95.2\";\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 // todo: performance? cache regexp?\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, dependency) {\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 let found = this.findOrCreate(f.getObjectName(), f.getObjectType());\n if (dependency === false && found && this.isDependency(found)) {\n this.removeDependency(found);\n found = this.findOrCreate(f.getObjectName(), f.getObjectType());\n }\n found.addFile(f);\n }\n return this;\n }\n addFiles(files) {\n this._addFiles(files, false);\n return this;\n }\n addDependencies(files) {\n for (const f of files) {\n this.addDependency(f);\n }\n return this;\n }\n addDependency(file) {\n var _a;\n const type = (_a = file.getObjectType()) === null || _a === void 0 ? void 0 : _a.toUpperCase();\n if (type === undefined) {\n return this;\n }\n const name = file.getObjectName().toUpperCase();\n if (this.dependencies[type] === undefined) {\n this.dependencies[type] = {};\n }\n this.dependencies[type][name] = true;\n this._addFiles([file], true);\n return this;\n }\n removeDependency(obj) {\n var _a;\n (_a = this.dependencies[obj.getType()]) === null || _a === void 0 ? true : delete _a[obj.getName()];\n this.removeObject(obj);\n }\n isDependency(obj) {\n var _a;\n return ((_a = this.dependencies[obj.getType()]) === null || _a === void 0 ? void 0 : _a[obj.getName()]) === true;\n }\n isFileDependency(filename) {\n var _a, _b;\n const f = this.getFileByName(filename);\n if (f === undefined) {\n return false;\n }\n const type = (_a = f.getObjectType()) === null || _a === void 0 ? void 0 : _a.toUpperCase();\n if (type === undefined) {\n return false;\n }\n const name = f.getObjectName().toUpperCase();\n return ((_b = this.dependencies[type]) === null || _b === void 0 ? void 0 : _b[name]) === 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 new rules_runner_1.RulesRunner(this).runRules(this.getObjects(), 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 new rules_runner_1.RulesRunner(this).runRules([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 for (const o of this.getObjects()) {\n this.parsePrivate(o);\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 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 }\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, this);\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 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?");
11790
11790
 
11791
11791
  /***/ }),
11792
11792
 
@@ -12314,7 +12314,7 @@ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\n
12314
12314
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
12315
12315
 
12316
12316
  "use strict";
12317
- eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.ExpandMacros = exports.ExpandMacrosConf = 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\nconst position_1 = __webpack_require__(/*! ../position */ \"./node_modules/@abaplint/core/build/src/position.js\");\r\nclass ExpandMacrosConf extends _basic_rule_config_1.BasicRuleConfig {\r\n}\r\nexports.ExpandMacrosConf = ExpandMacrosConf;\r\nclass ExpandMacros extends _abap_rule_1.ABAPRule {\r\n constructor() {\r\n super(...arguments);\r\n this.conf = new ExpandMacrosConf();\r\n }\r\n getMetadata() {\r\n return {\r\n key: \"expand_macros\",\r\n title: \"Expand Macros\",\r\n shortDescription: `Allows expanding macro calls with quick fixes`,\r\n extendedInformation: `Macros: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abenmacros_guidl.htm\r\n\r\nNote that macros/DEFINE cannot be used in the ABAP Cloud programming model`,\r\n badExample: `DEFINE _hello.\r\n WRITE 'hello'.\r\nEND-OF-DEFINITION.\r\n_hello.`,\r\n goodExample: `WRITE 'hello'.`,\r\n tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.Upport],\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 const issues = [];\r\n const message = \"Expand macro call\";\r\n const statements = file.getStatements();\r\n for (let i = 0; i < statements.length; i++) {\r\n const statementNode = statements[i];\r\n const statement = statementNode.get();\r\n if (!(statement instanceof _statement_1.MacroCall)) {\r\n continue;\r\n }\r\n let replace = \"\";\r\n for (let j = i + 1; j < statements.length; j++) {\r\n const sub = statements[j];\r\n if (sub.getFirstToken().getStart() instanceof position_1.VirtualPosition) {\r\n replace += sub.concatTokens();\r\n }\r\n else {\r\n break;\r\n }\r\n }\r\n const fix = edit_helper_1.EditHelper.replaceRange(file, statementNode.getStart(), statementNode.getEnd(), replace);\r\n issues.push(issue_1.Issue.atStatement(file, statementNode, message, this.getMetadata().key, this.conf.severity, fix));\r\n }\r\n return issues;\r\n }\r\n}\r\nexports.ExpandMacros = ExpandMacros;\r\n//# sourceMappingURL=expand_macros.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/rules/expand_macros.js?");
12317
+ eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.ExpandMacros = exports.ExpandMacrosConf = 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\nconst position_1 = __webpack_require__(/*! ../position */ \"./node_modules/@abaplint/core/build/src/position.js\");\r\nclass ExpandMacrosConf extends _basic_rule_config_1.BasicRuleConfig {\r\n}\r\nexports.ExpandMacrosConf = ExpandMacrosConf;\r\nclass ExpandMacros extends _abap_rule_1.ABAPRule {\r\n constructor() {\r\n super(...arguments);\r\n this.conf = new ExpandMacrosConf();\r\n }\r\n getMetadata() {\r\n return {\r\n key: \"expand_macros\",\r\n title: \"Expand Macros\",\r\n shortDescription: `Allows expanding macro calls with quick fixes`,\r\n extendedInformation: `Macros: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abenmacros_guidl.htm\r\n\r\nNote that macros/DEFINE cannot be used in the ABAP Cloud programming model`,\r\n badExample: `DEFINE _hello.\r\n WRITE 'hello'.\r\nEND-OF-DEFINITION.\r\n_hello.`,\r\n goodExample: `WRITE 'hello'.`,\r\n tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Quickfix, _irule_1.RuleTag.Upport],\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 const issues = [];\r\n const message = \"Expand macro call\";\r\n const statements = file.getStatements();\r\n for (let i = 0; i < statements.length; i++) {\r\n const statementNode = statements[i];\r\n const statement = statementNode.get();\r\n if (!(statement instanceof _statement_1.MacroCall)) {\r\n continue;\r\n }\r\n let replace = \"\";\r\n for (let j = i + 1; j < statements.length; j++) {\r\n const sub = statements[j];\r\n if (sub.getFirstToken().getStart() instanceof position_1.VirtualPosition) {\r\n if (replace !== \"\") {\r\n replace += \"\\n\";\r\n }\r\n replace += sub.concatTokensVirtual();\r\n }\r\n else {\r\n break;\r\n }\r\n }\r\n if (statementNode.getColon()) {\r\n replace += \"\\n\";\r\n }\r\n const fix1 = edit_helper_1.EditHelper.deleteStatement(file, statementNode);\r\n const fix2 = edit_helper_1.EditHelper.insertAt(file, statementNode.getStart(), replace);\r\n const fix = edit_helper_1.EditHelper.merge(fix1, fix2);\r\n issues.push(issue_1.Issue.atStatement(file, statementNode, message, this.getMetadata().key, this.conf.severity, fix));\r\n // only one fix at a time per file\r\n break;\r\n }\r\n return issues;\r\n }\r\n}\r\nexports.ExpandMacros = ExpandMacros;\r\n//# sourceMappingURL=expand_macros.js.map\n\n//# sourceURL=webpack://@abaplint/cli/./node_modules/@abaplint/core/build/src/rules/expand_macros.js?");
12318
12318
 
12319
12319
  /***/ }),
12320
12320
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.95.0",
3
+ "version": "2.95.2",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "bin": {
6
6
  "abaplint": "./abaplint"
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "homepage": "https://abaplint.org",
39
39
  "devDependencies": {
40
- "@abaplint/core": "^2.95.0",
40
+ "@abaplint/core": "^2.95.2",
41
41
  "@types/chai": "^4.3.4",
42
42
  "@types/glob": "^7.2.0",
43
43
  "@types/minimist": "^1.2.2",