@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.
Files changed (36) hide show
  1. package/build/abaplint.d.ts +20 -1
  2. package/build/adhoc/syntax_performance.d.ts +1 -0
  3. package/build/adhoc/syntax_performance.js +15 -0
  4. package/build/adhoc/typed_array.d.ts +20 -0
  5. package/build/adhoc/typed_array.js +47 -0
  6. package/build/src/abap/5_syntax/_builtin.js +173 -173
  7. package/build/src/abap/5_syntax/_type_utils.js +2 -1
  8. package/build/src/abap/5_syntax/basic_types.js +9 -3
  9. package/build/src/abap/5_syntax/expressions/constant.js +4 -3
  10. package/build/src/abap/5_syntax/expressions/inline_loop_definition.js +1 -1
  11. package/build/src/abap/5_syntax/expressions/method_call_param.js +1 -1
  12. package/build/src/abap/5_syntax/expressions/method_param.js +3 -0
  13. package/build/src/abap/5_syntax/expressions/source.js +2 -2
  14. package/build/src/abap/5_syntax/expressions/string_template.js +2 -2
  15. package/build/src/abap/5_syntax/statements/concatenate.js +26 -4
  16. package/build/src/abap/5_syntax/statements/controls.js +6 -6
  17. package/build/src/abap/5_syntax/statements/describe.js +3 -3
  18. package/build/src/abap/5_syntax/statements/find.js +10 -10
  19. package/build/src/abap/5_syntax/statements/get_bit.js +1 -1
  20. package/build/src/abap/5_syntax/statements/get_run_time.js +1 -1
  21. package/build/src/abap/5_syntax/statements/message.js +1 -1
  22. package/build/src/abap/5_syntax/statements/read_table.js +2 -2
  23. package/build/src/abap/5_syntax/statements/split.js +1 -1
  24. package/build/src/abap/5_syntax/structures/type_enum.js +2 -2
  25. package/build/src/abap/types/basic/hex_type.js +1 -1
  26. package/build/src/abap/types/basic/index.js +1 -0
  27. package/build/src/abap/types/basic/integer_type.js +19 -0
  28. package/build/src/abap/types/basic/string_type.js +19 -0
  29. package/build/src/abap/types/basic/xgeneric_type.js +23 -0
  30. package/build/src/ddic.js +5 -4
  31. package/build/src/registry.js +1 -1
  32. package/build/src/rules/align_parameters.js +17 -2
  33. package/build/src/rules/downport.js +4 -0
  34. package/build/src/rules/fully_type_itabs.js +2 -2
  35. package/build/src/rules/select_single_full_key.js +1 -2
  36. 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
- const f = struType.getComponentByName(fieldName);
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
- const f = stru.getComponentByName(fieldName);
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 new basic_1.IntegerType({ qualifiedName: "I" });
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 new basic_1.StringType({ qualifiedName: "STRING", derivedFromConstant: true });
20
+ return basic_1.StringType.get({ derivedFromConstant: true });
20
21
  }
21
22
  else {
22
- return new basic_1.StringType({ qualifiedName: "STRING" });
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, new basic_1.IntegerType(), ["inline" /* IdentifierMeta.InlineDefinition */]);
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 = new basic_1.StringType();
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 new basic_1.StringType();
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 new basic_1.StringType();
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, new basic_1.StringType({ qualifiedName: "STRING" }));
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 new basic_1.StringType({ qualifiedName: "STRING" });
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
- // todo, does this give XSTRING in BYTE MODE?
15
- new inline_data_1.InlineData().runSyntax(inline, scope, filename, new basic_1.StringType());
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: new basic_1.IntegerType() },
19
+ { name: "INDEX", type: basic_1.IntegerType.get() },
20
20
  { name: "SELECTED", type: new basic_1.CharacterType(1) },
21
- { name: "VISLENGTH", type: new basic_1.IntegerType() },
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: new basic_1.IntegerType() },
27
- { name: "TOP_LINE", type: new basic_1.IntegerType() },
28
- { name: "CURRENT_LINE", type: new basic_1.IntegerType() },
29
- { name: "LEFT_COL", type: new basic_1.IntegerType() },
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, new basic_1.IntegerType());
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, new basic_1.IntegerType());
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, new basic_1.IntegerType());
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: new basic_1.IntegerType() },
18
- { name: "LENGTH", type: new basic_1.IntegerType() }
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: new basic_1.IntegerType() },
22
- { name: "OFFSET", type: new basic_1.IntegerType() },
23
- { name: "LENGTH", type: new basic_1.IntegerType() },
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, new basic_1.IntegerType());
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, new basic_1.IntegerType());
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, new basic_1.IntegerType());
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, new basic_1.IntegerType());
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, new basic_1.StringType());
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, new basic_1.IntegerType());
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, new basic_1.IntegerType());
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, new basic_1.StringType());
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, new basic_1.IntegerType()) === false) {
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, new basic_1.IntegerType()) === false) {
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(new basic_1.StringType(), { withHeader: false, keyType: basic_1.TableKeyType.default }) : new basic_1.StringType();
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, new basic_1.IntegerType()));
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, new basic_1.IntegerType()));
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 LENGTHm, Hex");
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 new Types.StringType({ qualifiedName: qualifiedName || name });
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 new Types.IntegerType({ qualifiedName: qualifiedName || name });
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.IntegerType({ qualifiedName: qualifiedName });
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 new Types.StringType({ qualifiedName: qualifiedName || "STRING" });
380
+ return Types.StringType.get({ qualifiedName: qualifiedName });
380
381
  case "RSTR": // 256 <= len
381
382
  case "RAWSTRING": // 256 <= len
382
383
  case "GEOM_EWKB":
@@ -65,7 +65,7 @@ class Registry {
65
65
  }
66
66
  static abaplintVersion() {
67
67
  // magic, see build script "version.sh"
68
- return "2.101.14";
68
+ return "2.101.16";
69
69
  }
70
70
  getDDICReferences() {
71
71
  return this.ddicReferences;
@@ -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
- Also https://rules.abaplint.org/max_one_method_parameter_per_line/ can help aligning parameter syntax`,
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.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
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.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity));
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: [_irule_1.RuleTag.Experimental],
25
+ tags: [],
27
26
  };
28
27
  }
29
28
  initialize(reg) {