@abaplint/core 2.88.10 → 2.89.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.
- package/build/abaplint.d.ts +3 -1
- package/build/src/abap/5_syntax/expressions/source.js +11 -3
- package/build/src/abap/5_syntax/statements/data.js +5 -0
- package/build/src/abap/5_syntax/statements/find.js +2 -2
- package/build/src/abap/5_syntax/statements/selection_screen.js +4 -1
- package/build/src/objects/class.js +8 -0
- package/build/src/registry.js +1 -1
- package/build/src/rules/check_transformation_exists.js +7 -5
- package/build/src/rules/classic_exceptions_overlap.js +69 -0
- package/build/src/rules/definitions_top.js +2 -1
- package/build/src/rules/double_space.js +1 -0
- package/build/src/rules/identical_form_names.js +1 -0
- package/build/src/rules/index.js +4 -2
- package/build/src/rules/local_testclass_consistency.js +63 -0
- package/build/src/rules/no_inline_in_optional_branches.js +78 -0
- package/build/src/rules/unknown_types.js +7 -0
- package/build/src/rules/unused_variables.js +1 -0
- package/package.json +3 -3
- package/build/src/rules/local_testclass_location.js +0 -54
package/build/abaplint.d.ts
CHANGED
|
@@ -741,6 +741,7 @@ declare class Class extends ABAPObject {
|
|
|
741
741
|
getNameFromXML(): string | undefined;
|
|
742
742
|
getCategory(): string | undefined;
|
|
743
743
|
getLocalsImpFile(): ABAPFile | undefined;
|
|
744
|
+
getTestclassFile(): ABAPFile | undefined;
|
|
744
745
|
private parseXML;
|
|
745
746
|
}
|
|
746
747
|
|
|
@@ -2652,7 +2653,8 @@ export declare const enum IdentifierMeta {
|
|
|
2652
2653
|
BuiltIn = "built-in",
|
|
2653
2654
|
DDIC = "ddic",
|
|
2654
2655
|
Static = "static",
|
|
2655
|
-
Enum = "enum"
|
|
2656
|
+
Enum = "enum",
|
|
2657
|
+
SelectionScreenTab = "selection_screen_tab"
|
|
2656
2658
|
}
|
|
2657
2659
|
|
|
2658
2660
|
export declare interface IDependency {
|
|
@@ -198,10 +198,18 @@ class Source {
|
|
|
198
198
|
}
|
|
199
199
|
return targetType;
|
|
200
200
|
}
|
|
201
|
-
if (typeName !== "#") {
|
|
201
|
+
if (typeName !== "#" && typeToken) {
|
|
202
202
|
const found = basic.parseType(typeExpression);
|
|
203
|
-
if (found
|
|
204
|
-
|
|
203
|
+
if (found && found instanceof unknown_type_1.UnknownType) {
|
|
204
|
+
if (scope.getDDIC().inErrorNamespace(typeName) === false) {
|
|
205
|
+
scope.addReference(typeToken, undefined, _reference_1.ReferenceType.VoidType, filename);
|
|
206
|
+
return new basic_1.VoidType(typeName);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const tid = new _typed_identifier_1.TypedIdentifier(typeToken, filename, found);
|
|
210
|
+
scope.addReference(typeToken, tid, _reference_1.ReferenceType.TypeReference, filename);
|
|
211
|
+
return found;
|
|
212
|
+
}
|
|
205
213
|
}
|
|
206
214
|
else if (found === undefined) {
|
|
207
215
|
throw new Error("Type \"" + typeName + "\" not found in scope, VALUE");
|
|
@@ -5,8 +5,13 @@ const Expressions = require("../../2_statements/expressions");
|
|
|
5
5
|
const _typed_identifier_1 = require("../../types/_typed_identifier");
|
|
6
6
|
const data_definition_1 = require("../expressions/data_definition");
|
|
7
7
|
const unknown_type_1 = require("../../types/basic/unknown_type");
|
|
8
|
+
const basic_types_1 = require("../basic_types");
|
|
8
9
|
class Data {
|
|
9
10
|
runSyntax(node, scope, filename) {
|
|
11
|
+
const val = node.findFirstExpression(Expressions.Value);
|
|
12
|
+
if (val) {
|
|
13
|
+
new basic_types_1.BasicTypes(filename, scope).findValue(node);
|
|
14
|
+
}
|
|
10
15
|
const dd = node.findFirstExpression(Expressions.DataDefinition);
|
|
11
16
|
if (dd) {
|
|
12
17
|
return new data_definition_1.DataDefinition().runSyntax(dd, scope, filename);
|
|
@@ -18,12 +18,12 @@ class Find {
|
|
|
18
18
|
{ name: "OFFSET", type: new basic_1.IntegerType() },
|
|
19
19
|
{ name: "LENGTH", type: new basic_1.IntegerType() },
|
|
20
20
|
{ name: "SUBMATCHES", type: new basic_1.TableType(new basic_1.StringType(), { withHeader: false }) },
|
|
21
|
-
]);
|
|
21
|
+
], "MATCH_RESULT");
|
|
22
22
|
if (node.concatTokens().toUpperCase().startsWith("FIND FIRST")) {
|
|
23
23
|
this.inline(rfound, scope, filename, type);
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
|
-
this.inline(rfound, scope, filename, new basic_1.TableType(type, { withHeader: false }));
|
|
26
|
+
this.inline(rfound, scope, filename, new basic_1.TableType(type, { withHeader: false }, "MATCH_RESULT_TAB"));
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
const ofound = node.findExpressionsAfterToken("OFFSET");
|
|
@@ -18,7 +18,10 @@ class SelectionScreen {
|
|
|
18
18
|
{ name: "DYNNR", type: new basic_1.CharacterType(4) },
|
|
19
19
|
{ name: "ACTIVETAB", type: new basic_1.CharacterType(132) },
|
|
20
20
|
]);
|
|
21
|
-
scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(name, filename, type));
|
|
21
|
+
scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(name, filename, type, ["selection_screen_tab" /* SelectionScreenTab */]));
|
|
22
|
+
}
|
|
23
|
+
else if (concat.startsWith("SELECTION-SCREEN TAB")) {
|
|
24
|
+
scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(name, filename, new basic_1.CharacterType(83), ["selection_screen_tab" /* SelectionScreenTab */]));
|
|
22
25
|
}
|
|
23
26
|
else {
|
|
24
27
|
scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(name, filename, new basic_1.CharacterType(83)));
|
|
@@ -78,6 +78,14 @@ class Class extends _abap_object_1.ABAPObject {
|
|
|
78
78
|
}
|
|
79
79
|
return undefined;
|
|
80
80
|
}
|
|
81
|
+
getTestclassFile() {
|
|
82
|
+
for (const file of this.getABAPFiles()) {
|
|
83
|
+
if (file.getFilename().endsWith(".clas.testclasses.abap")) {
|
|
84
|
+
return file;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
81
89
|
/////////////////////////
|
|
82
90
|
parseXML() {
|
|
83
91
|
if (this.parsedXML !== undefined) {
|
package/build/src/registry.js
CHANGED
|
@@ -40,13 +40,15 @@ class CheckTransformationExists extends _abap_rule_1.ABAPRule {
|
|
|
40
40
|
}
|
|
41
41
|
for (const s of file.getStatements()) {
|
|
42
42
|
if (s.get() instanceof statements_1.CallTransformation) {
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
43
|
+
const nameExpression = s.findFirstExpression(expressions_1.NamespaceSimpleName);
|
|
44
|
+
if (nameExpression === undefined) {
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
|
-
const tok =
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
const tok = nameExpression.getFirstToken();
|
|
48
|
+
const name = tok.getStr();
|
|
49
|
+
if (this.reg.inErrorNamespace(name) === true
|
|
50
|
+
&& this.reg.getObject("XSLT", name) === undefined) {
|
|
51
|
+
const issue = issue_1.Issue.atToken(file, tok, this.getDescription(name), this.getMetadata().key);
|
|
50
52
|
output.push(issue);
|
|
51
53
|
}
|
|
52
54
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClassicExceptionsOverlap = exports.ClassicExceptionsOverlapConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _abap_rule_1 = require("./_abap_rule");
|
|
6
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
+
const Expressions = require("../abap/2_statements/expressions");
|
|
8
|
+
const _irule_1 = require("./_irule");
|
|
9
|
+
class ClassicExceptionsOverlapConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
10
|
+
}
|
|
11
|
+
exports.ClassicExceptionsOverlapConf = ClassicExceptionsOverlapConf;
|
|
12
|
+
class ClassicExceptionsOverlap extends _abap_rule_1.ABAPRule {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.conf = new ClassicExceptionsOverlapConf();
|
|
16
|
+
}
|
|
17
|
+
getMetadata() {
|
|
18
|
+
return {
|
|
19
|
+
key: "classic_exceptions_overlap",
|
|
20
|
+
title: "Classic exceptions overlap when catching",
|
|
21
|
+
shortDescription: `Find overlapping classic exceptions`,
|
|
22
|
+
extendedInformation: `When debugging its typically good to know exactly which exception is caught`,
|
|
23
|
+
tags: [_irule_1.RuleTag.SingleFile],
|
|
24
|
+
badExample: ` EXCEPTIONS
|
|
25
|
+
system_failure = 1 MESSAGE lv_message
|
|
26
|
+
communication_failure = 1 MESSAGE lv_message
|
|
27
|
+
resource_failure = 1
|
|
28
|
+
OTHERS = 1.`,
|
|
29
|
+
goodExample: ` EXCEPTIONS
|
|
30
|
+
system_failure = 1 MESSAGE lv_message
|
|
31
|
+
communication_failure = 2 MESSAGE lv_message
|
|
32
|
+
resource_failure = 3
|
|
33
|
+
OTHERS = 4.`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
getConfig() {
|
|
37
|
+
return this.conf;
|
|
38
|
+
}
|
|
39
|
+
setConfig(conf) {
|
|
40
|
+
this.conf = conf;
|
|
41
|
+
}
|
|
42
|
+
runParsed(file) {
|
|
43
|
+
var _a;
|
|
44
|
+
const output = [];
|
|
45
|
+
const struc = file.getStructure();
|
|
46
|
+
if (struc === undefined) {
|
|
47
|
+
return []; // syntax error
|
|
48
|
+
}
|
|
49
|
+
for (const p of struc.findAllExpressions(Expressions.ParameterListExceptions)) {
|
|
50
|
+
const set = new Set();
|
|
51
|
+
for (const e of p.findAllExpressions(Expressions.ParameterException)) {
|
|
52
|
+
const text = (_a = e.findDirectExpression(Expressions.SimpleName)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
|
|
53
|
+
if (text === undefined) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (set.has(text)) {
|
|
57
|
+
const message = "Exception overlap, " + text;
|
|
58
|
+
const issue = issue_1.Issue.atToken(file, e.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity);
|
|
59
|
+
output.push(issue);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
set.add(text);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return output;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.ClassicExceptionsOverlap = ClassicExceptionsOverlap;
|
|
69
|
+
//# sourceMappingURL=classic_exceptions_overlap.js.map
|
|
@@ -122,7 +122,8 @@ class DefinitionsTop extends _abap_rule_1.ABAPRule {
|
|
|
122
122
|
return undefined;
|
|
123
123
|
}
|
|
124
124
|
buildFix(file, statement, start) {
|
|
125
|
-
|
|
125
|
+
let concat = statement.concatTokens();
|
|
126
|
+
concat = concat.replace(/,$/, ".");
|
|
126
127
|
const fix1 = edit_helper_1.EditHelper.deleteStatement(file, statement);
|
|
127
128
|
const indentation = " ".repeat(statement.getFirstToken().getCol() - 1);
|
|
128
129
|
const fix2 = edit_helper_1.EditHelper.insertAt(file, start.getEnd(), "\n" + indentation + concat);
|
|
@@ -145,6 +145,7 @@ class DoubleSpace extends _abap_rule_1.ABAPRule {
|
|
|
145
145
|
const upper = prev.get().getStr().toUpperCase();
|
|
146
146
|
if (prev instanceof nodes_1.TokenNodeRegex
|
|
147
147
|
|| upper === "("
|
|
148
|
+
|| upper === ")"
|
|
148
149
|
|| upper === "CHANGING"
|
|
149
150
|
|| upper === "EXPORTING"
|
|
150
151
|
|| upper === "OTHERS") {
|
|
@@ -8,6 +8,7 @@ const _abap_object_1 = require("../objects/_abap_object");
|
|
|
8
8
|
class IdenticalFormNamesConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
9
9
|
}
|
|
10
10
|
exports.IdenticalFormNamesConf = IdenticalFormNamesConf;
|
|
11
|
+
// todo: deprecation candidate? this is/should be handled by the syntax check?
|
|
11
12
|
class IdenticalFormNames {
|
|
12
13
|
constructor() {
|
|
13
14
|
this.conf = new IdenticalFormNamesConf();
|
package/build/src/rules/index.js
CHANGED
|
@@ -30,9 +30,9 @@ __exportStar(require("./check_abstract"), exports);
|
|
|
30
30
|
__exportStar(require("./check_comments"), exports);
|
|
31
31
|
__exportStar(require("./check_ddic"), exports);
|
|
32
32
|
__exportStar(require("./check_include"), exports);
|
|
33
|
-
__exportStar(require("./unnecessary_pragma"), exports);
|
|
34
33
|
__exportStar(require("./check_subrc"), exports);
|
|
35
34
|
__exportStar(require("./check_syntax"), exports);
|
|
35
|
+
__exportStar(require("./classic_exceptions_overlap"), exports);
|
|
36
36
|
__exportStar(require("./check_text_elements"), exports);
|
|
37
37
|
__exportStar(require("./check_transformation_exists"), exports);
|
|
38
38
|
__exportStar(require("./class_attribute_names"), exports);
|
|
@@ -80,7 +80,7 @@ __exportStar(require("./line_break_style"), exports);
|
|
|
80
80
|
__exportStar(require("./line_length"), exports);
|
|
81
81
|
__exportStar(require("./line_only_punc"), exports);
|
|
82
82
|
__exportStar(require("./local_class_naming"), exports);
|
|
83
|
-
__exportStar(require("./
|
|
83
|
+
__exportStar(require("./local_testclass_consistency"), exports);
|
|
84
84
|
__exportStar(require("./local_variable_names"), exports);
|
|
85
85
|
__exportStar(require("./main_file_contents"), exports);
|
|
86
86
|
__exportStar(require("./many_parentheses"), exports);
|
|
@@ -99,6 +99,7 @@ __exportStar(require("./nesting"), exports);
|
|
|
99
99
|
__exportStar(require("./newline_between_methods"), exports);
|
|
100
100
|
__exportStar(require("./no_aliases"), exports);
|
|
101
101
|
__exportStar(require("./no_chained_assignment"), exports);
|
|
102
|
+
__exportStar(require("./no_inline_in_optional_branches"), exports);
|
|
102
103
|
__exportStar(require("./no_public_attributes"), exports);
|
|
103
104
|
__exportStar(require("./no_yoda_conditions"), exports);
|
|
104
105
|
__exportStar(require("./nrob_consistency"), exports);
|
|
@@ -144,6 +145,7 @@ __exportStar(require("./types_naming"), exports);
|
|
|
144
145
|
__exportStar(require("./uncaught_exception"), exports);
|
|
145
146
|
__exportStar(require("./unknown_types"), exports);
|
|
146
147
|
__exportStar(require("./unnecessary_chaining"), exports);
|
|
148
|
+
__exportStar(require("./unnecessary_pragma"), exports);
|
|
147
149
|
__exportStar(require("./unreachable_code"), exports);
|
|
148
150
|
__exportStar(require("./unsecure_fae"), exports);
|
|
149
151
|
__exportStar(require("./unused_ddic"), exports);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalTestclassConsistency = exports.LocalTestclassConsistencyConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _abap_rule_1 = require("./_abap_rule");
|
|
6
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
+
const objects_1 = require("../objects");
|
|
8
|
+
const _irule_1 = require("./_irule");
|
|
9
|
+
const version_1 = require("../version");
|
|
10
|
+
class LocalTestclassConsistencyConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
11
|
+
}
|
|
12
|
+
exports.LocalTestclassConsistencyConf = LocalTestclassConsistencyConf;
|
|
13
|
+
class LocalTestclassConsistency extends _abap_rule_1.ABAPRule {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
this.conf = new LocalTestclassConsistencyConf();
|
|
17
|
+
}
|
|
18
|
+
getMetadata() {
|
|
19
|
+
return {
|
|
20
|
+
key: "local_testclass_consistency",
|
|
21
|
+
title: "Local testclass consistency",
|
|
22
|
+
shortDescription: `Checks that local test classes are placed in the test include, and class unit test flag is set`,
|
|
23
|
+
tags: [_irule_1.RuleTag.Syntax],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
getConfig() {
|
|
27
|
+
return this.conf;
|
|
28
|
+
}
|
|
29
|
+
setConfig(conf) {
|
|
30
|
+
this.conf = conf;
|
|
31
|
+
}
|
|
32
|
+
runParsed(file, obj) {
|
|
33
|
+
var _a;
|
|
34
|
+
const issues = [];
|
|
35
|
+
if (this.reg.getConfig().getVersion() === version_1.Version.v700) {
|
|
36
|
+
// 700 does not have testclass includes
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
if (!(obj instanceof objects_1.Class)) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
for (const c of file.getInfo().listClassDefinitions()) {
|
|
43
|
+
if (c.isLocal && c.isForTesting && !file.getFilename().includes(".testclasses.abap")) {
|
|
44
|
+
const message = "Place local testclass \"" + c.name + "\" in the testclass include";
|
|
45
|
+
const issue = issue_1.Issue.atIdentifier(c.identifier, message, this.getMetadata().key, this.conf.severity);
|
|
46
|
+
issues.push(issue);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (file.getFilename().includes(".testclasses.") === true
|
|
50
|
+
&& obj.getTestclassFile() !== undefined
|
|
51
|
+
&& ((_a = obj.getXML()) === null || _a === void 0 ? void 0 : _a.includes("<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>")) === false) {
|
|
52
|
+
const id = obj.getIdentifier();
|
|
53
|
+
if (id) {
|
|
54
|
+
const message = "Has testclass, but XML does not set <WITH_UNIT_TESTS>";
|
|
55
|
+
const issue = issue_1.Issue.atIdentifier(id, message, this.getMetadata().key, this.conf.severity);
|
|
56
|
+
issues.push(issue);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return issues;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.LocalTestclassConsistency = LocalTestclassConsistency;
|
|
63
|
+
//# sourceMappingURL=local_testclass_consistency.js.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoInlineInOptionalBranches = exports.NoInlineInOptionalBranchesConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _abap_rule_1 = require("./_abap_rule");
|
|
6
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
+
const Structures = require("../abap/3_structures/structures");
|
|
8
|
+
const Expressions = require("../abap/2_statements/expressions");
|
|
9
|
+
const _irule_1 = require("./_irule");
|
|
10
|
+
const version_1 = require("../version");
|
|
11
|
+
class NoInlineInOptionalBranchesConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
12
|
+
}
|
|
13
|
+
exports.NoInlineInOptionalBranchesConf = NoInlineInOptionalBranchesConf;
|
|
14
|
+
class NoInlineInOptionalBranches extends _abap_rule_1.ABAPRule {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.conf = new NoInlineInOptionalBranchesConf();
|
|
18
|
+
}
|
|
19
|
+
getMetadata() {
|
|
20
|
+
return {
|
|
21
|
+
key: "no_inline_in_optional_branches",
|
|
22
|
+
title: "Don't declare inline in optional branches",
|
|
23
|
+
shortDescription: `Don't declare inline in optional branches`,
|
|
24
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#dont-declare-inline-in-optional-branches
|
|
25
|
+
|
|
26
|
+
Considered optional branches:
|
|
27
|
+
* inside IF/ELSEIF/ELSE
|
|
28
|
+
* inside LOOP
|
|
29
|
+
* inside WHILE
|
|
30
|
+
* inside CASE/WHEN, CASE TYPE OF
|
|
31
|
+
* inside DO
|
|
32
|
+
* inside SELECT loops
|
|
33
|
+
|
|
34
|
+
Not considered optional branches:
|
|
35
|
+
* TRY/CATCH/CLEANUP`,
|
|
36
|
+
tags: [_irule_1.RuleTag.Styleguide, _irule_1.RuleTag.SingleFile],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
getConfig() {
|
|
40
|
+
return this.conf;
|
|
41
|
+
}
|
|
42
|
+
setConfig(conf) {
|
|
43
|
+
this.conf = conf;
|
|
44
|
+
}
|
|
45
|
+
runParsed(file) {
|
|
46
|
+
const output = [];
|
|
47
|
+
const version = this.reg.getConfig().getVersion();
|
|
48
|
+
if (version === version_1.Version.v700
|
|
49
|
+
|| version === version_1.Version.v702
|
|
50
|
+
|| version === version_1.Version.OpenABAP) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
const struc = file.getStructure();
|
|
54
|
+
if (struc === undefined) {
|
|
55
|
+
return []; // syntax error
|
|
56
|
+
}
|
|
57
|
+
const candidates = [
|
|
58
|
+
...struc.findAllStructures(Structures.If),
|
|
59
|
+
...struc.findAllStructures(Structures.Loop),
|
|
60
|
+
...struc.findAllStructures(Structures.While),
|
|
61
|
+
...struc.findAllStructures(Structures.Case),
|
|
62
|
+
...struc.findAllStructures(Structures.CaseType),
|
|
63
|
+
...struc.findAllStructures(Structures.Do),
|
|
64
|
+
...struc.findAllStructures(Structures.Select)
|
|
65
|
+
];
|
|
66
|
+
for (const c of candidates) {
|
|
67
|
+
const inline = c.findFirstExpression(Expressions.InlineData);
|
|
68
|
+
if (inline) {
|
|
69
|
+
const message = "Don't declare inline in optional branches";
|
|
70
|
+
const issue = issue_1.Issue.atToken(file, c.getFirstToken(), message, this.getMetadata().key, this.getConfig().severity);
|
|
71
|
+
output.push(issue);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return output;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.NoInlineInOptionalBranches = NoInlineInOptionalBranches;
|
|
78
|
+
//# sourceMappingURL=no_inline_in_optional_branches.js.map
|
|
@@ -10,6 +10,7 @@ const _irule_1 = require("./_irule");
|
|
|
10
10
|
const _typed_identifier_1 = require("../abap/types/_typed_identifier");
|
|
11
11
|
const _scope_type_1 = require("../abap/5_syntax/_scope_type");
|
|
12
12
|
const _reference_1 = require("../abap/5_syntax/_reference");
|
|
13
|
+
const basic_1 = require("../abap/types/basic");
|
|
13
14
|
class UnknownTypesConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
14
15
|
}
|
|
15
16
|
exports.UnknownTypesConf = UnknownTypesConf;
|
|
@@ -70,6 +71,12 @@ class UnknownTypes {
|
|
|
70
71
|
const message = r.extra.ooName + " unknown";
|
|
71
72
|
ret.push(issue_1.Issue.atIdentifier(r.position, message, this.getMetadata().key, this.conf.severity));
|
|
72
73
|
}
|
|
74
|
+
if (r.referenceType === _reference_1.ReferenceType.TypeReference
|
|
75
|
+
&& r.resolved instanceof _typed_identifier_1.TypedIdentifier
|
|
76
|
+
&& r.resolved.getType() instanceof basic_1.UnknownType) {
|
|
77
|
+
const message = r.resolved.getType().getError();
|
|
78
|
+
ret.push(issue_1.Issue.atIdentifier(r.position, message, this.getMetadata().key, this.conf.severity));
|
|
79
|
+
}
|
|
73
80
|
}
|
|
74
81
|
if (node.getIdentifier().stype !== _scope_type_1.ScopeType.ClassImplementation) {
|
|
75
82
|
const vars = nodeData.vars;
|
|
@@ -156,6 +156,7 @@ Unused variables are not reported if the object contains syntax errors. Errors f
|
|
|
156
156
|
}
|
|
157
157
|
else if (name === "ME"
|
|
158
158
|
|| name === "SUPER"
|
|
159
|
+
|| meta.includes("selection_screen_tab" /* SelectionScreenTab */)
|
|
159
160
|
|| meta.includes("event_parameter" /* EventParameter */)) {
|
|
160
161
|
// todo, workaround for "me" and "super", these should somehow be typed to built-in
|
|
161
162
|
continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.89.2",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"@microsoft/api-extractor": "^7.22.2",
|
|
49
49
|
"@types/chai": "^4.3.1",
|
|
50
50
|
"@types/mocha": "^9.1.0",
|
|
51
|
-
"@types/node": "^17.0.
|
|
51
|
+
"@types/node": "^17.0.25",
|
|
52
52
|
"chai": "^4.3.6",
|
|
53
53
|
"eslint": "^8.13.0",
|
|
54
54
|
"mocha": "^9.2.2",
|
|
55
|
-
"c8": "^7.11.
|
|
55
|
+
"c8": "^7.11.2",
|
|
56
56
|
"source-map-support": "^0.5.21",
|
|
57
57
|
"ts-json-schema-generator": "^1.0.0",
|
|
58
58
|
"typescript": "^4.6.3"
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LocalTestclassLocation = exports.LocalTestclassLocationConf = void 0;
|
|
4
|
-
const issue_1 = require("../issue");
|
|
5
|
-
const _abap_rule_1 = require("./_abap_rule");
|
|
6
|
-
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
7
|
-
const objects_1 = require("../objects");
|
|
8
|
-
const _irule_1 = require("./_irule");
|
|
9
|
-
const version_1 = require("../version");
|
|
10
|
-
class LocalTestclassLocationConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
11
|
-
}
|
|
12
|
-
exports.LocalTestclassLocationConf = LocalTestclassLocationConf;
|
|
13
|
-
class LocalTestclassLocation extends _abap_rule_1.ABAPRule {
|
|
14
|
-
constructor() {
|
|
15
|
-
super(...arguments);
|
|
16
|
-
this.conf = new LocalTestclassLocationConf();
|
|
17
|
-
}
|
|
18
|
-
getMetadata() {
|
|
19
|
-
return {
|
|
20
|
-
key: "local_testclass_location",
|
|
21
|
-
title: "Local testclass location",
|
|
22
|
-
shortDescription: `Checks that local test classes are placed in the test include.`,
|
|
23
|
-
tags: [_irule_1.RuleTag.SingleFile],
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
getDescription(className) {
|
|
27
|
-
return "Place local testclass \"" + className + "\" in the testclass include";
|
|
28
|
-
}
|
|
29
|
-
getConfig() {
|
|
30
|
-
return this.conf;
|
|
31
|
-
}
|
|
32
|
-
setConfig(conf) {
|
|
33
|
-
this.conf = conf;
|
|
34
|
-
}
|
|
35
|
-
runParsed(file, obj) {
|
|
36
|
-
const issues = [];
|
|
37
|
-
if (this.reg.getConfig().getVersion() === version_1.Version.v700) {
|
|
38
|
-
// 700 does not have testclass includes
|
|
39
|
-
return [];
|
|
40
|
-
}
|
|
41
|
-
if (!(obj instanceof objects_1.Class)) {
|
|
42
|
-
return [];
|
|
43
|
-
}
|
|
44
|
-
for (const c of file.getInfo().listClassDefinitions()) {
|
|
45
|
-
if (c.isLocal && c.isForTesting && !file.getFilename().includes(".testclasses.abap")) {
|
|
46
|
-
const issue = issue_1.Issue.atIdentifier(c.identifier, this.getDescription(c.name), this.getMetadata().key, this.conf.severity);
|
|
47
|
-
issues.push(issue);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return issues;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
exports.LocalTestclassLocation = LocalTestclassLocation;
|
|
54
|
-
//# sourceMappingURL=local_testclass_location.js.map
|