@abaplint/core 2.95.23 → 2.95.25

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.
@@ -6365,6 +6365,7 @@ export declare enum Version {
6365
6365
  v754 = "v754",
6366
6366
  v755 = "v755",
6367
6367
  v756 = "v756",
6368
+ v757 = "v757",
6368
6369
  Cloud = "Cloud"
6369
6370
  }
6370
6371
 
@@ -10,7 +10,8 @@ class InlineData extends combi_1.Expression {
10
10
  const right = (0, combi_1.altPrio)((0, combi_1.tok)(tokens_1.ParenRightW), (0, combi_1.tok)(tokens_1.ParenRight));
11
11
  const left = (0, combi_1.tok)(tokens_1.ParenLeft);
12
12
  const data = (0, combi_1.seq)("DATA", left, _1.TargetField, right);
13
- return (0, combi_1.ver)(version_1.Version.v740sp02, data);
13
+ const final = (0, combi_1.seq)("FINAL", left, _1.TargetField, right);
14
+ return (0, combi_1.altPrio)((0, combi_1.ver)(version_1.Version.v740sp02, data), (0, combi_1.ver)(version_1.Version.v757, final));
14
15
  }
15
16
  }
16
17
  exports.InlineData = InlineData;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Assign = void 0;
4
4
  const combi_1 = require("../combi");
5
5
  const expressions_1 = require("../expressions");
