@abaplint/core 2.113.216 → 2.113.218
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/src/abap/2_statements/expressions/association_name.js +1 -1
- package/build/src/abap/5_syntax/_type_utils.js +2 -2
- package/build/src/abap/5_syntax/expressions/corresponding_body.js +1 -1
- package/build/src/abap/5_syntax/expressions/field_chain.js +3 -1
- package/build/src/abap/5_syntax/statements/loop.js +33 -4
- package/build/src/cds/expressions/cds_case.js +1 -1
- package/build/src/cds/expressions/cds_define_custom.js +1 -1
- package/build/src/registry.js +1 -1
- package/build/src/rules/downport.js +0 -1
- package/build/src/rules/fully_type_constants.js +2 -2
- package/build/src/rules/implement_methods.js +18 -1
- package/build/src/rules/unnecessary_return.js +2 -2
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ exports.AssociationName = void 0;
|
|
|
4
4
|
const combi_1 = require("../combi");
|
|
5
5
|
class AssociationName extends combi_1.Expression {
|
|
6
6
|
getRunnable() {
|
|
7
|
-
return (0, combi_1.regex)(
|
|
7
|
+
return (0, combi_1.regex)(/^(\\_[\w]+)+$/);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
exports.AssociationName = AssociationName;
|
|
@@ -448,7 +448,7 @@ class TypeUtils {
|
|
|
448
448
|
if (!(sourceRowType instanceof basic_1.StructureType)) {
|
|
449
449
|
return false;
|
|
450
450
|
}
|
|
451
|
-
else if (!
|
|
451
|
+
else if (!this.structureContainsString(sourceRowType)
|
|
452
452
|
&& this.structureContainsVoid(sourceRowType) === false) {
|
|
453
453
|
return false;
|
|
454
454
|
}
|
|
@@ -458,7 +458,7 @@ class TypeUtils {
|
|
|
458
458
|
if (!(targetRowType instanceof basic_1.StructureType)) {
|
|
459
459
|
return false;
|
|
460
460
|
}
|
|
461
|
-
else if (!
|
|
461
|
+
else if (!this.structureContainsString(targetRowType)
|
|
462
462
|
&& this.structureContainsVoid(targetRowType) === false) {
|
|
463
463
|
return false;
|
|
464
464
|
}
|
|
@@ -11,7 +11,7 @@ class CorrespondingBody {
|
|
|
11
11
|
}
|
|
12
12
|
const base = (_a = node.findDirectExpression(Expressions.CorrespondingBodyBase)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Source);
|
|
13
13
|
if (base) {
|
|
14
|
-
source_1.Source.runSyntax(base, input);
|
|
14
|
+
source_1.Source.runSyntax(base, input, targetType);
|
|
15
15
|
}
|
|
16
16
|
let type = undefined;
|
|
17
17
|
for (const s of node.findDirectExpressions(Expressions.Source)) {
|
|
@@ -50,8 +50,10 @@ class FieldChain {
|
|
|
50
50
|
}
|
|
51
51
|
else if (current.get() instanceof tokens_1.Dash) {
|
|
52
52
|
if (context instanceof basic_1.UnknownType) {
|
|
53
|
+
/*
|
|
53
54
|
const message = "Not a structure, type unknown, FieldChain";
|
|
54
|
-
input.issues.push(
|
|
55
|
+
input.issues.push(syntaxIssue(input, current.getFirstToken(), message));
|
|
56
|
+
*/
|
|
55
57
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
56
58
|
}
|
|
57
59
|
else if (!(context instanceof basic_1.StructureType)
|
|
@@ -12,9 +12,10 @@ const component_cond_1 = require("../expressions/component_cond");
|
|
|
12
12
|
const dynamic_1 = require("../expressions/dynamic");
|
|
13
13
|
const loop_group_by_1 = require("../expressions/loop_group_by");
|
|
14
14
|
const _syntax_input_1 = require("../_syntax_input");
|
|
15
|
+
const version_1 = require("../../../version");
|
|
15
16
|
class Loop {
|
|
16
17
|
runSyntax(node, input) {
|
|
17
|
-
var _a;
|
|
18
|
+
var _a, _b;
|
|
18
19
|
const loopTarget = node.findDirectExpression(Expressions.LoopTarget);
|
|
19
20
|
let target = loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.findDirectExpression(Expressions.Target);
|
|
20
21
|
const targetType = target ? target_1.Target.runSyntax(target, input) : undefined;
|
|
@@ -64,6 +65,7 @@ class Loop {
|
|
|
64
65
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
65
66
|
}
|
|
66
67
|
const targetConcat = loopTarget === null || loopTarget === void 0 ? void 0 : loopTarget.concatTokens().toUpperCase();
|
|
68
|
+
const topType = sourceType; // todo: refactor topType vs sourceType vs rowType
|
|
67
69
|
if (sourceType instanceof basic_1.TableType) {
|
|
68
70
|
rowType = sourceType.getRowType();
|
|
69
71
|
sourceType = rowType;
|
|
@@ -71,6 +73,10 @@ class Loop {
|
|
|
71
73
|
sourceType = new basic_1.DataReference(sourceType);
|
|
72
74
|
}
|
|
73
75
|
}
|
|
76
|
+
const cond = node.findDirectExpression(Expressions.ComponentCond);
|
|
77
|
+
if (cond !== undefined) {
|
|
78
|
+
component_cond_1.ComponentCond.runSyntax(cond, input, rowType);
|
|
79
|
+
}
|
|
74
80
|
if (targetConcat
|
|
75
81
|
&& targetConcat.startsWith("TRANSPORTING ")
|
|
76
82
|
&& node.findDirectTokenByText("WHERE") === undefined) {
|
|
@@ -78,6 +84,32 @@ class Loop {
|
|
|
78
84
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
79
85
|
return;
|
|
80
86
|
}
|
|
87
|
+
if (node.findDirectTokenByText("USING") !== undefined
|
|
88
|
+
&& cond !== undefined
|
|
89
|
+
&& topType instanceof basic_1.TableType) {
|
|
90
|
+
// https://github.com/abap2xlsx/abap2xlsx/issues/1341
|
|
91
|
+
const keyName = node.findExpressionAfterToken("KEY");
|
|
92
|
+
let key = undefined;
|
|
93
|
+
if ((keyName === null || keyName === void 0 ? void 0 : keyName.get()) instanceof Expressions.SimpleName) {
|
|
94
|
+
// it might be dynamic, in that case we cannot check anything
|
|
95
|
+
key = (_b = topType.getOptions().secondary) === null || _b === void 0 ? void 0 : _b.find(k => k.name.toUpperCase() === keyName.getFirstToken().getStr().toUpperCase());
|
|
96
|
+
if (key === undefined) {
|
|
97
|
+
const message = "Key " + (keyName === null || keyName === void 0 ? void 0 : keyName.concatTokens()) + " not found in table type";
|
|
98
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (input.scope.getRegistry().getConfig().getVersion() <= version_1.Version.v740sp02) {
|
|
102
|
+
const compares = cond.findAllExpressionsRecursive(Expressions.ComponentCompare).map(c => c.concatTokens().toUpperCase());
|
|
103
|
+
for (const keyField of key.keyFields) {
|
|
104
|
+
if (compares.find(c => c === keyField.toUpperCase() + " IS INITIAL") !== undefined) {
|
|
105
|
+
const message = "Loop, key check with IS INITIAL cannot optimized before 7.40 SP02";
|
|
106
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
81
113
|
const inline = target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData);
|
|
82
114
|
if (inline) {
|
|
83
115
|
inline_data_1.InlineData.runSyntax(inline, input, sourceType);
|
|
@@ -98,9 +130,6 @@ class Loop {
|
|
|
98
130
|
fstarget_1.FSTarget.runSyntax(fstarget, input, sourceType);
|
|
99
131
|
}
|
|
100
132
|
}
|
|
101
|
-
for (const t of node.findDirectExpressions(Expressions.ComponentCond)) {
|
|
102
|
-
component_cond_1.ComponentCond.runSyntax(t, input, rowType);
|
|
103
|
-
}
|
|
104
133
|
for (const t of node.findDirectExpressions(Expressions.Dynamic)) {
|
|
105
134
|
dynamic_1.Dynamic.runSyntax(t, input);
|
|
106
135
|
}
|
|
@@ -6,7 +6,7 @@ const combi_1 = require("../../abap/2_statements/combi");
|
|
|
6
6
|
class CDSCase extends combi_1.Expression {
|
|
7
7
|
getRunnable() {
|
|
8
8
|
const name = (0, combi_1.seq)(_1.CDSName, (0, combi_1.starPrio)((0, combi_1.seq)(".", _1.CDSName)));
|
|
9
|
-
const value = (0, combi_1.altPrio)(_1.
|
|
9
|
+
const value = (0, combi_1.altPrio)(_1.CDSString, CDSCase, _1.CDSCast, _1.CDSArithmetics, _1.CDSFunction, name);
|
|
10
10
|
const thenValue = (0, combi_1.altPrio)((0, combi_1.seq)("(", value, ")"), value);
|
|
11
11
|
const simple = (0, combi_1.seq)((0, combi_1.altPrio)(_1.CDSFunction, name), (0, combi_1.plusPrio)((0, combi_1.seq)("WHEN", value, "THEN", thenValue)));
|
|
12
12
|
const complex = (0, combi_1.plusPrio)((0, combi_1.seq)("WHEN", _1.CDSCondition, "THEN", thenValue));
|
|
@@ -9,7 +9,7 @@ class CDSDefineCustom extends combi_1.Expression {
|
|
|
9
9
|
getRunnable() {
|
|
10
10
|
const field = (0, combi_1.seq)((0, combi_1.opt)((0, combi_1.str)("KEY")), cds_name_1.CDSName, ":", cds_type_1.CDSType, ";");
|
|
11
11
|
const compsiOrAssoci = (0, combi_1.seq)(cds_name_1.CDSName, ":", (0, combi_1.alt)(_1.CDSComposition, _1.CDSAssociation), ";");
|
|
12
|
-
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.str)("DEFINE"), (0, combi_1.opt)((0, combi_1.str)("ROOT")), (0, combi_1.str)("CUSTOM ENTITY"), (0, combi_1.opt)(_1.CDSWithParameters),
|
|
12
|
+
return (0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.str)("DEFINE"), (0, combi_1.opt)((0, combi_1.str)("ROOT")), (0, combi_1.str)("CUSTOM ENTITY"), cds_name_1.CDSName, (0, combi_1.opt)(_1.CDSWithParameters), (0, combi_1.str)("{"), (0, combi_1.plus)((0, combi_1.seq)((0, combi_1.star)(_1.CDSAnnotation), (0, combi_1.alt)(field, compsiOrAssoci))), (0, combi_1.str)("}"), (0, combi_1.opt)(";"));
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
exports.CDSDefineCustom = CDSDefineCustom;
|
package/build/src/registry.js
CHANGED
|
@@ -939,7 +939,6 @@ ${indentation}${uniqueName} = ${source.concatTokens()}.\n${indentation}`);
|
|
|
939
939
|
const source = high.findExpressionAfterToken("MESSAGE");
|
|
940
940
|
if ((source === null || source === void 0 ? void 0 : source.get()) instanceof Expressions.MessageSourceSource
|
|
941
941
|
&& ((_a = source.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Source) {
|
|
942
|
-
;
|
|
943
942
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
944
943
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
945
944
|
const firstToken = high.getFirstToken();
|
|
@@ -45,7 +45,7 @@ class FullyTypeConstants extends _abap_rule_1.ABAPRule {
|
|
|
45
45
|
for (const stat of file.getStatements()) {
|
|
46
46
|
if ((stat.get() instanceof Statements.Constant
|
|
47
47
|
|| (this.conf.checkData === true && stat.get() instanceof Statements.Data))
|
|
48
|
-
&&
|
|
48
|
+
&& !this.isTyped(stat)) {
|
|
49
49
|
const type = stat.get() instanceof Statements.Constant ? "constant definition" : "data definition";
|
|
50
50
|
let token = (_a = stat.findFirstExpression(expressions_1.NamespaceSimpleName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
|
|
51
51
|
if (token === undefined) {
|
|
@@ -60,7 +60,7 @@ class FullyTypeConstants extends _abap_rule_1.ABAPRule {
|
|
|
60
60
|
return issues;
|
|
61
61
|
}
|
|
62
62
|
isTyped(stat) {
|
|
63
|
-
return
|
|
63
|
+
return stat.findFirstExpression(expressions_1.Type) || stat.findFirstExpression(expressions_1.TypeTable);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
exports.FullyTypeConstants = FullyTypeConstants;
|
|
@@ -180,7 +180,7 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
|
|
|
180
180
|
return [idef];
|
|
181
181
|
}
|
|
182
182
|
for (const m of this.findInterfaceMethods(idef)) {
|
|
183
|
-
if (
|
|
183
|
+
if (this.isAbstract(m, interfaceInfo, def)) {
|
|
184
184
|
continue;
|
|
185
185
|
}
|
|
186
186
|
if (this.isImplemented(m, def, impl) === false) {
|
|
@@ -199,6 +199,23 @@ class ImplementMethods extends _abap_rule_1.ABAPRule {
|
|
|
199
199
|
}
|
|
200
200
|
return ret;
|
|
201
201
|
}
|
|
202
|
+
isAbstract(m, interfaceInfo, def) {
|
|
203
|
+
if (interfaceInfo.abstractMethods.includes(m.method.name.toUpperCase())) {
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
if (!def.superClassName) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
// look up in superclass if method is abstract there
|
|
210
|
+
const superClass = this.findClass(def.superClassName);
|
|
211
|
+
const superInterface = superClass === null || superClass === void 0 ? void 0 : superClass.def.interfaces.find(iface => iface.name.toUpperCase() === m.objectName.toUpperCase());
|
|
212
|
+
if (superClass && superInterface) {
|
|
213
|
+
return this.isAbstract(m, superInterface, superClass.def);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
202
219
|
isImplemented(m, def, impl) {
|
|
203
220
|
if (impl === undefined) {
|
|
204
221
|
return false;
|
|
@@ -61,9 +61,9 @@ ENDFORM.`,
|
|
|
61
61
|
for (let i = 0; i < statements.length; i++) {
|
|
62
62
|
const node = statements[i];
|
|
63
63
|
const nodeType = node.get();
|
|
64
|
-
if (
|
|
64
|
+
if (nodeType instanceof Statements.MethodImplementation
|
|
65
65
|
|| nodeType instanceof Statements.Form
|
|
66
|
-
|| nodeType instanceof Statements.FunctionModule)
|
|
66
|
+
|| nodeType instanceof Statements.FunctionModule) {
|
|
67
67
|
statementCounter = 0;
|
|
68
68
|
continue;
|
|
69
69
|
}
|