@abaplint/core 2.91.4 → 2.91.7
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/abaplint.d.ts +1 -0
- package/build/src/abap/2_statements/expressions/select.js +1 -2
- package/build/src/abap/2_statements/expressions/select_loop.js +1 -2
- package/build/src/abap/2_statements/expressions/sql_client.js +2 -1
- package/build/src/abap/2_statements/statements/append.js +4 -2
- package/build/src/abap/2_statements/statements/delete_internal.js +3 -2
- package/build/src/abap/2_statements/statements/insert_database.js +3 -4
- package/build/src/abap/2_statements/statements/modify_database.js +1 -2
- package/build/src/abap/5_syntax/_current_scope.js +3 -0
- package/build/src/abap/5_syntax/statements/move_corresponding.js +15 -4
- package/build/src/registry.js +1 -1
- package/build/src/rules/obsolete_statement.js +19 -2
- package/package.json +5 -5
package/build/abaplint.d.ts
CHANGED
|
@@ -1124,6 +1124,7 @@ export declare class CurrentScope {
|
|
|
1124
1124
|
static buildDefault(reg: IRegistry, obj: IObject): CurrentScope;
|
|
1125
1125
|
private static addBuiltIn;
|
|
1126
1126
|
private constructor();
|
|
1127
|
+
getVersion(): Version;
|
|
1127
1128
|
addType(type: TypedIdentifier | undefined): void;
|
|
1128
1129
|
addTypeNamed(name: string, type: TypedIdentifier | undefined): void;
|
|
1129
1130
|
addExtraLikeType(type: TypedIdentifier | undefined): void;
|
|
@@ -14,10 +14,9 @@ class Select extends combi_1.Expression {
|
|
|
14
14
|
const into = (0, combi_1.altPrio)(_1.SQLIntoTable, sql_into_structure_1.SQLIntoStructure);
|
|
15
15
|
const where = (0, combi_1.seq)("WHERE", _1.SQLCond);
|
|
16
16
|
const offset = (0, combi_1.ver)(version_1.Version.v751, (0, combi_1.seq)("OFFSET", _1.SQLSource));
|
|
17
|
-
const client = (0, combi_1.str)("CLIENT SPECIFIED");
|
|
18
17
|
const bypass = (0, combi_1.str)("BYPASSING BUFFER");
|
|
19
18
|
const fields = (0, combi_1.seq)("FIELDS", _1.SQLFieldList);
|
|
20
|
-
const perm = (0, combi_1.per)(_1.SQLFrom, into, _1.SQLForAllEntries, where, _1.SQLOrderBy, sql_up_to_1.SQLUpTo, offset,
|
|
19
|
+
const perm = (0, combi_1.per)(_1.SQLFrom, into, _1.SQLForAllEntries, where, _1.SQLOrderBy, sql_up_to_1.SQLUpTo, offset, _1.SQLClient, _1.SQLHaving, bypass, sql_group_by_1.SQLGroupBy, fields, _1.DatabaseConnection);
|
|
21
20
|
const paren = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), sql_field_name_1.SQLFieldName, (0, combi_1.tok)(tokens_1.WParenRightW));
|
|
22
21
|
const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)("DISTINCT", (0, combi_1.optPrio)((0, combi_1.seq)("SINGLE", (0, combi_1.optPrio)("FOR UPDATE")))), (0, combi_1.optPrio)((0, combi_1.altPrio)(_1.SQLFieldList, paren)), perm, (0, combi_1.optPrio)(_1.SQLHints));
|
|
23
22
|
return ret;
|
|
@@ -13,11 +13,10 @@ const sql_up_to_1 = require("./sql_up_to");
|
|
|
13
13
|
class SelectLoop extends combi_1.Expression {
|
|
14
14
|
getRunnable() {
|
|
15
15
|
const where = (0, combi_1.seq)("WHERE", _1.SQLCond);
|
|
16
|
-
const client = "CLIENT SPECIFIED";
|
|
17
16
|
const bypass = "BYPASSING BUFFER";
|
|
18
17
|
const pack = (0, combi_1.seq)("PACKAGE SIZE", _1.SQLSource);
|
|
19
18
|
const tab = (0, combi_1.seq)(_1.SQLIntoTable, (0, combi_1.alt)(pack, (0, combi_1.seq)(_1.SQLFrom, pack), (0, combi_1.seq)(pack, _1.SQLFrom)));
|
|
20
|
-
const perm = (0, combi_1.per)(_1.SQLFrom, where, sql_up_to_1.SQLUpTo, sql_order_by_1.SQLOrderBy, sql_having_1.SQLHaving,
|
|
19
|
+
const perm = (0, combi_1.per)(_1.SQLFrom, where, sql_up_to_1.SQLUpTo, sql_order_by_1.SQLOrderBy, sql_having_1.SQLHaving, _1.SQLClient, bypass, _1.SQLGroupBy, _1.SQLForAllEntries, (0, combi_1.alt)(tab, sql_into_structure_1.SQLIntoStructure));
|
|
21
20
|
const strict = (0, combi_1.seq)(_1.SQLFrom, "FIELDS", sql_field_list_1.SQLFieldList, where, sql_into_structure_1.SQLIntoStructure, sql_up_to_1.SQLUpTo);
|
|
22
21
|
const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.optPrio)("DISTINCT"), sql_field_list_loop_1.SQLFieldListLoop, perm), strict), (0, combi_1.optPrio)(sql_hints_1.SQLHints));
|
|
23
22
|
return ret;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SQLClient = void 0;
|
|
4
|
+
const version_1 = require("../../../version");
|
|
4
5
|
const combi_1 = require("../combi");
|
|
5
6
|
const sql_source_simple_1 = require("./sql_source_simple");
|
|
6
7
|
class SQLClient extends combi_1.Expression {
|
|
7
8
|
getRunnable() {
|
|
8
9
|
// todo, client specified and connection not possible in Cloud
|
|
9
|
-
const client = (0, combi_1.alt)("CLIENT SPECIFIED", (0, combi_1.seq)("USING CLIENT", sql_source_simple_1.SQLSourceSimple));
|
|
10
|
+
const client = (0, combi_1.alt)("CLIENT SPECIFIED", (0, combi_1.seq)("USING", (0, combi_1.alt)((0, combi_1.ver)(version_1.Version.v740sp05, (0, combi_1.seq)("CLIENT", sql_source_simple_1.SQLSourceSimple)), (0, combi_1.ver)(version_1.Version.v754, (0, combi_1.seq)("CLIENTS IN", (0, combi_1.alt)(sql_source_simple_1.SQLSourceSimple, "T000"))), (0, combi_1.ver)(version_1.Version.v754, "ALL CLIENTS"))));
|
|
10
11
|
return client;
|
|
11
12
|
}
|
|
12
13
|
}
|
|
@@ -9,9 +9,11 @@ class Append {
|
|
|
9
9
|
const assigning = (0, combi_1.seq)("ASSIGNING", expressions_1.FSTarget);
|
|
10
10
|
const reference = (0, combi_1.seq)("REFERENCE INTO", expressions_1.Target);
|
|
11
11
|
const sorted = (0, combi_1.seq)("SORTED BY", expressions_1.Field);
|
|
12
|
-
const
|
|
12
|
+
const fromIndex = (0, combi_1.seq)("FROM", expressions_1.Source);
|
|
13
|
+
const toIndex = (0, combi_1.seq)("TO", expressions_1.Source);
|
|
14
|
+
const toTarget = (0, combi_1.seq)("TO", expressions_1.Target);
|
|
13
15
|
const src = (0, combi_1.alt)(expressions_1.SimpleSource4, (0, combi_1.ver)(version_1.Version.v740sp02, expressions_1.Source));
|
|
14
|
-
return (0, combi_1.seq)("APPEND", (0, combi_1.altPrio)("INITIAL LINE", (0, combi_1.seq)((0, combi_1.optPrio)("LINES OF"), src)), (0, combi_1.
|
|
16
|
+
return (0, combi_1.seq)("APPEND", (0, combi_1.altPrio)("INITIAL LINE", (0, combi_1.seq)((0, combi_1.optPrio)("LINES OF"), src)), (0, combi_1.optPrio)(fromIndex), (0, combi_1.opt)((0, combi_1.alt)((0, combi_1.seq)(toIndex, toTarget), toTarget)), (0, combi_1.opt)((0, combi_1.altPrio)(assigning, reference)), (0, combi_1.optPrio)("CASTING"), (0, combi_1.optPrio)(sorted));
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
exports.Append = Append;
|
|
@@ -9,10 +9,11 @@ class DeleteInternal {
|
|
|
9
9
|
const index = (0, combi_1.seq)("INDEX", expressions_1.Source);
|
|
10
10
|
const keyName = (0, combi_1.altPrio)(expressions_1.SimpleName, expressions_1.Dynamic);
|
|
11
11
|
const using = (0, combi_1.seq)("USING KEY", keyName);
|
|
12
|
-
const
|
|
12
|
+
const from = (0, combi_1.optPrio)((0, combi_1.seq)("FROM", expressions_1.Source));
|
|
13
|
+
const fromTo = (0, combi_1.seq)(from, (0, combi_1.optPrio)((0, combi_1.seq)("TO", expressions_1.Source)));
|
|
13
14
|
const where = (0, combi_1.seq)("WHERE", (0, combi_1.alt)(expressions_1.ComponentCond, expressions_1.Dynamic));
|
|
14
15
|
const key = (0, combi_1.seq)("WITH TABLE KEY", (0, combi_1.opt)((0, combi_1.seq)(keyName, "COMPONENTS")), (0, combi_1.plus)(expressions_1.ComponentCompare));
|
|
15
|
-
const table = (0, combi_1.seq)("TABLE", expressions_1.Target, (0, combi_1.alt)((0, combi_1.per)(index, using),
|
|
16
|
+
const table = (0, combi_1.seq)("TABLE", expressions_1.Target, (0, combi_1.alt)((0, combi_1.per)(index, using), from, key));
|
|
16
17
|
const other = (0, combi_1.seq)(expressions_1.Target, (0, combi_1.alt)((0, combi_1.per)(index, using), fromTo, key), (0, combi_1.opt)(where));
|
|
17
18
|
const f = (0, combi_1.seq)(expressions_1.FieldSub, (0, combi_1.optPrio)(expressions_1.FieldOffset), (0, combi_1.optPrio)(expressions_1.FieldLength));
|
|
18
19
|
const adjacent = (0, combi_1.seq)("ADJACENT DUPLICATES FROM", expressions_1.Target, (0, combi_1.optPrio)(using), (0, combi_1.opt)((0, combi_1.seq)("COMPARING", (0, combi_1.altPrio)("ALL FIELDS", (0, combi_1.plus)((0, combi_1.altPrio)(f, expressions_1.Dynamic))))), (0, combi_1.optPrio)(using));
|
|
@@ -6,11 +6,10 @@ const expressions_1 = require("../expressions");
|
|
|
6
6
|
const tokens_1 = require("../../1_lexer/tokens");
|
|
7
7
|
class InsertDatabase {
|
|
8
8
|
getMatcher() {
|
|
9
|
-
const client = (0, combi_1.str)("CLIENT SPECIFIED");
|
|
10
9
|
const sub = (0, combi_1.seq)((0, combi_1.tok)(tokens_1.WParenLeftW), expressions_1.Select, (0, combi_1.tok)(tokens_1.WParenRightW));
|
|
11
|
-
const f = (0, combi_1.seq)((0, combi_1.opt)(
|
|
12
|
-
const from = (0, combi_1.seq)(expressions_1.DatabaseTable, (0, combi_1.opt)((0, combi_1.alt)(f,
|
|
13
|
-
const into = (0, combi_1.seq)("INTO", expressions_1.DatabaseTable, (0, combi_1.opt)(
|
|
10
|
+
const f = (0, combi_1.seq)((0, combi_1.opt)(expressions_1.SQLClient), (0, combi_1.opt)(expressions_1.DatabaseConnection), "FROM", (0, combi_1.opt)("TABLE"), (0, combi_1.alt)(expressions_1.SQLSource, sub), (0, combi_1.opt)("ACCEPTING DUPLICATE KEYS"));
|
|
11
|
+
const from = (0, combi_1.seq)(expressions_1.DatabaseTable, (0, combi_1.opt)((0, combi_1.alt)(f, expressions_1.SQLClient, expressions_1.DatabaseConnection)));
|
|
12
|
+
const into = (0, combi_1.seq)("INTO", expressions_1.DatabaseTable, (0, combi_1.opt)(expressions_1.SQLClient), (0, combi_1.opt)(expressions_1.DatabaseConnection), "VALUES", expressions_1.SQLSource);
|
|
14
13
|
return (0, combi_1.seq)("INSERT", (0, combi_1.alt)(from, into));
|
|
15
14
|
}
|
|
16
15
|
}
|
|
@@ -6,8 +6,7 @@ const expressions_1 = require("../expressions");
|
|
|
6
6
|
class ModifyDatabase {
|
|
7
7
|
getMatcher() {
|
|
8
8
|
const from = (0, combi_1.seq)("FROM", (0, combi_1.opt)("TABLE"), expressions_1.SQLSource);
|
|
9
|
-
const
|
|
10
|
-
const options = (0, combi_1.per)(expressions_1.DatabaseConnection, from, client);
|
|
9
|
+
const options = (0, combi_1.per)(expressions_1.DatabaseConnection, from, expressions_1.SQLClient);
|
|
11
10
|
return (0, combi_1.seq)("MODIFY", expressions_1.DatabaseTable, options);
|
|
12
11
|
}
|
|
13
12
|
}
|
|
@@ -4,13 +4,24 @@ exports.MoveCorresponding = void 0;
|
|
|
4
4
|
const Expressions = require("../../2_statements/expressions");
|
|
5
5
|
const source_1 = require("../expressions/source");
|
|
6
6
|
const target_1 = require("../expressions/target");
|
|
7
|
+
const version_1 = require("../../../version");
|
|
8
|
+
const basic_1 = require("../../types/basic");
|
|
7
9
|
class MoveCorresponding {
|
|
8
10
|
runSyntax(node, scope, filename) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
const s = node.findDirectExpression(Expressions.Source);
|
|
12
|
+
const t = node.findDirectExpression(Expressions.Target);
|
|
13
|
+
if (s === undefined || t === undefined) {
|
|
14
|
+
throw new Error("MoveCorresponding, source or target not found");
|
|
11
15
|
}
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const sourceType = new source_1.Source().runSyntax(s, scope, filename);
|
|
17
|
+
const targetType = new target_1.Target().runSyntax(t, scope, filename);
|
|
18
|
+
if (scope.getVersion() < version_1.Version.v740sp05) {
|
|
19
|
+
if (sourceType instanceof basic_1.TableType && sourceType.isWithHeader() === false) {
|
|
20
|
+
throw new Error("MOVE-CORRESPONSING with tables possible from v740sp05");
|
|
21
|
+
}
|
|
22
|
+
else if (targetType instanceof basic_1.TableType && targetType.isWithHeader() === false) {
|
|
23
|
+
throw new Error("MOVE-CORRESPONSING with tables possible from v740sp05");
|
|
24
|
+
}
|
|
14
25
|
}
|
|
15
26
|
}
|
|
16
27
|
}
|
package/build/src/registry.js
CHANGED
|
@@ -65,6 +65,8 @@ class ObsoleteStatementConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
65
65
|
this.regex = true;
|
|
66
66
|
/** Check for OCCURENCES vs OCCURRENCES usage */
|
|
67
67
|
this.occurences = true;
|
|
68
|
+
/** Check for CLIENT SPECIFIED */
|
|
69
|
+
this.clientSpecified = true;
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
exports.ObsoleteStatementConf = ObsoleteStatementConf;
|
|
@@ -119,7 +121,9 @@ CALL TRANSFORMATION OBJECTS: https://help.sap.com/doc/abapdocu_752_index_htm/7.5
|
|
|
119
121
|
|
|
120
122
|
POSIX REGEX: https://help.sap.com/doc/abapdocu_755_index_htm/7.55/en-US/index.htm
|
|
121
123
|
|
|
122
|
-
OCCURENCES: check for OCCURENCES vs OCCURRENCES
|
|
124
|
+
OCCURENCES: check for OCCURENCES vs OCCURRENCES
|
|
125
|
+
|
|
126
|
+
CLIENT SPECIFIED, from 754: https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapselect_client_obsolete.htm`,
|
|
123
127
|
};
|
|
124
128
|
}
|
|
125
129
|
getConfig() {
|
|
@@ -229,7 +233,7 @@ OCCURENCES: check for OCCURENCES vs OCCURRENCES`,
|
|
|
229
233
|
}
|
|
230
234
|
if (this.conf.withHeaderLine === true && sta instanceof Statements.Data) {
|
|
231
235
|
if (staNode.concatTokens().toUpperCase().includes("WITH HEADER LINE")) {
|
|
232
|
-
const token = staNode.
|
|
236
|
+
const token = staNode.getTokens().find(t => t.getStr().toUpperCase() === "WITH");
|
|
233
237
|
if (token) {
|
|
234
238
|
const issue = issue_1.Issue.atToken(file, token, "WITH HEADER LINE is obsolete", this.getMetadata().key, this.conf.severity);
|
|
235
239
|
issues.push(issue);
|
|
@@ -283,6 +287,19 @@ OCCURENCES: check for OCCURENCES vs OCCURRENCES`,
|
|
|
283
287
|
issues.push(issue);
|
|
284
288
|
}
|
|
285
289
|
}
|
|
290
|
+
if (configVersion >= version_1.Version.v754 && this.conf.clientSpecified
|
|
291
|
+
&& (sta instanceof Statements.Select
|
|
292
|
+
|| sta instanceof Statements.SelectLoop
|
|
293
|
+
|| sta instanceof Statements.DeleteDatabase
|
|
294
|
+
|| sta instanceof Statements.InsertDatabase
|
|
295
|
+
|| sta instanceof Statements.ModifyDatabase
|
|
296
|
+
|| sta instanceof Statements.UpdateDatabase)) {
|
|
297
|
+
const concat = staNode.concatTokens().toUpperCase();
|
|
298
|
+
if (concat.includes(" CLIENT SPECIFIED")) {
|
|
299
|
+
const issue = issue_1.Issue.atStatement(file, staNode, "Use USING CLIENT", this.getMetadata().key, this.conf.severity);
|
|
300
|
+
issues.push(issue);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
286
303
|
if (configVersion >= version_1.Version.v756 && this.conf.regex) {
|
|
287
304
|
if (sta instanceof Statements.Find || sta instanceof Statements.Replace) {
|
|
288
305
|
if ((_c = staNode.findFirstExpression(Expressions.FindType)) === null || _c === void 0 ? void 0 : _c.concatTokens().includes("REGEX")) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.91.
|
|
3
|
+
"version": "2.91.7",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -45,17 +45,17 @@
|
|
|
45
45
|
},
|
|
46
46
|
"homepage": "https://abaplint.org",
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@microsoft/api-extractor": "^7.
|
|
48
|
+
"@microsoft/api-extractor": "^7.28.3",
|
|
49
49
|
"@types/chai": "^4.3.1",
|
|
50
50
|
"@types/mocha": "^9.1.1",
|
|
51
|
-
"@types/node": "^18.0.
|
|
51
|
+
"@types/node": "^18.0.3",
|
|
52
52
|
"chai": "^4.3.6",
|
|
53
|
-
"eslint": "^8.
|
|
53
|
+
"eslint": "^8.19.0",
|
|
54
54
|
"mocha": "^10.0.0",
|
|
55
55
|
"c8": "^7.11.3",
|
|
56
56
|
"source-map-support": "^0.5.21",
|
|
57
57
|
"ts-json-schema-generator": "^1.0.0",
|
|
58
|
-
"typescript": "^4.7.
|
|
58
|
+
"typescript": "^4.7.4"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"fast-xml-parser": "^4.0.8",
|