6
+ const version_1 = require("../../../version");
6
7
  class Assign {
7
8
  getMatcher() {
8
9
  const type = (0, combi_1.seq)("TYPE", (0, combi_1.altPrio)(expressions_1.Dynamic, expressions_1.TypeName));
@@ -12,7 +13,7 @@ class Assign {
12
13
  const decimals = (0, combi_1.seq)("DECIMALS", expressions_1.Source);
13
14
  const casting = (0, combi_1.seq)("CASTING", (0, combi_1.opt)((0, combi_1.alt)(like, handle, (0, combi_1.per)(type, decimals))));
14
15
  const obsoleteType = (0, combi_1.seq)("TYPE", expressions_1.Source, (0, combi_1.optPrio)(decimals));
15
- const ret = (0, combi_1.seq)("ASSIGN", (0, combi_1.opt)((0, combi_1.seq)(expressions_1.Target, "INCREMENT")), expressions_1.AssignSource, "TO", expressions_1.FSTarget, (0, combi_1.opt)((0, combi_1.altPrio)(casting, obsoleteType)), (0, combi_1.opt)(range));
16
+ const ret = (0, combi_1.seq)("ASSIGN", (0, combi_1.opt)((0, combi_1.seq)(expressions_1.Target, "INCREMENT")), expressions_1.AssignSource, "TO", expressions_1.FSTarget, (0, combi_1.opt)((0, combi_1.altPrio)(casting, obsoleteType)), (0, combi_1.opt)(range), (0, combi_1.opt)((0, combi_1.ver)(version_1.Version.v757, "ELSE UNASSIGN")));
16
17
  return ret;
17
18
  }
18
19
  }
@@ -4,7 +4,6 @@ exports.Import = void 0;
4
4
  const combi_1 = require("../combi");
5
5
  const tokens_1 = require("../../1_lexer/tokens");
6
6
  const expressions_1 = require("../expressions");
7
- const version_1 = require("../../../version");
8
7
  class Import {
9
8
  getMatcher() {
10
9
  const dto = (0, combi_1.seq)("TO", expressions_1.Target);
@@ -23,7 +22,7 @@ class Import {
23
22
  const target = (0, combi_1.alt)(toeq, to, expressions_1.Dynamic, (0, combi_1.plus)(expressions_1.Target));
24
23
  const options = (0, combi_1.per)("ACCEPTING PADDING", "IGNORING CONVERSION ERRORS", "IN CHAR-TO-HEX MODE", "IGNORING STRUCTURE BOUNDARIES", "ACCEPTING TRUNCATION", (0, combi_1.seq)("REPLACEMENT CHARACTER", expressions_1.Source), (0, combi_1.seq)("CODE PAGE INTO", expressions_1.Source), (0, combi_1.seq)("ENDIAN INTO", expressions_1.Source));
25
24
  const ret = (0, combi_1.seq)("IMPORT", target, "FROM", source, (0, combi_1.opt)(options));
26
- return (0, combi_1.verNot)(version_1.Version.Cloud, ret);
25
+ return ret;
27
26
  }
28
27
  }
29
28
  exports.Import = Import;
@@ -2,9 +2,31 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ComponentCompare = void 0;
4
4
  const Expressions = require("../../2_statements/expressions");
5
+ const basic_1 = require("../../types/basic");
5
6
  const source_1 = require("./source");
6
7
  class ComponentCompare {
7
- runSyntax(node, scope, filename) {
8
+ runSyntax(node, scope, filename, type) {
9
+ const chain = node.findDirectExpression(Expressions.ComponentChainSimple);
10
+ if (chain === undefined) {
11
+ throw new Error("ComponentCompare, chain not found");
12
+ }
13
+ // todo, handle deep chain
14
+ if (chain.getChildren().length === 1
15
+ && type !== undefined
16
+ && !(type instanceof basic_1.VoidType)
17
+ && !(type instanceof basic_1.UnknownType)
18
+ && !(type instanceof basic_1.AnyType)) {
19
+ const fieldName = chain.concatTokens();
20
+ if (fieldName.toLowerCase() !== "table_line") {
21
+ if (!(type instanceof basic_1.StructureType)) {
22
+ throw new Error("ComponentCompare, source not structured");
23
+ }
24
+ if (type.getComponentByName(fieldName) === undefined) {
25
+ throw new Error("Component \"" + fieldName + "\" not part of structure");
26
+ }
27
+ // todo, check type compatibility
28
+ }
29
+ }
8
30
  for (const s of node.findDirectExpressions(Expressions.Source)) {
9
31
  new source_1.Source().runSyntax(s, scope, filename);
10
32
  }
@@ -4,15 +4,15 @@ exports.ComponentCond = void 0;
4
4
  const Expressions = require("../../2_statements/expressions");
5
5
  const component_compare_1 = require("./component_compare");
6
6
  class ComponentCond {
7
- runSyntax(node, scope, filename) {
7
+ runSyntax(node, scope, filename, type) {
8
8
  for (const t of node.findDirectExpressions(Expressions.ComponentCondSub)) {
9
9
  const c = t.findDirectExpression(Expressions.ComponentCond);
10
10
  if (c) {
11
- new ComponentCond().runSyntax(c, scope, filename);
11
+ new ComponentCond().runSyntax(c, scope, filename, type);
12
12
  }
13
13
  }
14
14
  for (const t of node.findDirectExpressions(Expressions.ComponentCompare)) {
15
- new component_compare_1.ComponentCompare().runSyntax(t, scope, filename);
15
+ new component_compare_1.ComponentCompare().runSyntax(t, scope, filename, type);
16
16
  }
17
17
  }
18
18
  }
@@ -8,7 +8,6 @@ const source_1 = require("../expressions/source");
8
8
  const inline_data_1 = require("../expressions/inline_data");
9
9
  const inline_fs_1 = require("../expressions/inline_fs");
10
10
  const fstarget_1 = require("../expressions/fstarget");
11
- const component_compare_1 = require("../expressions/component_compare");
12
11
  const component_cond_1 = require("../expressions/component_cond");
13
12
  const dynamic_1 = require("../expressions/dynamic");
14
13
  const loop_group_by_1 = require("../expressions/loop_group_by");
@@ -27,6 +26,7 @@ class Loop {
27
26
  firstSource = sources[0];
28
27
  }
29
28
  let sourceType = firstSource ? new source_1.Source().runSyntax(firstSource, scope, filename, targetType) : undefined;
29
+ let rowType = undefined;
30
30
  const concat = node.concatTokens().toUpperCase();
31
31
  if (sourceType === undefined) {
32
32
  throw new Error("No source type determined");
@@ -48,7 +48,8 @@ class Loop {
48
48
  }
49
49
  if (sourceType instanceof basic_1.TableType) {
50
50
  const targetConcat = (_a = node.findDirectExpression(Expressions.LoopTarget)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
51
- sourceType = sourceType.getRowType();
51
+ rowType = sourceType.getRowType();
52
+ sourceType = rowType;
52
53
  if (targetConcat === null || targetConcat === void 0 ? void 0 : targetConcat.startsWith("REFERENCE INTO ")) {
53
54
  sourceType = new basic_1.DataReference(sourceType);
54
55
  }
@@ -73,11 +74,8 @@ class Loop {
73
74
  new fstarget_1.FSTarget().runSyntax(fstarget, scope, filename, sourceType);
74
75
  }
75
76
  }
76
- for (const t of node.findDirectExpressions(Expressions.ComponentCompare)) {
77
- new component_compare_1.ComponentCompare().runSyntax(t, scope, filename);
78
- }
79
77
  for (const t of node.findDirectExpressions(Expressions.ComponentCond)) {
80
- new component_cond_1.ComponentCond().runSyntax(t, scope, filename);
78
+ new component_cond_1.ComponentCond().runSyntax(t, scope, filename, rowType);
81
79
  }
82
80
  for (const t of node.findDirectExpressions(Expressions.Dynamic)) {
83
81
  new dynamic_1.Dynamic().runSyntax(t, scope, filename);
@@ -63,7 +63,7 @@ class Registry {
63
63
  }
64
64
  static abaplintVersion() {
65
65
  // magic, see build script "version.sh"
66
- return "2.95.23";
66
+ return "2.95.25";
67
67
  }
68
68
  getDDICReferences() {
69
69
  return this.references;
@@ -54,6 +54,7 @@ class UncaughtException extends _abap_rule_1.ABAPRule {
54
54
  if (stru === undefined) {
55
55
  return [];
56
56
  }
57
+ this.findLocalExceptions(obj);
57
58
  this.syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
58
59
  if (this.syntax.issues.length > 0) {
59
60
  return [];
@@ -176,7 +177,6 @@ class UncaughtException extends _abap_rule_1.ABAPRule {
176
177
  def.getRaising().forEach(r => { var _a; return (_a = this.sinked) === null || _a === void 0 ? void 0 : _a.push(r); });
177
178
  }
178
179
  isSinked(name) {
179
- // todo: ignore dynamic and no_check exceptions
180
180
  if (this.sinked === undefined || name === undefined) {
181
181
  return true;
182
182
  }
@@ -184,9 +184,13 @@ class UncaughtException extends _abap_rule_1.ABAPRule {
184
184
  if (sup === "CX_DYNAMIC_CHECK" || sup === "CX_NO_CHECK") {
185
185
  return true;
186
186
  }
187
- // todo, check local class hierarchy
187
+ const lsup = this.localExceptions[name.toUpperCase()];
188
+ if (lsup === "CX_DYNAMIC_CHECK" || lsup === "CX_NO_CHECK") {
189
+ return true;
190
+ }
188
191
  return this.sinked.some(a => a.toUpperCase() === name.toUpperCase())
189
- || (sup !== undefined && this.isSinked(sup) === true);
192
+ || (sup !== undefined && this.isSinked(sup) === true)
193
+ || (lsup !== undefined && this.isSinked(lsup) === true);
190
194
  }
191
195
  findGlobalExceptions() {
192
196
  var _a, _b;
@@ -203,6 +207,17 @@ class UncaughtException extends _abap_rule_1.ABAPRule {
203
207
  this.globalExceptions[o.getName().toUpperCase()] = (_b = def.superClassName) === null || _b === void 0 ? void 0 : _b.toUpperCase();
204
208
  }
205
209
  }
210
+ findLocalExceptions(obj) {
211
+ var _a;
212
+ this.localExceptions = {};
213
+ for (const file of obj.getABAPFiles()) {
214
+ for (const def of file.getInfo().listClassDefinitions()) {
215
+ if (def.isLocal === true && def.superClassName !== undefined) {
216
+ this.localExceptions[def.name.toUpperCase()] = (_a = def.superClassName) === null || _a === void 0 ? void 0 : _a.toUpperCase();
217
+ }
218
+ }
219
+ }
220
+ }
206
221
  }
207
222
  exports.UncaughtException = UncaughtException;
208
223
  //# sourceMappingURL=uncaught_exception.js.map
@@ -10,6 +10,7 @@ const objects_1 = require("../objects");
10
10
  const _reference_1 = require("../abap/5_syntax/_reference");
11
11
  const visibility_1 = require("../abap/4_file_information/visibility");
12
12
  const edit_helper_1 = require("../edit_helper");
13
+ const _statement_1 = require("../abap/2_statements/statements/_statement");
13
14
  class UnusedMethodsConf extends _basic_rule_config_1.BasicRuleConfig {
14
15
  }
15
16
  exports.UnusedMethodsConf = UnusedMethodsConf;
@@ -57,6 +58,8 @@ class UnusedMethods {
57
58
  shortDescription: `Checks for unused methods`,
58
59
  extendedInformation: `Checks private and protected methods.
59
60
 
61
+ Unused methods are not reported if the object contains parser or syntax errors.
62
+
60
63
  Skips:
61
64
  * methods FOR TESTING
62
65
  * methods SETUP + TEARDOWN + CLASS_SETUP + CLASS_TEARDOWN in testclasses
@@ -89,6 +92,13 @@ Skips:
89
92
  else if (obj instanceof objects_1.Program && obj.isInclude() === true) {
90
93
  return [];
91
94
  }
95
+ for (const file of obj.getABAPFiles()) {
96
+ for (const statement of file.getStatements()) {
97
+ if (statement.get() instanceof _statement_1.Unknown) {
98
+ return []; // contains parser errors
99
+ }
100
+ }
101
+ }
92
102
  // dont report anything when there are syntax errors
93
103
  const syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
94
104
  if (syntax.issues.length > 0) {
@@ -9,6 +9,7 @@ const _abap_object_1 = require("../objects/_abap_object");
9
9
  const _scope_type_1 = require("../abap/5_syntax/_scope_type");
10
10
  const edit_helper_1 = require("../edit_helper");
11
11
  const _reference_1 = require("../abap/5_syntax/_reference");
12
+ const _statement_1 = require("../abap/2_statements/statements/_statement");
12
13
  class WorkArea {
13
14
  constructor() {
14
15
  this.workarea = [];
@@ -55,6 +56,7 @@ class UnusedTypes {
55
56
  key: "unused_types",
56
57
  title: "Unused types",
57
58
  shortDescription: `Checks for unused TYPE definitions`,
59
+ extendedInformation: `Unused types are not reported if the object contains parser or syntax errors.`,
58
60
  tags: [_irule_1.RuleTag.Quickfix],
59
61
  pragma: "##NEEDED",
60
62
  };
@@ -76,6 +78,13 @@ class UnusedTypes {
76
78
  if (!(obj instanceof _abap_object_1.ABAPObject)) {
77
79
  return [];
78
80
  }
81
+ for (const file of obj.getABAPFiles()) {
82
+ for (const statement of file.getStatements()) {
83
+ if (statement.get() instanceof _statement_1.Unknown) {
84
+ return []; // contains parser errors
85
+ }
86
+ }
87
+ }
79
88
  // dont report unused variables when there are syntax errors
80
89
  const syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
81
90
  if (syntax.issues.length > 0) {
@@ -68,7 +68,9 @@ class UnusedVariables {
68
68
 
69
69
  Note that this currently does not work if the source code uses macros.
70
70
 
71
- Unused variables are not reported if the object contains syntax errors. Errors found in INCLUDES are reported for the main program.`,
71
+ Unused variables are not reported if the object contains parser or syntax errors.
72
+
73
+ Errors found in INCLUDES are reported for the main program.`,
72
74
  tags: [_irule_1.RuleTag.Quickfix],
73
75
  pragma: "##NEEDED",
74
76
  pseudoComment: "EC NEEDED",
@@ -94,10 +96,17 @@ Unused variables are not reported if the object contains syntax errors. Errors f
94
96
  else if (obj instanceof objects_1.Interface) { // todo, how to handle interfaces?
95
97
  return [];
96
98
  }
99
+ for (const file of obj.getABAPFiles()) {
100
+ for (const statement of file.getStatements()) {
101
+ if (statement.get() instanceof _statement_1.Unknown) {
102
+ return []; // contains parser errors
103
+ }
104
+ }
105
+ }
97
106
  // dont report unused variables when there are syntax errors
98
107
  const syntax = new syntax_1.SyntaxLogic(this.reg, obj).run();
99
108
  if (syntax.issues.length > 0) {
100
- return [];
109
+ return []; // contains syntax errors
101
110
  }
102
111
  this.workarea = new WorkArea();
103
112
  const top = syntax.spaghetti.getTop();
@@ -16,9 +16,10 @@ var Version;
16
16
  Version["v754"] = "v754";
17
17
  Version["v755"] = "v755";
18
18
  Version["v756"] = "v756";
19
+ Version["v757"] = "v757";
19
20
  Version["Cloud"] = "Cloud";
20
21
  })(Version = exports.Version || (exports.Version = {}));
21
- exports.defaultVersion = Version.v756;
22
+ exports.defaultVersion = Version.v757;
22
23
  function getPreviousVersion(v) {
23
24
  if (v === Version.OpenABAP) {
24
25
  return Version.v702;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.95.23",
3
+ "version": "2.95.25",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -50,7 +50,7 @@
50
50
  "@microsoft/api-extractor": "^7.34.4",
51
51
  "@types/chai": "^4.3.4",
52
52
  "@types/mocha": "^10.0.1",
53
- "@types/node": "^18.14.0",
53
+ "@types/node": "^18.14.1",
54
54
  "chai": "^4.3.7",
55
55
  "eslint": "^8.34.0",
56
56
  "mocha": "^10.2.0",