@abaplint/core 2.78.12 → 2.79.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 +19 -0
- package/build/src/abap/4_file_information/abap_file_information.js +30 -1
- package/build/src/abap/5_syntax/_type_utils.js +1 -0
- package/build/src/abap/5_syntax/expressions/field_assignment.js +6 -0
- package/build/src/lsp/semantic.js +1 -1
- package/build/src/objects/domain.js +18 -1
- package/build/src/registry.js +1 -1
- package/build/src/rules/constant_classes.js +109 -0
- package/build/src/rules/index.js +1 -0
- package/build/src/rules/obsolete_statement.js +34 -1
- package/build/src/rules/use_line_exists.js +5 -1
- package/build/src/version.js +1 -0
- package/package.json +2 -2
package/build/abaplint.d.ts
CHANGED
|
@@ -1350,6 +1350,13 @@ declare class Domain extends AbstractObject {
|
|
|
1350
1350
|
updated: boolean;
|
|
1351
1351
|
runtime: number;
|
|
1352
1352
|
};
|
|
1353
|
+
getFixedValues(): DomainValue[];
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
declare interface DomainValue {
|
|
1357
|
+
language: string;
|
|
1358
|
+
value: string;
|
|
1359
|
+
description: string;
|
|
1353
1360
|
}
|
|
1354
1361
|
|
|
1355
1362
|
declare class Dynamic extends Expression {
|
|
@@ -2628,6 +2635,7 @@ declare namespace Info {
|
|
|
2628
2635
|
InfoMethodParameter,
|
|
2629
2636
|
InfoMethodDefinition,
|
|
2630
2637
|
InfoInterfaceDefinition,
|
|
2638
|
+
InfoConstant,
|
|
2631
2639
|
InfoAlias,
|
|
2632
2640
|
InfoImplementing,
|
|
2633
2641
|
InfoClassDefinition,
|
|
@@ -2667,6 +2675,14 @@ declare interface InfoClassImplementation {
|
|
|
2667
2675
|
methods: readonly Identifier[];
|
|
2668
2676
|
}
|
|
2669
2677
|
|
|
2678
|
+
declare interface InfoConstant {
|
|
2679
|
+
identifier: Identifier;
|
|
2680
|
+
name: string;
|
|
2681
|
+
typeName: string;
|
|
2682
|
+
visibility: Visibility;
|
|
2683
|
+
value: string;
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2670
2686
|
declare interface InfoFormDefinition {
|
|
2671
2687
|
name: string;
|
|
2672
2688
|
identifier: Identifier;
|
|
@@ -2688,6 +2704,7 @@ declare interface InfoInterfaceDefinition {
|
|
|
2688
2704
|
interfaces: readonly InfoImplementing[];
|
|
2689
2705
|
methods: readonly InfoMethodDefinition[];
|
|
2690
2706
|
aliases: readonly InfoAlias[];
|
|
2707
|
+
constants: readonly InfoConstant[];
|
|
2691
2708
|
attributes: readonly InfoAttribute[];
|
|
2692
2709
|
}
|
|
2693
2710
|
|
|
@@ -3646,6 +3663,7 @@ declare namespace Objects {
|
|
|
3646
3663
|
DataElement,
|
|
3647
3664
|
DialogModule,
|
|
3648
3665
|
Documentation,
|
|
3666
|
+
DomainValue,
|
|
3649
3667
|
Domain,
|
|
3650
3668
|
EcattTestConfiguration,
|
|
3651
3669
|
EcattTestDataContainer,
|
|
@@ -5660,6 +5678,7 @@ export declare enum Version {
|
|
|
5660
5678
|
v753 = "v753",
|
|
5661
5679
|
v754 = "v754",
|
|
5662
5680
|
v755 = "v755",
|
|
5681
|
+
v756 = "v756",
|
|
5663
5682
|
Cloud = "Cloud"
|
|
5664
5683
|
}
|
|
5665
5684
|
|
|
@@ -76,7 +76,7 @@ class ABAPFileInformation {
|
|
|
76
76
|
this.implementations.push({
|
|
77
77
|
name: name.getStr(),
|
|
78
78
|
identifier: new _identifier_1.Identifier(name, this.filename),
|
|
79
|
-
methods
|
|
79
|
+
methods,
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
for (const statement of structure.findAllStructures(Structures.Form)) {
|
|
@@ -100,6 +100,7 @@ class ABAPFileInformation {
|
|
|
100
100
|
const methods = this.parseMethodDefinition(found, visibility_1.Visibility.Public);
|
|
101
101
|
const attributes = this.parseAttributes(found, visibility_1.Visibility.Public);
|
|
102
102
|
const aliases = this.parseAliases(found, visibility_1.Visibility.Public);
|
|
103
|
+
const constants = this.parseConstants(found, visibility_1.Visibility.Public);
|
|
103
104
|
const g = i.findDirectExpression(Expressions.ClassGlobal);
|
|
104
105
|
this.interfaces.push({
|
|
105
106
|
name: interfaceName.getStr(),
|
|
@@ -109,6 +110,7 @@ class ABAPFileInformation {
|
|
|
109
110
|
interfaces: this.getImplementing(found),
|
|
110
111
|
aliases,
|
|
111
112
|
methods,
|
|
113
|
+
constants,
|
|
112
114
|
attributes,
|
|
113
115
|
});
|
|
114
116
|
}
|
|
@@ -126,6 +128,9 @@ class ABAPFileInformation {
|
|
|
126
128
|
const aliases = this.parseAliases(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
|
|
127
129
|
aliases.push(...this.parseAliases(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
|
|
128
130
|
aliases.push(...this.parseAliases(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
|
|
131
|
+
const constants = this.parseConstants(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
|
|
132
|
+
constants.push(...this.parseConstants(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
|
|
133
|
+
constants.push(...this.parseConstants(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
|
|
129
134
|
const superClassName = (_a = found.findFirstExpression(Expressions.SuperClassName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
|
|
130
135
|
const containsGlobal = found.findFirstExpression(Expressions.ClassGlobal);
|
|
131
136
|
const concat = found.findFirstStatement(Statements.ClassDefinition).concatTokens().toUpperCase();
|
|
@@ -142,6 +147,7 @@ class ABAPFileInformation {
|
|
|
142
147
|
isFinal: found.findFirstExpression(Expressions.ClassFinal) !== undefined,
|
|
143
148
|
aliases,
|
|
144
149
|
attributes,
|
|
150
|
+
constants,
|
|
145
151
|
});
|
|
146
152
|
}
|
|
147
153
|
}
|
|
@@ -194,6 +200,29 @@ class ABAPFileInformation {
|
|
|
194
200
|
}
|
|
195
201
|
return ret;
|
|
196
202
|
}
|
|
203
|
+
parseConstants(node, visibility) {
|
|
204
|
+
var _a, _b;
|
|
205
|
+
if (node === undefined) {
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
const results = [];
|
|
209
|
+
for (const constant of node.findAllStatements(Statements.Constant)) {
|
|
210
|
+
const name = constant.findFirstExpression(Expressions.DefinitionName).getFirstToken();
|
|
211
|
+
const typeName = constant.findFirstExpression(Expressions.TypeName);
|
|
212
|
+
// VALUE `const_value` -> `const_value`
|
|
213
|
+
const literal = (_b = (_a = constant.findFirstExpression(Expressions.Value)) === null || _a === void 0 ? void 0 : _a.getTokens()[1].getStr()) !== null && _b !== void 0 ? _b : "``";
|
|
214
|
+
// `const_value` -> const_value
|
|
215
|
+
const value = literal.slice(1, (literal === null || literal === void 0 ? void 0 : literal.length) - 1);
|
|
216
|
+
results.push({
|
|
217
|
+
name: name.getStr(),
|
|
218
|
+
typeName: typeName ? typeName.getFirstToken().getStr() : "",
|
|
219
|
+
value: value,
|
|
220
|
+
identifier: new _identifier_1.Identifier(name, this.filename),
|
|
221
|
+
visibility,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return results;
|
|
225
|
+
}
|
|
197
226
|
parseAttributes(node, visibility) {
|
|
198
227
|
if (node === undefined) {
|
|
199
228
|
return [];
|
|
@@ -20,6 +20,7 @@ class TypeUtils {
|
|
|
20
20
|
|| type instanceof basic_1.AnyType
|
|
21
21
|
|| type instanceof basic_1.UnknownType
|
|
22
22
|
|| type instanceof basic_1.NumericType
|
|
23
|
+
|| type instanceof basic_1.CSequenceType
|
|
23
24
|
|| type instanceof basic_1.DateType
|
|
24
25
|
|| type instanceof basic_1.CLikeType
|
|
25
26
|
|| type instanceof basic_1.PackedType
|
|
@@ -18,6 +18,12 @@ class FieldAssignment {
|
|
|
18
18
|
let type = undefined;
|
|
19
19
|
if (targetType instanceof basic_1.StructureType) {
|
|
20
20
|
type = targetType.getComponentByName(name);
|
|
21
|
+
if (type === undefined && targetType.containsVoid() === false) {
|
|
22
|
+
throw new Error(`field ${name} does not exist in structure`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (targetType instanceof basic_1.VoidType) {
|
|
26
|
+
type = targetType;
|
|
21
27
|
}
|
|
22
28
|
new source_1.Source().runSyntax(s, scope, filename, type);
|
|
23
29
|
}
|
|
@@ -70,7 +70,7 @@ class SemanticHighlighting {
|
|
|
70
70
|
|| statementInstance instanceof Statements.MethodImplementation
|
|
71
71
|
|| statementInstance instanceof Statements.EndMethod
|
|
72
72
|
|| statementInstance instanceof Statements.EndClass
|
|
73
|
-
|| statementInstance instanceof Statements.
|
|
73
|
+
|| statementInstance instanceof Statements.Interface
|
|
74
74
|
|| statementInstance instanceof Statements.EndInterface
|
|
75
75
|
|| statementInstance instanceof Statements.Form
|
|
76
76
|
|| statementInstance instanceof Statements.EndForm) {
|
|
@@ -35,7 +35,7 @@ class Domain extends _abstract_object_1.AbstractObject {
|
|
|
35
35
|
return this.parsedType;
|
|
36
36
|
}
|
|
37
37
|
parse() {
|
|
38
|
-
var _a, _b, _c;
|
|
38
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
39
39
|
if (this.parsedXML) {
|
|
40
40
|
return { updated: false, runtime: 0 };
|
|
41
41
|
}
|
|
@@ -46,15 +46,32 @@ class Domain extends _abstract_object_1.AbstractObject {
|
|
|
46
46
|
return { updated: false, runtime: 0 };
|
|
47
47
|
}
|
|
48
48
|
const dd01v = (_c = (_b = (_a = parsed.abapGit) === null || _a === void 0 ? void 0 : _a["asx:abap"]) === null || _b === void 0 ? void 0 : _b["asx:values"]) === null || _c === void 0 ? void 0 : _c.DD01V;
|
|
49
|
+
const dd07v_tab = (_g = (_f = (_e = (_d = parsed.abapGit) === null || _d === void 0 ? void 0 : _d["asx:abap"]) === null || _e === void 0 ? void 0 : _e["asx:values"]) === null || _f === void 0 ? void 0 : _f.DD07V_TAB) === null || _g === void 0 ? void 0 : _g.DD07V;
|
|
50
|
+
const values = [];
|
|
51
|
+
if (dd07v_tab) {
|
|
52
|
+
for (const ddo7v of dd07v_tab) {
|
|
53
|
+
const value = {
|
|
54
|
+
description: ddo7v === null || ddo7v === void 0 ? void 0 : ddo7v.DDTEXT,
|
|
55
|
+
value: ddo7v === null || ddo7v === void 0 ? void 0 : ddo7v.DOMVALUE_L,
|
|
56
|
+
language: ddo7v === null || ddo7v === void 0 ? void 0 : ddo7v.DDLANGUAGE,
|
|
57
|
+
};
|
|
58
|
+
values.push(value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
49
61
|
this.parsedXML = {
|
|
50
62
|
description: dd01v === null || dd01v === void 0 ? void 0 : dd01v.DDTEXT,
|
|
51
63
|
datatype: dd01v === null || dd01v === void 0 ? void 0 : dd01v.DATATYPE,
|
|
52
64
|
length: dd01v === null || dd01v === void 0 ? void 0 : dd01v.LENG,
|
|
53
65
|
decimals: dd01v === null || dd01v === void 0 ? void 0 : dd01v.DECIMALS,
|
|
66
|
+
values: values,
|
|
54
67
|
};
|
|
55
68
|
const end = Date.now();
|
|
56
69
|
return { updated: true, runtime: end - start };
|
|
57
70
|
}
|
|
71
|
+
getFixedValues() {
|
|
72
|
+
var _a, _b;
|
|
73
|
+
return (_b = (_a = this.parsedXML) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : [];
|
|
74
|
+
}
|
|
58
75
|
}
|
|
59
76
|
exports.Domain = Domain;
|
|
60
77
|
//# sourceMappingURL=domain.js.map
|
package/build/src/registry.js
CHANGED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConstantClasses = exports.ConstantClassesConf = void 0;
|
|
4
|
+
const issue_1 = require("../issue");
|
|
5
|
+
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
6
|
+
const _irule_1 = require("./_irule");
|
|
7
|
+
const __1 = require("..");
|
|
8
|
+
/** Checks that constants classes are in sync with domain fixed values */
|
|
9
|
+
class ConstantClassesConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
10
|
+
}
|
|
11
|
+
exports.ConstantClassesConf = ConstantClassesConf;
|
|
12
|
+
class ConstantClasses {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.conf = new ConstantClassesConf();
|
|
15
|
+
}
|
|
16
|
+
getMetadata() {
|
|
17
|
+
return {
|
|
18
|
+
key: "constant_classes",
|
|
19
|
+
title: "Validate constant classes",
|
|
20
|
+
shortDescription: `Checks that a class contains exactly the constants corresponding to a domain's fixed values.`,
|
|
21
|
+
extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-enumeration-classes-to-constants-interfaces`,
|
|
22
|
+
tags: [_irule_1.RuleTag.Syntax, _irule_1.RuleTag.Styleguide, _irule_1.RuleTag.Experimental],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
initialize(reg) {
|
|
26
|
+
this.reg = reg;
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
getConfig() {
|
|
30
|
+
return this.conf;
|
|
31
|
+
}
|
|
32
|
+
setConfig(conf) {
|
|
33
|
+
this.conf = conf;
|
|
34
|
+
}
|
|
35
|
+
run(obj) {
|
|
36
|
+
if (this.conf
|
|
37
|
+
&& this.conf.mapping
|
|
38
|
+
&& obj instanceof __1.Objects.Domain) {
|
|
39
|
+
const configEntry = this.conf.mapping.find(x => x.domain.toUpperCase() === obj.getName().toUpperCase());
|
|
40
|
+
if (!configEntry) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
const classWithConstants = this.reg.getObject("CLAS", configEntry === null || configEntry === void 0 ? void 0 : configEntry.class.toUpperCase());
|
|
44
|
+
if (!classWithConstants) {
|
|
45
|
+
return [issue_1.Issue.atIdentifier(obj.getIdentifier(), `Constant class pattern implementation ${configEntry.class} missing for domain ${configEntry.domain}`, this.getMetadata().key, this.conf.severity)];
|
|
46
|
+
// quickfix will implement the whole class
|
|
47
|
+
}
|
|
48
|
+
const classContents = classWithConstants.getMainABAPFile();
|
|
49
|
+
if (classContents === undefined) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const def = classWithConstants.getClassDefinition();
|
|
53
|
+
if (!def) {
|
|
54
|
+
// this issue is checked by rule implement_methods.
|
|
55
|
+
// we will not issue errors that all constants are missing until there is a class implementation
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const domainValueInfo = obj.getFixedValues();
|
|
59
|
+
const domainValues = domainValueInfo.map(x => x.value);
|
|
60
|
+
const issues = [];
|
|
61
|
+
if (obj.getFixedValues().length === 0) {
|
|
62
|
+
// possibly this is not even a domain with fixed values
|
|
63
|
+
issues.push(issue_1.Issue.atStatement(classContents, classContents.getStatements()[0], `Domain ${configEntry.domain} does not contain any fixed values. Either add some values or disable this check`, this.getMetadata().key, this.conf.severity));
|
|
64
|
+
}
|
|
65
|
+
// later we will raise an issue if we did not find it
|
|
66
|
+
let domainNameConstantFound = false;
|
|
67
|
+
for (const constant of def.constants) {
|
|
68
|
+
if (configEntry.constantForDomainName
|
|
69
|
+
&& constant.name === configEntry.constantForDomainName) {
|
|
70
|
+
// we require the constant value to be uppercase just in case
|
|
71
|
+
// in the config it does not matter
|
|
72
|
+
if (constant.value !== configEntry.domain.toLocaleUpperCase()) {
|
|
73
|
+
issues.push(this.issueAtConstant(constant, `Constant value ${constant.value} must match domain name ${configEntry.domain} `));
|
|
74
|
+
}
|
|
75
|
+
domainNameConstantFound = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (configEntry.useExactType && constant.typeName.toLowerCase() !== configEntry.domain.toLowerCase()) {
|
|
79
|
+
issues.push(this.issueAtConstant(constant, `Use exact type ${configEntry.domain} instead of ${constant.typeName}`));
|
|
80
|
+
// quickfix will change the type
|
|
81
|
+
}
|
|
82
|
+
if (constant.visibility !== __1.Visibility.Public) {
|
|
83
|
+
issues.push(this.issueAtConstant(constant, `Constant ${constant.name} should be public`));
|
|
84
|
+
// quickfix will move constant
|
|
85
|
+
}
|
|
86
|
+
if (!domainValues.includes(constant.value)) {
|
|
87
|
+
issues.push(this.issueAtConstant(constant, `Extra constant ${constant.name} found which is not present in domain ${configEntry.domain}`));
|
|
88
|
+
// quickfix will remove constant
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const d of domainValueInfo) {
|
|
92
|
+
if (!def.constants.find(c => c.value === d.value)) {
|
|
93
|
+
issues.push(issue_1.Issue.atStatement(classContents, classContents.getStatements()[0], `Missing constant for ${d.value} (domain ${configEntry.domain})`, this.getMetadata().key, this.conf.severity));
|
|
94
|
+
// quickfix will add constant
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (configEntry.constantForDomainName && !domainNameConstantFound) {
|
|
98
|
+
issues.push(issue_1.Issue.atStatement(classContents, classContents.getStatements()[0], `Missing constant ${configEntry.constantForDomainName} for name of domain ${configEntry.domain}`, this.getMetadata().key, this.conf.severity));
|
|
99
|
+
}
|
|
100
|
+
return issues;
|
|
101
|
+
}
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
issueAtConstant(constant, message) {
|
|
105
|
+
return issue_1.Issue.atIdentifier(constant.identifier, message, this.getMetadata().key, this.conf.severity);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.ConstantClasses = ConstantClasses;
|
|
109
|
+
//# sourceMappingURL=constant_classes.js.map
|
package/build/src/rules/index.js
CHANGED
|
@@ -142,4 +142,5 @@ __exportStar(require("./use_new"), exports);
|
|
|
142
142
|
__exportStar(require("./when_others_last"), exports);
|
|
143
143
|
__exportStar(require("./whitespace_end"), exports);
|
|
144
144
|
__exportStar(require("./xml_consistency"), exports);
|
|
145
|
+
__exportStar(require("./constant_classes"), exports);
|
|
145
146
|
//# sourceMappingURL=index.js.map
|
|
@@ -61,6 +61,8 @@ class ObsoleteStatementConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
61
61
|
this.sortByFS = true;
|
|
62
62
|
/** Checks for CALL TRANSFORMATION OBJECTS */
|
|
63
63
|
this.callTransformation = true;
|
|
64
|
+
/** Check for POSIX REGEX usage */
|
|
65
|
+
this.regex = true;
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
exports.ObsoleteStatementConf = ObsoleteStatementConf;
|
|
@@ -109,7 +111,9 @@ FREE MEMORY: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-us/abapfree
|
|
|
109
111
|
|
|
110
112
|
SORT BY FS: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abapsort_itab_obsolete.htm
|
|
111
113
|
|
|
112
|
-
CALL TRANSFORMATION OBJECTS: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abapcall_transformation_objects.htm
|
|
114
|
+
CALL TRANSFORMATION OBJECTS: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abapcall_transformation_objects.htm
|
|
115
|
+
|
|
116
|
+
POSIX REGEX: https://help.sap.com/doc/abapdocu_755_index_htm/7.55/en-US/index.htm`,
|
|
113
117
|
};
|
|
114
118
|
}
|
|
115
119
|
getConfig() {
|
|
@@ -266,6 +270,35 @@ CALL TRANSFORMATION OBJECTS: https://help.sap.com/doc/abapdocu_752_index_htm/7.5
|
|
|
266
270
|
issues.push(issue);
|
|
267
271
|
}
|
|
268
272
|
}
|
|
273
|
+
if (configVersion >= version_1.Version.v756 && this.conf.regex) {
|
|
274
|
+
if (sta instanceof Statements.Find || sta instanceof Statements.Replace) {
|
|
275
|
+
const concat = staNode.concatTokens().toUpperCase();
|
|
276
|
+
if (concat.includes("REGEX")) {
|
|
277
|
+
const issue = issue_1.Issue.atStatement(file, staNode, "REGEX obsolete, use PCRE", this.getMetadata().key, this.conf.severity);
|
|
278
|
+
issues.push(issue);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
const classNameExpression = staNode.findAllExpressions(Expressions.ClassName);
|
|
283
|
+
const methodNameExpression = staNode.findAllExpressions(Expressions.MethodName);
|
|
284
|
+
if (classNameExpression.length !== 0 && methodNameExpression.length !== 0) {
|
|
285
|
+
const className = classNameExpression[0].concatTokens();
|
|
286
|
+
const methodName = methodNameExpression[0].concatTokens();
|
|
287
|
+
if (className === "cl_abap_regex") {
|
|
288
|
+
if (methodName === "create_posix") {
|
|
289
|
+
const issue = issue_1.Issue.atStatement(file, staNode, "create_posix obsolete, use create_pcre", this.getMetadata().key, this.conf.severity);
|
|
290
|
+
issues.push(issue);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
else if (className === "cl_abap_matcher") {
|
|
294
|
+
if (methodName.includes("posix")) {
|
|
295
|
+
const issue = issue_1.Issue.atStatement(file, staNode, "posix methods obsolete, use pcre methods", this.getMetadata().key, this.conf.severity);
|
|
296
|
+
issues.push(issue);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
269
302
|
}
|
|
270
303
|
return issues;
|
|
271
304
|
}
|
|
@@ -45,7 +45,11 @@ ENDIF.`,
|
|
|
45
45
|
if (obj.getType() === "INTF") {
|
|
46
46
|
return [];
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
const vers = this.reg.getConfig().getVersion();
|
|
49
|
+
if (vers === version_1.Version.OpenABAP) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
else if (vers < version_1.Version.v740sp02 && vers !== version_1.Version.Cloud) {
|
|
49
53
|
return [];
|
|
50
54
|
}
|
|
51
55
|
const statements = file.getStatements();
|
package/build/src/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.79.2",
|
|
4
4
|
"description": "abaplint - Core API",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/abaplint.d.ts",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"homepage": "https://abaplint.org",
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@microsoft/api-extractor": "^7.18.
|
|
57
|
+
"@microsoft/api-extractor": "^7.18.9",
|
|
58
58
|
"@types/chai": "^4.2.21",
|
|
59
59
|
"@types/mocha": "^9.0.0",
|
|
60
60
|
"@types/node": "^16.9.1",
|