@abaplint/core 2.119.44 → 2.119.46
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 +360 -5
- package/build/src/abap/2_statements/expressions/_select_core.js +9 -7
- package/build/src/abap/2_statements/expressions/assign_source.js +9 -3
- package/build/src/abap/2_statements/expressions/database_table.js +8 -0
- package/build/src/abap/2_statements/expressions/select.js +1 -1
- package/build/src/abap/2_statements/expressions/select_cte.js +2 -1
- package/build/src/abap/2_statements/expressions/sql_client.js +1 -1
- package/build/src/abap/2_statements/expressions/sql_from.js +9 -8
- package/build/src/abap/2_statements/expressions/sql_from_source.js +2 -1
- package/build/src/abap/2_statements/statements/add.js +2 -1
- package/build/src/abap/2_statements/statements/assert.js +2 -1
- package/build/src/abap/2_statements/statements/assign.js +8 -3
- package/build/src/abap/2_statements/statements/at.js +2 -1
- package/build/src/abap/2_statements/statements/authority_check.js +2 -1
- package/build/src/abap/2_statements/statements/call.js +2 -1
- package/build/src/abap/2_statements/statements/call_function.js +1 -1
- package/build/src/abap/2_statements/statements/call_transformation.js +2 -1
- package/build/src/abap/2_statements/statements/class_deferred.js +2 -1
- package/build/src/abap/2_statements/statements/class_definition_load.js +2 -1
- package/build/src/abap/2_statements/statements/commit.js +2 -1
- package/build/src/abap/2_statements/statements/commit_entities.js +1 -1
- package/build/src/abap/2_statements/statements/create_data.js +1 -1
- package/build/src/abap/2_statements/statements/create_object.js +1 -1
- package/build/src/abap/2_statements/statements/delete_database.js +2 -1
- package/build/src/abap/2_statements/statements/delete_internal.js +3 -1
- package/build/src/abap/2_statements/statements/divide.js +2 -1
- package/build/src/abap/2_statements/statements/endform.js +2 -2
- package/build/src/abap/2_statements/statements/endfunction.js +2 -1
- package/build/src/abap/2_statements/statements/endwith.js +1 -1
- package/build/src/abap/2_statements/statements/export.js +4 -3
- package/build/src/abap/2_statements/statements/form.js +2 -1
- package/build/src/abap/2_statements/statements/free.js +2 -1
- package/build/src/abap/2_statements/statements/function_module.js +2 -1
- package/build/src/abap/2_statements/statements/function_pool.js +2 -1
- package/build/src/abap/2_statements/statements/get_reference.js +2 -1
- package/build/src/abap/2_statements/statements/get_time.js +2 -1
- package/build/src/abap/2_statements/statements/import.js +5 -4
- package/build/src/abap/2_statements/statements/insert_database.js +2 -1
- package/build/src/abap/2_statements/statements/interface_deferred.js +2 -1
- package/build/src/abap/2_statements/statements/interface_load.js +2 -1
- package/build/src/abap/2_statements/statements/loop.js +1 -1
- package/build/src/abap/2_statements/statements/loop_extract.js +2 -1
- package/build/src/abap/2_statements/statements/message.js +2 -1
- package/build/src/abap/2_statements/statements/method_def.js +8 -4
- package/build/src/abap/2_statements/statements/method_implementation.js +3 -1
- package/build/src/abap/2_statements/statements/modify_database.js +2 -1
- package/build/src/abap/2_statements/statements/multiply.js +2 -1
- package/build/src/abap/2_statements/statements/perform.js +1 -1
- package/build/src/abap/2_statements/statements/raise.js +2 -1
- package/build/src/abap/2_statements/statements/raise_entity_event.js +2 -1
- package/build/src/abap/2_statements/statements/raise_event.js +2 -1
- package/build/src/abap/2_statements/statements/read_table.js +3 -2
- package/build/src/abap/2_statements/statements/rollback.js +2 -1
- package/build/src/abap/2_statements/statements/rollback_entities.js +1 -1
- package/build/src/abap/2_statements/statements/set_handler.js +2 -1
- package/build/src/abap/2_statements/statements/set_locks.js +1 -1
- package/build/src/abap/2_statements/statements/static.js +3 -2
- package/build/src/abap/2_statements/statements/subtract.js +2 -1
- package/build/src/abap/2_statements/statements/test_injection.js +2 -1
- package/build/src/abap/2_statements/statements/test_seam.js +1 -1
- package/build/src/abap/2_statements/statements/update_database.js +4 -3
- package/build/src/abap/2_statements/statements/wait.js +4 -3
- package/build/src/abap/2_statements/statements/with.js +1 -1
- package/build/src/abap/5_syntax/_current_scope.js +1 -2
- package/build/src/abap/5_syntax/expressions/select.js +15 -3
- package/build/src/abap/5_syntax/statements/delete_internal.js +4 -3
- package/build/src/abap/5_syntax/statements/loop.js +8 -0
- package/build/src/abap/5_syntax/statements/modify_internal.js +7 -0
- package/build/src/abap/5_syntax/statements/select_loop.js +1 -1
- package/build/src/cds/cds_parser.js +8 -8
- package/build/src/config.js +24 -15
- package/build/src/ddl/ddl_parser.js +2 -2
- package/build/src/registry.js +1 -1
- package/build/src/rules/index.js +1 -0
- package/build/src/rules/sy_read_restriction.js +152 -0
- package/build/src/version.js +2 -65
- package/package.json +1 -1
|
@@ -3,9 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Rollback = void 0;
|
|
4
4
|
const combi_1 = require("../combi");
|
|
5
5
|
const expressions_1 = require("../expressions");
|
|
6
|
+
const version_1 = require("../../../version");
|
|
6
7
|
class Rollback {
|
|
7
8
|
getMatcher() {
|
|
8
|
-
return (0, combi_1.seq)("ROLLBACK", (0, combi_1.altPrio)("WORK", expressions_1.DatabaseConnection));
|
|
9
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.seq)("ROLLBACK", (0, combi_1.altPrio)("WORK", expressions_1.DatabaseConnection)));
|
|
9
10
|
}
|
|
10
11
|
}
|
|
11
12
|
exports.Rollback = Rollback;
|
|
@@ -6,7 +6,7 @@ const version_1 = require("../../../version");
|
|
|
6
6
|
class RollbackEntities {
|
|
7
7
|
getMatcher() {
|
|
8
8
|
const s = "ROLLBACK ENTITIES";
|
|
9
|
-
return (0, combi_1.ver)(version_1.Release.v754, s);
|
|
9
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.ver)(version_1.Release.v754, s));
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
exports.RollbackEntities = RollbackEntities;
|
|
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SetHandler = void 0;
|
|
4
4
|
const combi_1 = require("../combi");
|
|
5
5
|
const expressions_1 = require("../expressions");
|
|
6
|
+
const version_1 = require("../../../version");
|
|
6
7
|
class SetHandler {
|
|
7
8
|
getMatcher() {
|
|
8
9
|
const activation = (0, combi_1.seq)("ACTIVATION", expressions_1.Source);
|
|
9
10
|
const fo = (0, combi_1.seq)("FOR", (0, combi_1.altPrio)("ALL INSTANCES", expressions_1.Source));
|
|
10
11
|
const ret = (0, combi_1.seq)("SET HANDLER", (0, combi_1.plus)(expressions_1.MethodSource), (0, combi_1.optPrio)(fo), (0, combi_1.optPrio)(activation));
|
|
11
|
-
return ret;
|
|
12
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, ret);
|
|
12
13
|
}
|
|
13
14
|
}
|
|
14
15
|
exports.SetHandler = SetHandler;
|
|
@@ -7,7 +7,7 @@ const version_1 = require("../../../version");
|
|
|
7
7
|
class SetLocks {
|
|
8
8
|
getMatcher() {
|
|
9
9
|
const s = (0, combi_1.seq)("SET LOCKS OF", expressions_1.SimpleName, "ENTITY", expressions_1.SimpleName, "FROM", expressions_1.Source, "FAILED", expressions_1.Target, "REPORTED", expressions_1.Target);
|
|
10
|
-
return (0, combi_1.ver)(version_1.Release.v754, s);
|
|
10
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.ver)(version_1.Release.v754, s));
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
exports.SetLocks = SetLocks;
|
|
@@ -36,12 +36,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.Static = void 0;
|
|
37
37
|
const combi_1 = require("../combi");
|
|
38
38
|
const Expressions = __importStar(require("../expressions"));
|
|
39
|
+
const version_1 = require("../../../version");
|
|
39
40
|
class Static {
|
|
40
41
|
getMatcher() {
|
|
41
42
|
const p = (0, combi_1.opt)((0, combi_1.per)(Expressions.Type, Expressions.Value, Expressions.Length, Expressions.Decimals));
|
|
42
43
|
const type = (0, combi_1.seq)((0, combi_1.opt)(Expressions.ConstantFieldLength), p);
|
|
43
|
-
const
|
|
44
|
-
return
|
|
44
|
+
const body = (0, combi_1.seq)(Expressions.DefinitionName, (0, combi_1.optPrio)(Expressions.ConstantFieldLength), (0, combi_1.alt)(type, Expressions.TypeTable));
|
|
45
|
+
return (0, combi_1.altPrio)((0, combi_1.seq)("STATIC", body), (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.seq)("STATICS", body)));
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
exports.Static = Static;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Subtract = void 0;
|
|
4
|
+
const version_1 = require("../../../version");
|
|
4
5
|
const combi_1 = require("../combi");
|
|
5
6
|
const expressions_1 = require("../expressions");
|
|
6
7
|
class Subtract {
|
|
7
8
|
getMatcher() {
|
|
8
9
|
const ret = (0, combi_1.seq)("SUBTRACT", expressions_1.Source, "FROM", expressions_1.Target);
|
|
9
|
-
return ret;
|
|
10
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, ret);
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
exports.Subtract = Subtract;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TestInjection = void 0;
|
|
4
|
+
const version_1 = require("../../../version");
|
|
4
5
|
const combi_1 = require("../combi");
|
|
5
6
|
const expressions_1 = require("../expressions");
|
|
6
7
|
class TestInjection {
|
|
7
8
|
getMatcher() {
|
|
8
|
-
return (0, combi_1.seq)("TEST-INJECTION", expressions_1.TestSeamName);
|
|
9
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.seq)("TEST-INJECTION", expressions_1.TestSeamName));
|
|
9
10
|
}
|
|
10
11
|
}
|
|
11
12
|
exports.TestInjection = TestInjection;
|
|
@@ -6,7 +6,7 @@ const expressions_1 = require("../expressions");
|
|
|
6
6
|
const version_1 = require("../../../version");
|
|
7
7
|
class TestSeam {
|
|
8
8
|
getMatcher() {
|
|
9
|
-
return (0, combi_1.ver)(version_1.Release.v750, (0, combi_1.seq)("TEST-SEAM", expressions_1.TestSeamName), { also: combi_1.AlsoIn.OpenABAP });
|
|
9
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.ver)(version_1.Release.v750, (0, combi_1.seq)("TEST-SEAM", expressions_1.TestSeamName), { also: combi_1.AlsoIn.OpenABAP }));
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
exports.TestSeam = TestSeam;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.UpdateDatabase = void 0;
|
|
4
|
+
const version_1 = require("../../../version");
|
|
4
5
|
const combi_1 = require("../combi");
|
|
5
6
|
const expressions_1 = require("../expressions");
|
|
6
|
-
const
|
|
7
|
+
const version_2 = require("../../../version");
|
|
7
8
|
class UpdateDatabase {
|
|
8
9
|
getMatcher() {
|
|
9
10
|
const parameters = (0, combi_1.seq)(expressions_1.SQLFieldAndValue, (0, combi_1.star)((0, combi_1.seq)((0, combi_1.opt)(","), expressions_1.SQLFieldAndValue)));
|
|
10
11
|
const set = (0, combi_1.seq)("SET", (0, combi_1.alt)(parameters, expressions_1.Dynamic), (0, combi_1.opt)((0, combi_1.seq)("WHERE", expressions_1.SQLCond)));
|
|
11
12
|
const indicators = (0, combi_1.seq)("INDICATORS SET STRUCTURE", expressions_1.ComponentName);
|
|
12
|
-
const fromTable = (0, combi_1.seq)("FROM", (0, combi_1.opt)("TABLE"), expressions_1.SQLSource, (0, combi_1.opt)((0, combi_1.ver)(
|
|
13
|
+
const fromTable = (0, combi_1.seq)("FROM", (0, combi_1.opt)("TABLE"), expressions_1.SQLSource, (0, combi_1.opt)((0, combi_1.ver)(version_2.Release.v755, indicators)));
|
|
13
14
|
const ret = (0, combi_1.seq)("UPDATE", expressions_1.DatabaseTable, (0, combi_1.opt)(expressions_1.SQLClient), (0, combi_1.opt)(expressions_1.DatabaseConnection), (0, combi_1.opt)((0, combi_1.alt)(fromTable, set)));
|
|
14
|
-
return ret;
|
|
15
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, ret);
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
exports.UpdateDatabase = UpdateDatabase;
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Wait = void 0;
|
|
4
|
-
const combi_1 = require("../combi");
|
|
5
4
|
const version_1 = require("../../../version");
|
|
5
|
+
const combi_1 = require("../combi");
|
|
6
|
+
const version_2 = require("../../../version");
|
|
6
7
|
const expressions_1 = require("../expressions");
|
|
7
8
|
class Wait {
|
|
8
9
|
getMatcher() {
|
|
9
10
|
const up = (0, combi_1.seq)("UP TO", expressions_1.Source, "SECONDS");
|
|
10
11
|
const channels = "MESSAGING CHANNELS";
|
|
11
|
-
const push = (0, combi_1.ver)(
|
|
12
|
+
const push = (0, combi_1.ver)(version_2.Release.v750, "PUSH CHANNELS", { also: combi_1.AlsoIn.OpenABAP });
|
|
12
13
|
const tasks = "ASYNCHRONOUS TASKS";
|
|
13
14
|
const type = (0, combi_1.seq)("FOR", (0, combi_1.per)(channels, push, tasks));
|
|
14
15
|
const until = (0, combi_1.seq)((0, combi_1.opt)(type), "UNTIL", expressions_1.Cond, (0, combi_1.opt)(up));
|
|
15
16
|
const ret = (0, combi_1.seq)("WAIT", (0, combi_1.alt)(until, up));
|
|
16
|
-
return ret;
|
|
17
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, ret);
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
exports.Wait = Wait;
|
|
@@ -9,7 +9,7 @@ class With {
|
|
|
9
9
|
getMatcher() {
|
|
10
10
|
const exposing = (0, combi_1.optPrio)((0, combi_1.seq)("WITH", (0, combi_1.altPrio)(new expressions_1.SQLCTEHierarchy(), expressions_1.SQLCTEAssociations)));
|
|
11
11
|
const cte = (0, combi_1.seq)(expressions_1.WithName, "AS", (0, combi_1.tok)(tokens_1.WParenLeftW), expressions_1.SelectCTE, (0, combi_1.tok)(tokens_1.WParenRightW), exposing);
|
|
12
|
-
return (0, combi_1.ver)(version_1.Release.v751, (0, combi_1.seq)("WITH", cte, (0, combi_1.star)((0, combi_1.seq)(",", cte)), expressions_1.Select));
|
|
12
|
+
return (0, combi_1.verNotLang)(version_1.LanguageVersion.KeyUser, (0, combi_1.ver)(version_1.Release.v751, (0, combi_1.seq)("WITH", cte, (0, combi_1.star)((0, combi_1.seq)(",", cte)), expressions_1.Select)));
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
exports.With = With;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CurrentScope = void 0;
|
|
4
|
-
const version_1 = require("../../version");
|
|
5
4
|
const _builtin_1 = require("./_builtin");
|
|
6
5
|
const ddic_1 = require("../../ddic");
|
|
7
6
|
const position_1 = require("../../position");
|
|
@@ -37,7 +36,7 @@ class CurrentScope {
|
|
|
37
36
|
}
|
|
38
37
|
///////////////////////////
|
|
39
38
|
getRelease() {
|
|
40
|
-
return
|
|
39
|
+
return this.reg.getConfig().getRelease();
|
|
41
40
|
}
|
|
42
41
|
getVersion() {
|
|
43
42
|
return this.reg.getConfig().getVersion();
|
|
@@ -50,7 +50,7 @@ const _syntax_input_1 = require("../_syntax_input");
|
|
|
50
50
|
const version_1 = require("../../../version");
|
|
51
51
|
const isSimple = /^\w+$/;
|
|
52
52
|
class Select {
|
|
53
|
-
static runSyntax(node, input, skipImplicitInto = false) {
|
|
53
|
+
static runSyntax(node, input, skipImplicitInto = false, selectLoop = false) {
|
|
54
54
|
var _a;
|
|
55
55
|
const token = node.getFirstToken();
|
|
56
56
|
let from = node.findDirectExpression(Expressions.SQLFrom);
|
|
@@ -109,6 +109,14 @@ class Select {
|
|
|
109
109
|
sql_source_1.SQLSource.runSyntax(s, input);
|
|
110
110
|
}
|
|
111
111
|
for (const up of node.findDirectExpressions(Expressions.SQLUpTo)) {
|
|
112
|
+
if (intoExpression
|
|
113
|
+
&& this.isStrictMode(node, input)
|
|
114
|
+
&& (selectLoop === false || input.scope.getLanguageVersion() === version_1.LanguageVersion.Cloud)
|
|
115
|
+
&& from.getFirstToken().getStart().isBefore(up.getFirstToken().getStart())
|
|
116
|
+
&& up.getFirstToken().getStart().isBefore(intoExpression.getFirstToken().getStart())) {
|
|
117
|
+
const message = `The addition "UP TO n ROWS" must only be placed after the INTO/APPENDING clause.`;
|
|
118
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, up.getFirstToken(), message));
|
|
119
|
+
}
|
|
112
120
|
for (const s of up.findDirectExpressions(Expressions.SQLSource)) {
|
|
113
121
|
sql_source_1.SQLSource.runSyntax(s, input);
|
|
114
122
|
}
|
|
@@ -134,7 +142,7 @@ class Select {
|
|
|
134
142
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, orderBy.getFirstToken(), message));
|
|
135
143
|
}
|
|
136
144
|
}
|
|
137
|
-
if (this.isStrictMode(node)) {
|
|
145
|
+
if (this.isStrictMode(node, input)) {
|
|
138
146
|
this.strictModeChecks(node, input);
|
|
139
147
|
}
|
|
140
148
|
if (input.scope.getType() === _scope_type_1.ScopeType.OpenSQL) {
|
|
@@ -142,7 +150,11 @@ class Select {
|
|
|
142
150
|
}
|
|
143
151
|
}
|
|
144
152
|
// there are multiple rules, but gotta start somewhere
|
|
145
|
-
static isStrictMode(node) {
|
|
153
|
+
static isStrictMode(node, input) {
|
|
154
|
+
// strict OpenSQL is always required in the cloud language version
|
|
155
|
+
if (input.scope.getLanguageVersion() === version_1.LanguageVersion.Cloud) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
146
158
|
const into = node.findDirectExpressionsMulti([Expressions.SQLIntoList, Expressions.SQLIntoStructure, Expressions.SQLIntoTable])[0];
|
|
147
159
|
const where = node.findDirectExpression(Expressions.SQLCond);
|
|
148
160
|
// INTO is after WHERE
|
|
@@ -54,8 +54,9 @@ class DeleteInternal {
|
|
|
54
54
|
const localVariable = input.scope.findVariable(target.concatTokens());
|
|
55
55
|
if (localVariable === undefined && node.getChildren().length === 5 && node.getChildren()[2].concatTokens().toUpperCase() === "FROM") {
|
|
56
56
|
// it might be a database table
|
|
57
|
-
|
|
58
|
-
if (
|
|
57
|
+
const found = (_a = input.scope.getDDIC()) === null || _a === void 0 ? void 0 : _a.lookupTableOrView(target.concatTokens());
|
|
58
|
+
if ((found === null || found === void 0 ? void 0 : found.object) !== undefined) {
|
|
59
|
+
tabl = found;
|
|
59
60
|
input.scope.getDDICReferences().addUsing(input.scope.getParentObj(), { object: tabl.object });
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -63,7 +64,7 @@ class DeleteInternal {
|
|
|
63
64
|
targetType = target_1.Target.runSyntax(target, input);
|
|
64
65
|
if (node.findDirectTokenByText("TABLE") === undefined
|
|
65
66
|
&& node.findDirectTokenByText("ADJACENT") === undefined
|
|
66
|
-
&& node.findDirectTokenByText("FROM")
|
|
67
|
+
&& (node.findDirectTokenByText("FROM") || node.findDirectTokenByText("INDEX"))
|
|
67
68
|
&& targetType instanceof basic_1.TableType
|
|
68
69
|
&& targetType.getAccessType() === basic_1.TableAccessType.hashed) {
|
|
69
70
|
const message = "Implicit or explicit index operation on hashed table is not possible";
|
|
@@ -99,6 +99,14 @@ class Loop {
|
|
|
99
99
|
}
|
|
100
100
|
const targetConcat = loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.concatTokens().toUpperCase();
|
|
101
101
|
const topType = sourceType; // todo: refactor topType vs sourceType vs rowType
|
|
102
|
+
if (topType instanceof basic_1.TableType
|
|
103
|
+
&& topType.getAccessType() === basic_1.TableAccessType.hashed
|
|
104
|
+
&& node.findDirectTokenByText("USING") === undefined
|
|
105
|
+
&& (node.findDirectTokenByText("FROM") || node.findDirectTokenByText("TO"))) {
|
|
106
|
+
const message = "Implicit or explicit index operation on hashed table is not possible";
|
|
107
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
102
110
|
if (sourceType instanceof basic_1.TableType) {
|
|
103
111
|
rowType = sourceType.getRowType();
|
|
104
112
|
sourceType = rowType;
|
|
@@ -58,6 +58,13 @@ class ModifyInternal {
|
|
|
58
58
|
// ok
|
|
59
59
|
}
|
|
60
60
|
else if (targetType instanceof basic_1.TableType) {
|
|
61
|
+
if (node.findDirectTokenByText("TABLE") === undefined
|
|
62
|
+
&& node.findDirectTokenByText("INDEX")
|
|
63
|
+
&& targetType.getAccessType() === basic_1.TableAccessType.hashed) {
|
|
64
|
+
const message = "Implicit or explicit index operation on hashed table is not possible";
|
|
65
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
61
68
|
if (node.findDirectTokenByText("TABLE")
|
|
62
69
|
&& node.findDirectTokenByText("INDEX")
|
|
63
70
|
&& targetType.isWithHeader() === false) {
|
|
@@ -48,27 +48,27 @@ class CDSParser {
|
|
|
48
48
|
}
|
|
49
49
|
let tokens = cds_lexer_1.CDSLexer.run(file);
|
|
50
50
|
tokens = tokens.filter(t => !(t instanceof tokens_1.Comment));
|
|
51
|
-
let res = combi_1.Combi.run(new Expressions.CDSDefineView(), tokens, version_1.
|
|
51
|
+
let res = combi_1.Combi.run(new Expressions.CDSDefineView(), tokens, version_1.defaultRelease);
|
|
52
52
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
53
|
-
res = combi_1.Combi.run(new Expressions.CDSDefineAbstract(), tokens, version_1.
|
|
53
|
+
res = combi_1.Combi.run(new Expressions.CDSDefineAbstract(), tokens, version_1.defaultRelease);
|
|
54
54
|
}
|
|
55
55
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
56
|
-
res = combi_1.Combi.run(new Expressions.CDSDefineProjection(), tokens, version_1.
|
|
56
|
+
res = combi_1.Combi.run(new Expressions.CDSDefineProjection(), tokens, version_1.defaultRelease);
|
|
57
57
|
}
|
|
58
58
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
59
|
-
res = combi_1.Combi.run(new Expressions.CDSAnnotate(), tokens, version_1.
|
|
59
|
+
res = combi_1.Combi.run(new Expressions.CDSAnnotate(), tokens, version_1.defaultRelease);
|
|
60
60
|
}
|
|
61
61
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
62
|
-
res = combi_1.Combi.run(new Expressions.CDSDefineCustom(), tokens, version_1.
|
|
62
|
+
res = combi_1.Combi.run(new Expressions.CDSDefineCustom(), tokens, version_1.defaultRelease);
|
|
63
63
|
}
|
|
64
64
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
65
|
-
res = combi_1.Combi.run(new Expressions.CDSDefineTableFunction(), tokens, version_1.
|
|
65
|
+
res = combi_1.Combi.run(new Expressions.CDSDefineTableFunction(), tokens, version_1.defaultRelease);
|
|
66
66
|
}
|
|
67
67
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
68
|
-
res = combi_1.Combi.run(new Expressions.CDSExtendView(), tokens, version_1.
|
|
68
|
+
res = combi_1.Combi.run(new Expressions.CDSExtendView(), tokens, version_1.defaultRelease);
|
|
69
69
|
}
|
|
70
70
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
71
|
-
res = combi_1.Combi.run(new Expressions.CDSDefineHierarchy(), tokens, version_1.
|
|
71
|
+
res = combi_1.Combi.run(new Expressions.CDSDefineHierarchy(), tokens, version_1.defaultRelease);
|
|
72
72
|
}
|
|
73
73
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
74
74
|
return undefined;
|
package/build/src/config.js
CHANGED
|
@@ -47,10 +47,7 @@ class Config {
|
|
|
47
47
|
for (const rule of sorted) {
|
|
48
48
|
rules[rule.getMetadata().key] = rule.getConfig();
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
if (ver) {
|
|
52
|
-
version = ver;
|
|
53
|
-
}
|
|
50
|
+
const version = ver;
|
|
54
51
|
// defaults: dont skip anything, report everything. The user can decide to skip stuff
|
|
55
52
|
// its difficult to debug errors not being reported
|
|
56
53
|
const config = {
|
|
@@ -158,42 +155,54 @@ class Config {
|
|
|
158
155
|
return this.config.syntax;
|
|
159
156
|
}
|
|
160
157
|
getRelease() {
|
|
161
|
-
|
|
158
|
+
const v = this.config.syntax.version;
|
|
159
|
+
if (v !== undefined && typeof v !== "string") {
|
|
160
|
+
return version_1.Release[v.release];
|
|
161
|
+
}
|
|
162
|
+
if (this.config.global === undefined || v === undefined) {
|
|
163
|
+
return version_1.defaultRelease;
|
|
164
|
+
}
|
|
165
|
+
return (0, version_1.versionToABAPRelease)(v);
|
|
162
166
|
}
|
|
163
167
|
getOpenABAP() {
|
|
164
168
|
return this.config.syntax.openABAP === true;
|
|
165
169
|
}
|
|
166
170
|
getVersion() {
|
|
167
|
-
|
|
168
|
-
|
|
171
|
+
const v = this.config.syntax.version;
|
|
172
|
+
if (this.config.global === undefined || v === undefined || typeof v !== "string") {
|
|
173
|
+
return version_1.Version.v816;
|
|
169
174
|
}
|
|
170
|
-
return
|
|
175
|
+
return v;
|
|
171
176
|
}
|
|
172
177
|
getLanguageVersion() {
|
|
173
178
|
var _a;
|
|
179
|
+
const v = this.config.syntax.version;
|
|
180
|
+
if (v !== undefined && typeof v !== "string") {
|
|
181
|
+
return v.language;
|
|
182
|
+
}
|
|
174
183
|
return (_a = this.config.syntax.languageVersion) !== null && _a !== void 0 ? _a : version_1.LanguageVersion.Normal;
|
|
175
184
|
}
|
|
176
185
|
checkVersion() {
|
|
177
|
-
|
|
178
|
-
|
|
186
|
+
const version = this.config.syntax.version;
|
|
187
|
+
if (version === undefined || typeof version !== "string") {
|
|
188
|
+
return; // undefined handled in getVersion, object form is already explicit
|
|
179
189
|
}
|
|
180
190
|
let match = false;
|
|
181
191
|
const vers = version_1.Version;
|
|
182
192
|
for (const v in version_1.Version) {
|
|
183
|
-
if (vers[v] ===
|
|
193
|
+
if (vers[v] === version) {
|
|
184
194
|
match = true;
|
|
185
195
|
break;
|
|
186
196
|
}
|
|
187
197
|
}
|
|
188
198
|
if (match === false) {
|
|
189
|
-
this.config.syntax.version =
|
|
199
|
+
this.config.syntax.version = undefined;
|
|
190
200
|
return;
|
|
191
201
|
}
|
|
192
|
-
if (
|
|
193
|
-
this.config.syntax.version = version_1.Version.Newest;
|
|
202
|
+
if (version === version_1.Version.Cloud) {
|
|
194
203
|
this.config.syntax.languageVersion = version_1.LanguageVersion.Cloud;
|
|
195
204
|
}
|
|
196
|
-
else if (
|
|
205
|
+
else if (version === version_1.Version.OpenABAP) {
|
|
197
206
|
this.config.syntax.version = version_1.Version.v702;
|
|
198
207
|
this.config.syntax.openABAP = true;
|
|
199
208
|
}
|
|
@@ -47,9 +47,9 @@ var DDLKind;
|
|
|
47
47
|
class DDLParser {
|
|
48
48
|
parse(file) {
|
|
49
49
|
const tokens = ddl_lexer_1.DDLLexer.run(file);
|
|
50
|
-
let res = combi_1.Combi.run(new Expressions.DDLStructure(), tokens, version_1.
|
|
50
|
+
let res = combi_1.Combi.run(new Expressions.DDLStructure(), tokens, version_1.defaultRelease);
|
|
51
51
|
if (res === undefined) {
|
|
52
|
-
res = combi_1.Combi.run(new Expressions.DDLTable(), tokens, version_1.
|
|
52
|
+
res = combi_1.Combi.run(new Expressions.DDLTable(), tokens, version_1.defaultRelease);
|
|
53
53
|
}
|
|
54
54
|
if (res === undefined || !(res[0] instanceof nodes_1.ExpressionNode)) {
|
|
55
55
|
return undefined;
|
package/build/src/registry.js
CHANGED
package/build/src/rules/index.js
CHANGED
|
@@ -172,6 +172,7 @@ __exportStar(require("./strict_sql"), exports);
|
|
|
172
172
|
__exportStar(require("./superclass_final"), exports);
|
|
173
173
|
__exportStar(require("./superfluous_value"), exports);
|
|
174
174
|
__exportStar(require("./sy_modification"), exports);
|
|
175
|
+
__exportStar(require("./sy_read_restriction"), exports);
|
|
175
176
|
__exportStar(require("./tabl_enhancement_category"), exports);
|
|
176
177
|
__exportStar(require("./tables_declared_locally"), exports);
|
|
177
178
|
__exportStar(require("./try_without_catch"), exports);
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SyReadRestriction = exports.SyReadRestrictionConf = void 0;
|
|
37
|
+
const issue_1 = require("../issue");
|
|
38
|
+
const Expressions = __importStar(require("../abap/2_statements/expressions"));
|
|
39
|
+
const _abap_rule_1 = require("./_abap_rule");
|
|
40
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
41
|
+
const _irule_1 = require("./_irule");
|
|
42
|
+
const version_1 = require("../version");
|
|
43
|
+
const severity_1 = require("../severity");
|
|
44
|
+
// ABAP Cloud: 17 system fields allowed for reading
|
|
45
|
+
// https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENSYSTEM_FIELDS.html
|
|
46
|
+
const CLOUD_ALLOWED = new Set([
|
|
47
|
+
"SY-BATCH",
|
|
48
|
+
"SY-DBCNT",
|
|
49
|
+
"SY-FDPOS",
|
|
50
|
+
"SY-INDEX",
|
|
51
|
+
"SY-LANGU",
|
|
52
|
+
"SY-MANDT",
|
|
53
|
+
"SY-MSGID",
|
|
54
|
+
"SY-MSGNO",
|
|
55
|
+
"SY-MSGTY",
|
|
56
|
+
"SY-MSGV1",
|
|
57
|
+
"SY-MSGV2",
|
|
58
|
+
"SY-MSGV3",
|
|
59
|
+
"SY-MSGV4",
|
|
60
|
+
"SY-SUBRC",
|
|
61
|
+
"SY-SYSID",
|
|
62
|
+
"SY-TABIX",
|
|
63
|
+
"SY-UNAME",
|
|
64
|
+
]);
|
|
65
|
+
// ABAP for Key Users: 5 system fields allowed for reading
|
|
66
|
+
const KEYUSER_ALLOWED = new Set([
|
|
67
|
+
"SY-DBCNT",
|
|
68
|
+
"SY-FDPOS",
|
|
69
|
+
"SY-INDEX",
|
|
70
|
+
"SY-SUBRC",
|
|
71
|
+
"SY-TABIX",
|
|
72
|
+
]);
|
|
73
|
+
class SyReadRestrictionConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
74
|
+
}
|
|
75
|
+
exports.SyReadRestrictionConf = SyReadRestrictionConf;
|
|
76
|
+
class SyReadRestriction extends _abap_rule_1.ABAPRule {
|
|
77
|
+
constructor() {
|
|
78
|
+
super(...arguments);
|
|
79
|
+
this.conf = new SyReadRestrictionConf();
|
|
80
|
+
}
|
|
81
|
+
getMetadata() {
|
|
82
|
+
return {
|
|
83
|
+
key: "sy_read_restriction",
|
|
84
|
+
title: "SY field read restriction",
|
|
85
|
+
shortDescription: `Finds reads of SY fields not allowed in the current language version`,
|
|
86
|
+
extendedInformation: `In ABAP Cloud, only 17 system fields may be read; reads of other fields produce a warning.\n` +
|
|
87
|
+
`In ABAP for Key Users, only 5 system fields may be read:\n` +
|
|
88
|
+
`SY-DBCNT, SY-FDPOS, SY-INDEX, SY-SUBRC, SY-TABIX.\n` +
|
|
89
|
+
`https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENSYSTEM_FIELDS.html`,
|
|
90
|
+
tags: [_irule_1.RuleTag.SingleFile],
|
|
91
|
+
badExample: `lv = sy-uname.`,
|
|
92
|
+
goodExample: `IF sy-subrc = 0. ENDIF.`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
getConfig() {
|
|
96
|
+
return this.conf;
|
|
97
|
+
}
|
|
98
|
+
setConfig(conf) {
|
|
99
|
+
this.conf = conf;
|
|
100
|
+
}
|
|
101
|
+
runParsed(file, _obj) {
|
|
102
|
+
var _a;
|
|
103
|
+
const issues = [];
|
|
104
|
+
const langVer = this.reg.getConfig().getLanguageVersion();
|
|
105
|
+
if (langVer === version_1.LanguageVersion.Normal) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
const allowed = langVer === version_1.LanguageVersion.KeyUser ? KEYUSER_ALLOWED : CLOUD_ALLOWED;
|
|
109
|
+
const severity = langVer === version_1.LanguageVersion.KeyUser ? this.conf.severity : severity_1.Severity.Warning;
|
|
110
|
+
// Collect tokens that appear in writable Target positions — they're modifications,
|
|
111
|
+
// handled by the sy_modification rule, not this one.
|
|
112
|
+
const writeTokens = new Set();
|
|
113
|
+
for (const t of ((_a = file.getStructure()) === null || _a === void 0 ? void 0 : _a.findAllExpressionsRecursive(Expressions.Target)) || []) {
|
|
114
|
+
const concat = t.concatTokens().toUpperCase();
|
|
115
|
+
if (!concat.startsWith("SY-")) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
writeTokens.add(t.getFirstToken());
|
|
119
|
+
}
|
|
120
|
+
// Walk all tokens looking for the sequence SY - <fieldname>
|
|
121
|
+
const tokens = file.getTokens();
|
|
122
|
+
for (let i = 0; i + 2 < tokens.length; i++) {
|
|
123
|
+
const sy = tokens[i];
|
|
124
|
+
const dash = tokens[i + 1];
|
|
125
|
+
const fld = tokens[i + 2];
|
|
126
|
+
if (sy.getStr().toUpperCase() !== "SY") {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (dash.getStr() !== "-") {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
// Adjacent: no whitespace between the three tokens, on the same row
|
|
133
|
+
if (sy.getEnd().getCol() !== dash.getStart().getCol()
|
|
134
|
+
|| dash.getEnd().getCol() !== fld.getStart().getCol()
|
|
135
|
+
|| sy.getRow() !== dash.getRow()
|
|
136
|
+
|| dash.getRow() !== fld.getRow()) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (writeTokens.has(sy)) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const fieldName = "SY-" + fld.getStr().toUpperCase();
|
|
143
|
+
if (!allowed.has(fieldName)) {
|
|
144
|
+
const message = `SY field "${fieldName}" cannot be read in language version ${langVer}`;
|
|
145
|
+
issues.push(issue_1.Issue.atToken(file, sy, message, this.getMetadata().key, severity));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return issues;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.SyReadRestriction = SyReadRestriction;
|
|
152
|
+
//# sourceMappingURL=sy_read_restriction.js.map
|