@abaplint/core 2.101.14 → 2.101.16
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 +20 -1
- package/build/adhoc/syntax_performance.d.ts +1 -0
- package/build/adhoc/syntax_performance.js +15 -0
- package/build/adhoc/typed_array.d.ts +20 -0
- package/build/adhoc/typed_array.js +47 -0
- package/build/src/abap/5_syntax/_builtin.js +173 -173
- package/build/src/abap/5_syntax/_type_utils.js +2 -1
- package/build/src/abap/5_syntax/basic_types.js +9 -3
- package/build/src/abap/5_syntax/expressions/constant.js +4 -3
- package/build/src/abap/5_syntax/expressions/inline_loop_definition.js +1 -1
- package/build/src/abap/5_syntax/expressions/method_call_param.js +1 -1
- package/build/src/abap/5_syntax/expressions/method_param.js +3 -0
- package/build/src/abap/5_syntax/expressions/source.js +2 -2
- package/build/src/abap/5_syntax/expressions/string_template.js +2 -2
- package/build/src/abap/5_syntax/statements/concatenate.js +26 -4
- package/build/src/abap/5_syntax/statements/controls.js +6 -6
- package/build/src/abap/5_syntax/statements/describe.js +3 -3
- package/build/src/abap/5_syntax/statements/find.js +10 -10
- package/build/src/abap/5_syntax/statements/get_bit.js +1 -1
- package/build/src/abap/5_syntax/statements/get_run_time.js +1 -1
- package/build/src/abap/5_syntax/statements/message.js +1 -1
- package/build/src/abap/5_syntax/statements/read_table.js +2 -2
- package/build/src/abap/5_syntax/statements/split.js +1 -1
- package/build/src/abap/5_syntax/structures/type_enum.js +2 -2
- package/build/src/abap/types/basic/hex_type.js +1 -1
- package/build/src/abap/types/basic/index.js +1 -0
- package/build/src/abap/types/basic/integer_type.js +19 -0
- package/build/src/abap/types/basic/string_type.js +19 -0
- package/build/src/abap/types/basic/xgeneric_type.js +23 -0
- package/build/src/ddic.js +5 -4
- package/build/src/registry.js +1 -1
- package/build/src/rules/align_parameters.js +17 -2
- package/build/src/rules/downport.js +4 -0
- package/build/src/rules/fully_type_itabs.js +2 -2
- package/build/src/rules/select_single_full_key.js +1 -2
- package/package.json +4 -2
|
@@ -92,6 +92,7 @@ class TypeUtils {
|
|
|
92
92
|
else if (type instanceof basic_1.XStringType
|
|
93
93
|
|| type instanceof basic_1.HexType
|
|
94
94
|
|| type instanceof basic_1.VoidType
|
|
95
|
+
|| type instanceof basic_1.XGenericType
|
|
95
96
|
|| type instanceof basic_1.XSequenceType
|
|
96
97
|
|| type instanceof basic_1.AnyType
|
|
97
98
|
|| type instanceof basic_1.UnknownType) {
|
|
@@ -252,7 +253,7 @@ class TypeUtils {
|
|
|
252
253
|
if (target instanceof basic_1.StructureType && this.structureContainsString(target)) {
|
|
253
254
|
return false;
|
|
254
255
|
}
|
|
255
|
-
else if (target instanceof basic_1.XSequenceType) {
|
|
256
|
+
else if (target instanceof basic_1.XSequenceType || target instanceof basic_1.XStringType) {
|
|
256
257
|
if (((_f = source.getAbstractTypeData()) === null || _f === void 0 ? void 0 : _f.derivedFromConstant) === true) {
|
|
257
258
|
return true;
|
|
258
259
|
}
|
|
@@ -24,7 +24,7 @@ class BasicTypes {
|
|
|
24
24
|
}
|
|
25
25
|
lookupQualifiedName(name) {
|
|
26
26
|
var _a;
|
|
27
|
-
// argh, todo, rewrite this entire method, more argh
|
|
27
|
+
// argh, todo, rewrite this entire method, more argh, again argh
|
|
28
28
|
if (name === undefined) {
|
|
29
29
|
return undefined;
|
|
30
30
|
}
|
|
@@ -45,7 +45,10 @@ class BasicTypes {
|
|
|
45
45
|
const stru = oo.getTypeDefinitions().getByName(subTypeName);
|
|
46
46
|
const struType = stru === null || stru === void 0 ? void 0 : stru.getType();
|
|
47
47
|
if (stru && struType instanceof basic_1.StructureType) {
|
|
48
|
-
|
|
48
|
+
let f = struType.getComponentByName(fieldName);
|
|
49
|
+
if (split[2] && f instanceof basic_1.StructureType) {
|
|
50
|
+
f = f.getComponentByName(split[2]);
|
|
51
|
+
}
|
|
49
52
|
if (f) {
|
|
50
53
|
return new _typed_identifier_1.TypedIdentifier(stru.getToken(), stru.getFilename(), f);
|
|
51
54
|
}
|
|
@@ -67,7 +70,10 @@ class BasicTypes {
|
|
|
67
70
|
if (type) {
|
|
68
71
|
const stru = type.getType();
|
|
69
72
|
if (stru instanceof basic_1.StructureType) {
|
|
70
|
-
|
|
73
|
+
let f = stru.getComponentByName(fieldName);
|
|
74
|
+
if (split[2] && f instanceof basic_1.StructureType) {
|
|
75
|
+
f = f.getComponentByName(split[2]);
|
|
76
|
+
}
|
|
71
77
|
if (f) {
|
|
72
78
|
return new _typed_identifier_1.TypedIdentifier(type.getToken(), type.getFilename(), f);
|
|
73
79
|
}
|
|
@@ -5,8 +5,9 @@ const basic_1 = require("../../types/basic");
|
|
|
5
5
|
const expressions_1 = require("../../2_statements/expressions");
|
|
6
6
|
class Constant {
|
|
7
7
|
runSyntax(node) {
|
|
8
|
+
// todo: ConcatenatedConstant is not used?
|
|
8
9
|
if (node.findDirectExpression(expressions_1.Integer)) {
|
|
9
|
-
return
|
|
10
|
+
return basic_1.IntegerType.get();
|
|
10
11
|
}
|
|
11
12
|
else if (node.getFirstToken().getStr().startsWith("'")) {
|
|
12
13
|
let len = node.getFirstToken().getStr().length - 2;
|
|
@@ -16,10 +17,10 @@ class Constant {
|
|
|
16
17
|
return new basic_1.CharacterType(len, { derivedFromConstant: true });
|
|
17
18
|
}
|
|
18
19
|
else if (node.getFirstToken().getStr().startsWith("`")) {
|
|
19
|
-
return
|
|
20
|
+
return basic_1.StringType.get({ derivedFromConstant: true });
|
|
20
21
|
}
|
|
21
22
|
else {
|
|
22
|
-
return
|
|
23
|
+
return basic_1.StringType.get();
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -43,7 +43,7 @@ class InlineLoopDefinition {
|
|
|
43
43
|
}
|
|
44
44
|
const index = node.findExpressionAfterToken("INTO");
|
|
45
45
|
if (index && index.get() instanceof Expressions.TargetField) {
|
|
46
|
-
const identifier = new _typed_identifier_1.TypedIdentifier(index.getFirstToken(), filename,
|
|
46
|
+
const identifier = new _typed_identifier_1.TypedIdentifier(index.getFirstToken(), filename, basic_1.IntegerType.get(), ["inline" /* IdentifierMeta.InlineDefinition */]);
|
|
47
47
|
scope.addReference(index.getFirstToken(), identifier, _reference_1.ReferenceType.DataWriteReference, filename);
|
|
48
48
|
scope.addIdentifier(identifier);
|
|
49
49
|
}
|
|
@@ -48,7 +48,7 @@ class MethodCallParam {
|
|
|
48
48
|
else {
|
|
49
49
|
targetType = method;
|
|
50
50
|
}
|
|
51
|
-
let sourceType =
|
|
51
|
+
let sourceType = basic_1.StringType.get();
|
|
52
52
|
if (child.get() instanceof Expressions.Source) {
|
|
53
53
|
sourceType = new source_1.Source().runSyntax(child, scope, filename, targetType);
|
|
54
54
|
}
|
|
@@ -30,6 +30,9 @@ class MethodParam {
|
|
|
30
30
|
if (concat === "TYPE C" || concat.startsWith("TYPE C ")) {
|
|
31
31
|
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), filename, new cgeneric_type_1.CGenericType(), meta);
|
|
32
32
|
}
|
|
33
|
+
else if (concat === "TYPE X" || concat.startsWith("TYPE X ")) {
|
|
34
|
+
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), filename, new basic_1.XGenericType(), meta);
|
|
35
|
+
}
|
|
33
36
|
const found = new basic_types_1.BasicTypes(filename, scope).parseType(type);
|
|
34
37
|
if (found) {
|
|
35
38
|
return new _typed_identifier_1.TypedIdentifier(name.getFirstToken(), filename, found, meta);
|
|
@@ -52,7 +52,7 @@ class Source {
|
|
|
52
52
|
const method = new _builtin_1.BuiltIn().searchBuiltin(tok);
|
|
53
53
|
scope.addReference(token, method, _reference_1.ReferenceType.BuiltinMethodReference, filename);
|
|
54
54
|
new cond_1.Cond().runSyntax(node.findDirectExpression(Expressions.Cond), scope, filename);
|
|
55
|
-
return
|
|
55
|
+
return basic_1.StringType.get();
|
|
56
56
|
}
|
|
57
57
|
case "XSDBOOL":
|
|
58
58
|
{
|
|
@@ -195,7 +195,7 @@ class Source {
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
if (node.findDirectTokenByText("&&")) {
|
|
198
|
-
return
|
|
198
|
+
return basic_1.StringType.get();
|
|
199
199
|
}
|
|
200
200
|
return context;
|
|
201
201
|
}
|
|
@@ -10,7 +10,7 @@ class StringTemplate {
|
|
|
10
10
|
const typeUtils = new _type_utils_1.TypeUtils(scope);
|
|
11
11
|
for (const templateSource of node.findAllExpressions(Expressions.StringTemplateSource)) {
|
|
12
12
|
const s = templateSource.findDirectExpression(Expressions.Source);
|
|
13
|
-
const type = new source_1.Source().runSyntax(s, scope, filename,
|
|
13
|
+
const type = new source_1.Source().runSyntax(s, scope, filename, basic_1.StringType.get());
|
|
14
14
|
if (type === undefined) {
|
|
15
15
|
throw new Error("No target type determined");
|
|
16
16
|
}
|
|
@@ -34,7 +34,7 @@ class StringTemplate {
|
|
|
34
34
|
throw new Error("Cannot apply ALPHA to this type");
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
return
|
|
37
|
+
return basic_1.StringType.get();
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
exports.StringTemplate = StringTemplate;
|
|
@@ -6,19 +6,41 @@ const source_1 = require("../expressions/source");
|
|
|
6
6
|
const target_1 = require("../expressions/target");
|
|
7
7
|
const basic_1 = require("../../types/basic");
|
|
8
8
|
const inline_data_1 = require("../expressions/inline_data");
|
|
9
|
+
const _type_utils_1 = require("../_type_utils");
|
|
9
10
|
class Concatenate {
|
|
10
11
|
runSyntax(node, scope, filename) {
|
|
12
|
+
const byteMode = node.findDirectTokenByText("BYTE") !== undefined;
|
|
13
|
+
let linesMode = node.findDirectTokenByText("LINES") !== undefined;
|
|
11
14
|
const target = node.findFirstExpression(Expressions.Target);
|
|
12
15
|
const inline = target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData);
|
|
13
16
|
if (inline) {
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
if (byteMode) {
|
|
18
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, new basic_1.XStringType());
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, basic_1.StringType.get());
|
|
22
|
+
}
|
|
16
23
|
}
|
|
17
24
|
else if (target) {
|
|
18
|
-
new target_1.Target().runSyntax(target, scope, filename);
|
|
25
|
+
const type = new target_1.Target().runSyntax(target, scope, filename);
|
|
26
|
+
const compatible = byteMode ? new _type_utils_1.TypeUtils(scope).isHexLike(type) : new _type_utils_1.TypeUtils(scope).isCharLike(type);
|
|
27
|
+
if (compatible === false) {
|
|
28
|
+
throw new Error("Target type not compatible");
|
|
29
|
+
}
|
|
19
30
|
}
|
|
20
31
|
for (const s of node.findDirectExpressions(Expressions.Source)) {
|
|
21
|
-
new source_1.Source().runSyntax(s, scope, filename);
|
|
32
|
+
const type = new source_1.Source().runSyntax(s, scope, filename);
|
|
33
|
+
if (linesMode) {
|
|
34
|
+
if (!(type instanceof basic_1.UnknownType) && !(type instanceof basic_1.VoidType) && !(type instanceof basic_1.TableType)) {
|
|
35
|
+
throw new Error("Source must be an internal table");
|
|
36
|
+
}
|
|
37
|
+
linesMode = false;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const compatible = byteMode ? new _type_utils_1.TypeUtils(scope).isHexLike(type) : new _type_utils_1.TypeUtils(scope).isCharLike(type);
|
|
41
|
+
if (compatible === false) {
|
|
42
|
+
throw new Error("Source type not compatible");
|
|
43
|
+
}
|
|
22
44
|
}
|
|
23
45
|
}
|
|
24
46
|
}
|
|
@@ -16,17 +16,17 @@ class Controls {
|
|
|
16
16
|
if (node.findDirectTokenByText("TABLEVIEW") && token) {
|
|
17
17
|
const cols = new basic_1.StructureType([
|
|
18
18
|
{ name: "SCREEN", type: new basic_1.CharacterType(1) },
|
|
19
|
-
{ name: "INDEX", type:
|
|
19
|
+
{ name: "INDEX", type: basic_1.IntegerType.get() },
|
|
20
20
|
{ name: "SELECTED", type: new basic_1.CharacterType(1) },
|
|
21
|
-
{ name: "VISLENGTH", type:
|
|
21
|
+
{ name: "VISLENGTH", type: basic_1.IntegerType.get() },
|
|
22
22
|
{ name: "INVISIBLE", type: new basic_1.CharacterType(1) },
|
|
23
23
|
]);
|
|
24
24
|
const type = new basic_1.StructureType([
|
|
25
25
|
{ name: "FIXED_COLS", type: new basic_1.CharacterType(132) },
|
|
26
|
-
{ name: "LINES", type:
|
|
27
|
-
{ name: "TOP_LINE", type:
|
|
28
|
-
{ name: "CURRENT_LINE", type:
|
|
29
|
-
{ name: "LEFT_COL", type:
|
|
26
|
+
{ name: "LINES", type: basic_1.IntegerType.get() },
|
|
27
|
+
{ name: "TOP_LINE", type: basic_1.IntegerType.get() },
|
|
28
|
+
{ name: "CURRENT_LINE", type: basic_1.IntegerType.get() },
|
|
29
|
+
{ name: "LEFT_COL", type: basic_1.IntegerType.get() },
|
|
30
30
|
{ name: "LINE_SEL_MODE", type: new basic_1.CharacterType(1) },
|
|
31
31
|
{ name: "COL_SEL_MODE", type: new basic_1.CharacterType(1) },
|
|
32
32
|
{ name: "LINE_SELECTOR", type: new basic_1.CharacterType(1) },
|
|
@@ -20,7 +20,7 @@ class Describe {
|
|
|
20
20
|
if ((linesTarget === null || linesTarget === void 0 ? void 0 : linesTarget.get()) instanceof Expressions.Target) {
|
|
21
21
|
const inline = linesTarget === null || linesTarget === void 0 ? void 0 : linesTarget.findDirectExpression(Expressions.InlineData);
|
|
22
22
|
if (inline) {
|
|
23
|
-
new inline_data_1.InlineData().runSyntax(inline, scope, filename,
|
|
23
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, basic_1.IntegerType.get());
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
26
|
new target_1.Target().runSyntax(linesTarget, scope, filename);
|
|
@@ -40,7 +40,7 @@ class Describe {
|
|
|
40
40
|
if ((lengthTarget === null || lengthTarget === void 0 ? void 0 : lengthTarget.get()) instanceof Expressions.Target) {
|
|
41
41
|
const inline = lengthTarget === null || lengthTarget === void 0 ? void 0 : lengthTarget.findDirectExpression(Expressions.InlineData);
|
|
42
42
|
if (inline) {
|
|
43
|
-
new inline_data_1.InlineData().runSyntax(inline, scope, filename,
|
|
43
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, basic_1.IntegerType.get());
|
|
44
44
|
}
|
|
45
45
|
else {
|
|
46
46
|
new target_1.Target().runSyntax(lengthTarget, scope, filename);
|
|
@@ -50,7 +50,7 @@ class Describe {
|
|
|
50
50
|
if ((componentsTarget === null || componentsTarget === void 0 ? void 0 : componentsTarget.get()) instanceof Expressions.Target) {
|
|
51
51
|
const inline = componentsTarget === null || componentsTarget === void 0 ? void 0 : componentsTarget.findDirectExpression(Expressions.InlineData);
|
|
52
52
|
if (inline) {
|
|
53
|
-
new inline_data_1.InlineData().runSyntax(inline, scope, filename,
|
|
53
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, basic_1.IntegerType.get());
|
|
54
54
|
}
|
|
55
55
|
else {
|
|
56
56
|
new target_1.Target().runSyntax(componentsTarget, scope, filename);
|
|
@@ -14,13 +14,13 @@ class Find {
|
|
|
14
14
|
const rfound = node.findExpressionAfterToken("RESULTS");
|
|
15
15
|
if (rfound && rfound.get() instanceof Expressions.Target) {
|
|
16
16
|
const sub = new basic_1.StructureType([
|
|
17
|
-
{ name: "OFFSET", type:
|
|
18
|
-
{ name: "LENGTH", type:
|
|
17
|
+
{ name: "OFFSET", type: basic_1.IntegerType.get() },
|
|
18
|
+
{ name: "LENGTH", type: basic_1.IntegerType.get() }
|
|
19
19
|
], "SUBMATCH_RESULT", "SUBMATCH_RESULT");
|
|
20
20
|
const type = new basic_1.StructureType([
|
|
21
|
-
{ name: "LINE", type:
|
|
22
|
-
{ name: "OFFSET", type:
|
|
23
|
-
{ name: "LENGTH", type:
|
|
21
|
+
{ name: "LINE", type: basic_1.IntegerType.get() },
|
|
22
|
+
{ name: "OFFSET", type: basic_1.IntegerType.get() },
|
|
23
|
+
{ name: "LENGTH", type: basic_1.IntegerType.get() },
|
|
24
24
|
{ name: "SUBMATCHES", type: new basic_1.TableType(sub, { withHeader: false, keyType: basic_1.TableKeyType.default }) },
|
|
25
25
|
], "MATCH_RESULT", "MATCH_RESULT");
|
|
26
26
|
if (node.concatTokens().toUpperCase().startsWith("FIND FIRST")) {
|
|
@@ -33,20 +33,20 @@ class Find {
|
|
|
33
33
|
const ofound = node.findExpressionsAfterToken("OFFSET");
|
|
34
34
|
for (const o of ofound) {
|
|
35
35
|
if (o.get() instanceof Expressions.Target) {
|
|
36
|
-
this.inline(o, scope, filename,
|
|
36
|
+
this.inline(o, scope, filename, basic_1.IntegerType.get());
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
const lfound = node.findExpressionAfterToken("LINE");
|
|
40
40
|
if (lfound && lfound.get() instanceof Expressions.Target) {
|
|
41
|
-
this.inline(lfound, scope, filename,
|
|
41
|
+
this.inline(lfound, scope, filename, basic_1.IntegerType.get());
|
|
42
42
|
}
|
|
43
43
|
const cfound = node.findExpressionAfterToken("COUNT");
|
|
44
44
|
if (cfound && cfound.get() instanceof Expressions.Target) {
|
|
45
|
-
this.inline(cfound, scope, filename,
|
|
45
|
+
this.inline(cfound, scope, filename, basic_1.IntegerType.get());
|
|
46
46
|
}
|
|
47
47
|
const lnfound = node.findExpressionAfterToken("LENGTH");
|
|
48
48
|
if (lnfound && lnfound.get() instanceof Expressions.Target) {
|
|
49
|
-
this.inline(lnfound, scope, filename,
|
|
49
|
+
this.inline(lnfound, scope, filename, basic_1.IntegerType.get());
|
|
50
50
|
}
|
|
51
51
|
if (node.findDirectTokenByText("SUBMATCHES")) {
|
|
52
52
|
for (const t of node.findDirectExpressions(Expressions.Target)) {
|
|
@@ -58,7 +58,7 @@ class Find {
|
|
|
58
58
|
}
|
|
59
59
|
const inline = t === null || t === void 0 ? void 0 : t.findDirectExpression(Expressions.InlineData);
|
|
60
60
|
if (inline) {
|
|
61
|
-
new inline_data_1.InlineData().runSyntax(inline, scope, filename,
|
|
61
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, basic_1.StringType.get());
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
64
64
|
new target_1.Target().runSyntax(t, scope, filename);
|
|
@@ -19,7 +19,7 @@ class GetBit {
|
|
|
19
19
|
for (const t of node.findDirectExpressions(Expressions.Target)) {
|
|
20
20
|
const inline = t === null || t === void 0 ? void 0 : t.findDirectExpression(Expressions.InlineData);
|
|
21
21
|
if (inline) {
|
|
22
|
-
new inline_data_1.InlineData().runSyntax(t, scope, filename,
|
|
22
|
+
new inline_data_1.InlineData().runSyntax(t, scope, filename, basic_1.IntegerType.get());
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
25
25
|
new target_1.Target().runSyntax(t, scope, filename);
|
|
@@ -10,7 +10,7 @@ class GetRunTime {
|
|
|
10
10
|
const target = node.findDirectExpression(Expressions.Target);
|
|
11
11
|
const inline = target === null || target === void 0 ? void 0 : target.findDirectExpression(Expressions.InlineData);
|
|
12
12
|
if (inline) {
|
|
13
|
-
new inline_data_1.InlineData().runSyntax(inline, scope, filename,
|
|
13
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, basic_1.IntegerType.get());
|
|
14
14
|
}
|
|
15
15
|
else if (target) {
|
|
16
16
|
new target_1.Target().runSyntax(target, scope, filename);
|
|
@@ -12,7 +12,7 @@ class Message {
|
|
|
12
12
|
const found = node.findExpressionAfterToken("INTO");
|
|
13
13
|
const inline = found === null || found === void 0 ? void 0 : found.findDirectExpression(Expressions.InlineData);
|
|
14
14
|
if (inline) {
|
|
15
|
-
new inline_data_1.InlineData().runSyntax(inline, scope, filename,
|
|
15
|
+
new inline_data_1.InlineData().runSyntax(inline, scope, filename, basic_1.StringType.get());
|
|
16
16
|
}
|
|
17
17
|
else if (found) {
|
|
18
18
|
new target_1.Target().runSyntax(found, scope, filename);
|
|
@@ -35,14 +35,14 @@ class ReadTable {
|
|
|
35
35
|
const indexSource = node.findExpressionAfterToken("INDEX");
|
|
36
36
|
if (indexSource) {
|
|
37
37
|
const indexType = new source_1.Source().runSyntax(indexSource, scope, filename);
|
|
38
|
-
if (new _type_utils_1.TypeUtils(scope).isAssignable(indexType,
|
|
38
|
+
if (new _type_utils_1.TypeUtils(scope).isAssignable(indexType, basic_1.IntegerType.get()) === false) {
|
|
39
39
|
throw new Error("READ TABLE, INDEX must be simple");
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
const fromSource = node.findExpressionAfterToken("FROM");
|
|
43
43
|
if (fromSource) {
|
|
44
44
|
const fromType = new source_1.Source().runSyntax(fromSource, scope, filename);
|
|
45
|
-
if (new _type_utils_1.TypeUtils(scope).isAssignable(fromType,
|
|
45
|
+
if (new _type_utils_1.TypeUtils(scope).isAssignable(fromType, basic_1.IntegerType.get()) === false) {
|
|
46
46
|
throw new Error("READ TABLE, FROM must be simple");
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -10,7 +10,7 @@ const _type_utils_1 = require("../_type_utils");
|
|
|
10
10
|
class Split {
|
|
11
11
|
runSyntax(node, scope, filename) {
|
|
12
12
|
const intoTable = node.findTokenSequencePosition("INTO", "TABLE") !== undefined;
|
|
13
|
-
const type = intoTable ? new basic_1.TableType(
|
|
13
|
+
const type = intoTable ? new basic_1.TableType(basic_1.StringType.get(), { withHeader: false, keyType: basic_1.TableKeyType.default }) : basic_1.StringType.get();
|
|
14
14
|
for (const target of node.findAllExpressions(Expressions.Target)) {
|
|
15
15
|
const inline = target.findDirectExpression(Expressions.InlineData);
|
|
16
16
|
if (inline) {
|
|
@@ -28,7 +28,7 @@ class TypeEnum {
|
|
|
28
28
|
}
|
|
29
29
|
const token = expr.getFirstToken();
|
|
30
30
|
// integer is default if BASE TYPE is not specified
|
|
31
|
-
values.push(new _typed_identifier_1.TypedIdentifier(token, filename,
|
|
31
|
+
values.push(new _typed_identifier_1.TypedIdentifier(token, filename, basic_1.IntegerType.get()));
|
|
32
32
|
}
|
|
33
33
|
for (const type of node.findDirectStatements(Statements.TypeEnum)) {
|
|
34
34
|
const expr = type.findFirstExpression(Expressions.NamespaceSimpleName);
|
|
@@ -37,7 +37,7 @@ class TypeEnum {
|
|
|
37
37
|
}
|
|
38
38
|
const token = expr.getFirstToken();
|
|
39
39
|
// integer is default if BASE TYPE is not specified
|
|
40
|
-
values.push(new _typed_identifier_1.TypedIdentifier(token, filename,
|
|
40
|
+
values.push(new _typed_identifier_1.TypedIdentifier(token, filename, basic_1.IntegerType.get()));
|
|
41
41
|
}
|
|
42
42
|
const baseType = (_a = begin.findExpressionAfterToken("TYPE")) === null || _a === void 0 ? void 0 : _a.getFirstToken();
|
|
43
43
|
const baseName = baseType === null || baseType === void 0 ? void 0 : baseType.getStr();
|
|
@@ -6,7 +6,7 @@ class HexType extends _abstract_type_1.AbstractType {
|
|
|
6
6
|
constructor(length, qualifiedName) {
|
|
7
7
|
super({ qualifiedName: qualifiedName });
|
|
8
8
|
if (length <= 0) {
|
|
9
|
-
throw new Error("Bad
|
|
9
|
+
throw new Error("Bad LENGTH, Hex");
|
|
10
10
|
}
|
|
11
11
|
this.length = length;
|
|
12
12
|
}
|
|
@@ -42,6 +42,7 @@ __exportStar(require("./time_type"), exports);
|
|
|
42
42
|
__exportStar(require("./unknown_type"), exports);
|
|
43
43
|
__exportStar(require("./utc_long_type"), exports);
|
|
44
44
|
__exportStar(require("./void_type"), exports);
|
|
45
|
+
__exportStar(require("./xgeneric_type"), exports);
|
|
45
46
|
__exportStar(require("./xsequence_type"), exports);
|
|
46
47
|
__exportStar(require("./xstring_type"), exports);
|
|
47
48
|
//# sourceMappingURL=index.js.map
|
|
@@ -3,6 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.IntegerType = void 0;
|
|
4
4
|
const _abstract_type_1 = require("./_abstract_type");
|
|
5
5
|
class IntegerType extends _abstract_type_1.AbstractType {
|
|
6
|
+
static get(input) {
|
|
7
|
+
if (input === undefined) {
|
|
8
|
+
return this.singleton;
|
|
9
|
+
}
|
|
10
|
+
return new IntegerType(input);
|
|
11
|
+
}
|
|
12
|
+
constructor(input) {
|
|
13
|
+
super(input);
|
|
14
|
+
}
|
|
15
|
+
/** fully qualified symbolic name of the type */
|
|
16
|
+
getQualifiedName() {
|
|
17
|
+
var _a;
|
|
18
|
+
const qual = (_a = this.data) === null || _a === void 0 ? void 0 : _a.qualifiedName;
|
|
19
|
+
if (qual === undefined) {
|
|
20
|
+
return "I";
|
|
21
|
+
}
|
|
22
|
+
return qual;
|
|
23
|
+
}
|
|
6
24
|
toText() {
|
|
7
25
|
return "```i```";
|
|
8
26
|
}
|
|
@@ -20,4 +38,5 @@ class IntegerType extends _abstract_type_1.AbstractType {
|
|
|
20
38
|
}
|
|
21
39
|
}
|
|
22
40
|
exports.IntegerType = IntegerType;
|
|
41
|
+
IntegerType.singleton = new IntegerType();
|
|
23
42
|
//# sourceMappingURL=integer_type.js.map
|
|
@@ -3,6 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.StringType = void 0;
|
|
4
4
|
const _abstract_type_1 = require("./_abstract_type");
|
|
5
5
|
class StringType extends _abstract_type_1.AbstractType {
|
|
6
|
+
static get(input) {
|
|
7
|
+
if (input === undefined) {
|
|
8
|
+
return this.singleton;
|
|
9
|
+
}
|
|
10
|
+
return new StringType(input);
|
|
11
|
+
}
|
|
12
|
+
constructor(input) {
|
|
13
|
+
super(input);
|
|
14
|
+
}
|
|
15
|
+
/** fully qualified symbolic name of the type */
|
|
16
|
+
getQualifiedName() {
|
|
17
|
+
var _a;
|
|
18
|
+
const qual = (_a = this.data) === null || _a === void 0 ? void 0 : _a.qualifiedName;
|
|
19
|
+
if (qual === undefined) {
|
|
20
|
+
return "STRING";
|
|
21
|
+
}
|
|
22
|
+
return qual;
|
|
23
|
+
}
|
|
6
24
|
toText() {
|
|
7
25
|
return "```string```";
|
|
8
26
|
}
|
|
@@ -20,4 +38,5 @@ class StringType extends _abstract_type_1.AbstractType {
|
|
|
20
38
|
}
|
|
21
39
|
}
|
|
22
40
|
exports.StringType = StringType;
|
|
41
|
+
StringType.singleton = new StringType();
|
|
23
42
|
//# sourceMappingURL=string_type.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.XGenericType = void 0;
|
|
4
|
+
const _abstract_type_1 = require("./_abstract_type");
|
|
5
|
+
class XGenericType extends _abstract_type_1.AbstractType {
|
|
6
|
+
toText() {
|
|
7
|
+
return "```x```";
|
|
8
|
+
}
|
|
9
|
+
isGeneric() {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
toABAP() {
|
|
13
|
+
throw new Error("x, generic");
|
|
14
|
+
}
|
|
15
|
+
containsVoid() {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
toCDS() {
|
|
19
|
+
return "abap.TODO_CGENERIC";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.XGenericType = XGenericType;
|
|
23
|
+
//# sourceMappingURL=xgeneric_type.js.map
|
package/build/src/ddic.js
CHANGED
|
@@ -46,7 +46,7 @@ class DDIC {
|
|
|
46
46
|
lookupBuiltinType(name, length, decimals, qualifiedName) {
|
|
47
47
|
switch (name) {
|
|
48
48
|
case "STRING":
|
|
49
|
-
return
|
|
49
|
+
return Types.StringType.get({ qualifiedName: qualifiedName || name });
|
|
50
50
|
case "XSTRING":
|
|
51
51
|
return new Types.XStringType({ qualifiedName: qualifiedName || name });
|
|
52
52
|
case "D":
|
|
@@ -80,7 +80,7 @@ class DDIC {
|
|
|
80
80
|
case "CSEQUENCE":
|
|
81
81
|
return new Types.CSequenceType({ qualifiedName: qualifiedName });
|
|
82
82
|
case "I":
|
|
83
|
-
return
|
|
83
|
+
return Types.IntegerType.get({ qualifiedName: qualifiedName || name });
|
|
84
84
|
case "INT8": // todo, take version into account
|
|
85
85
|
return new Types.Integer8Type({ qualifiedName: qualifiedName || name });
|
|
86
86
|
case "F":
|
|
@@ -370,13 +370,14 @@ class DDIC {
|
|
|
370
370
|
case "INT1":
|
|
371
371
|
case "INT2":
|
|
372
372
|
case "INT4":
|
|
373
|
+
return Types.IntegerType.get({ qualifiedName: qualifiedName });
|
|
373
374
|
case "INT8":
|
|
374
|
-
return new Types.
|
|
375
|
+
return new Types.Integer8Type({ qualifiedName: qualifiedName });
|
|
375
376
|
case "SSTR": // 1 <= len <= 1333
|
|
376
377
|
case "SSTRING": // 1 <= len <= 1333
|
|
377
378
|
case "STRG": // 256 <= len
|
|
378
379
|
case "STRING": // 256 <= len
|
|
379
|
-
return
|
|
380
|
+
return Types.StringType.get({ qualifiedName: qualifiedName });
|
|
380
381
|
case "RSTR": // 256 <= len
|
|
381
382
|
case "RAWSTRING": // 256 <= len
|
|
382
383
|
case "GEOM_EWKB":
|
package/build/src/registry.js
CHANGED
|
@@ -6,7 +6,9 @@ const Expressions = require("../abap/2_statements/expressions");
|
|
|
6
6
|
const _abap_rule_1 = require("./_abap_rule");
|
|
7
7
|
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
8
8
|
const _irule_1 = require("./_irule");
|
|
9
|
+
const position_1 = require("../position");
|
|
9
10
|
const __1 = require("..");
|
|
11
|
+
const edit_helper_1 = require("../edit_helper");
|
|
10
12
|
class AlignParametersConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
11
13
|
}
|
|
12
14
|
exports.AlignParametersConf = AlignParametersConf;
|
|
@@ -33,7 +35,8 @@ https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#align-par
|
|
|
33
35
|
|
|
34
36
|
Does not take effect on non functional method calls, use https://rules.abaplint.org/functional_writing/
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
If parameters are on the same row, no issues are reported, see
|
|
39
|
+
https://rules.abaplint.org/max_one_method_parameter_per_line/ for splitting parameters to lines`,
|
|
37
40
|
tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Whitespace, _irule_1.RuleTag.Styleguide],
|
|
38
41
|
badExample: `CALL FUNCTION 'FOOBAR'
|
|
39
42
|
EXPORTING
|
|
@@ -96,16 +99,28 @@ DATA(sdf) = VALUE type(
|
|
|
96
99
|
return undefined;
|
|
97
100
|
}
|
|
98
101
|
let expectedEqualsColumn = 0;
|
|
102
|
+
let row = 0;
|
|
99
103
|
for (const p of candidate.parameters) {
|
|
100
104
|
const currentCol = p.left.getLastToken().getCol() + p.left.getLastToken().getStr().length + 1;
|
|
105
|
+
if (p.eq.getRow() === row) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
row = p.eq.getRow();
|
|
101
109
|
if (currentCol > expectedEqualsColumn) {
|
|
102
110
|
expectedEqualsColumn = currentCol;
|
|
103
111
|
}
|
|
104
112
|
}
|
|
105
113
|
for (const p of candidate.parameters) {
|
|
106
114
|
if (p.eq.getCol() !== expectedEqualsColumn) {
|
|
115
|
+
let fix;
|
|
116
|
+
if (p.eq.getCol() < expectedEqualsColumn) {
|
|
117
|
+
fix = edit_helper_1.EditHelper.insertAt(file, p.eq, " ".repeat(expectedEqualsColumn - p.eq.getCol()));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
fix = edit_helper_1.EditHelper.deleteRange(file, new position_1.Position(p.eq.getRow(), expectedEqualsColumn), p.eq);
|
|
121
|
+
}
|
|
107
122
|
const message = "Align parameters to column " + expectedEqualsColumn;
|
|
108
|
-
return issue_1.Issue.atPosition(file, p.eq, message, this.getMetadata().key, this.getConfig().severity);
|
|
123
|
+
return issue_1.Issue.atPosition(file, p.eq, message, this.getMetadata().key, this.getConfig().severity, fix);
|
|
109
124
|
}
|
|
110
125
|
}
|
|
111
126
|
return undefined;
|
|
@@ -669,6 +669,10 @@ Make sure to test the downported code, it might not always be completely correct
|
|
|
669
669
|
else if (fieldList.concatTokens().toUpperCase() === "COUNT( * )") {
|
|
670
670
|
fieldDefinition = `DATA ${name} TYPE i.`;
|
|
671
671
|
}
|
|
672
|
+
else if (fieldList.concatTokens().toUpperCase() === "@ABAP_TRUE"
|
|
673
|
+
|| fieldList.concatTokens().toUpperCase() === "@ABAP_FALSE") {
|
|
674
|
+
fieldDefinition = `DATA ${name} TYPE abap_bool.`;
|
|
675
|
+
}
|
|
672
676
|
else if (fieldList.getChildren().length === 1 && fieldList.getChildren()[0].get() instanceof Expressions.SQLAggregation) {
|
|
673
677
|
const c = fieldList.getChildren()[0];
|
|
674
678
|
if (c instanceof nodes_1.ExpressionNode) {
|
|
@@ -45,11 +45,11 @@ DATA lt_bar TYPE STANDARD TABLE OF ty.`,
|
|
|
45
45
|
const concat = tt.concatTokens().toUpperCase();
|
|
46
46
|
if (concat.includes("TYPE TABLE OF")) {
|
|
47
47
|
const message = "Specify table type";
|
|
48
|
-
issues.push(issue_1.Issue.
|
|
48
|
+
issues.push(issue_1.Issue.atPosition(file, tt.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity));
|
|
49
49
|
}
|
|
50
50
|
else if (concat.includes(" WITH ") === false && concat.includes(" RANGE OF ") === false) {
|
|
51
51
|
const message = "Specify table key";
|
|
52
|
-
issues.push(issue_1.Issue.
|
|
52
|
+
issues.push(issue_1.Issue.atPosition(file, tt.getFirstToken().getStart(), message, this.getMetadata().key, this.conf.severity));
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
return issues;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SelectSingleFullKey = exports.SelectSingleFullKeyConf = void 0;
|
|
4
4
|
const issue_1 = require("../issue");
|
|
5
5
|
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
6
|
-
const _irule_1 = require("./_irule");
|
|
7
6
|
const __1 = require("..");
|
|
8
7
|
class SelectSingleFullKeyConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
9
8
|
constructor() {
|
|
@@ -23,7 +22,7 @@ class SelectSingleFullKey {
|
|
|
23
22
|
shortDescription: `Detect SELECT SINGLE which are possibily not unique`,
|
|
24
23
|
extendedInformation: `Table definitions must be known, ie. inside the errorNamespace`,
|
|
25
24
|
pseudoComment: "EC CI_NOORDER",
|
|
26
|
-
tags: [
|
|
25
|
+
tags: [],
|
|
27
26
|
};
|
|
28
27
|
}
|
|
29
28
|
initialize(reg) {
|