@abaplint/core 2.94.5 → 2.94.7

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.
@@ -3502,6 +3502,7 @@ export declare interface ISpaghettiScopeNode {
3502
3502
  findScopeForVariable(name: string): IScopeIdentifier | undefined;
3503
3503
  findWriteReference(pos: Position): TypedIdentifier | undefined;
3504
3504
  findTableReference(pos: Position): string | undefined;
3505
+ findTableVoidReference(pos: Position): boolean;
3505
3506
  }
3506
3507
 
3507
3508
  export declare class Issue {
@@ -3563,11 +3564,11 @@ declare interface ISyntaxSettings {
3563
3564
  version?: Version;
3564
3565
  /** Report error for objects in this regex namespace. Types not in namespace will be void. Case insensitive */
3565
3566
  errorNamespace: string;
3566
- /** List of full named global constants
3567
+ /** List of full named global constants (regex not possible)
3567
3568
  * @uniqueItems true
3568
3569
  */
3569
3570
  globalConstants?: string[];
3570
- /** List of full named global macros
3571
+ /** List of full named global macros (regex not possible)
3571
3572
  * @uniqueItems true
3572
3573
  */
3573
3574
  globalMacros?: string[];
@@ -5101,6 +5102,7 @@ export declare class SpaghettiScopeNode extends ScopeData implements ISpaghettiS
5101
5102
  findVariable(name: string): TypedIdentifier | undefined;
5102
5103
  findWriteReference(pos: Position): TypedIdentifier | undefined;
5103
5104
  findTableReference(pos: Position): string | undefined;
5105
+ findTableVoidReference(pos: Position): boolean;
5104
5106
  findScopeForVariable(name: string): IScopeIdentifier | undefined;
5105
5107
  }
5106
5108
 
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BuiltIn = void 0;
3
+ exports.BuiltIn = exports.BuiltInMethod = void 0;
4
4
  /* eslint-disable max-len */
5
5
  const _typed_identifier_1 = require("../types/_typed_identifier");
6
6
  const basic_1 = require("../types/basic");
@@ -84,6 +84,7 @@ class BuiltInMethod extends _identifier_1.Identifier {
84
84
  return undefined;
85
85
  }
86
86
  }
87
+ exports.BuiltInMethod = BuiltInMethod;
87
88
  class BuiltIn {
88
89
  constructor() {
89
90
  this.row = 1;
@@ -171,6 +171,15 @@ class SpaghettiScopeNode extends ScopeData {
171
171
  }
172
172
  return undefined;
173
173
  }
174
+ findTableVoidReference(pos) {
175
+ for (const r of this.getData().references) {
176
+ if (r.referenceType === _reference_1.ReferenceType.TableVoidReference
177
+ && r.position.getStart().equals(pos)) {
178
+ return true;
179
+ }
180
+ }
181
+ return false;
182
+ }
174
183
  // TODO, this method can be deleted? its only used in tests?
175
184
  findScopeForVariable(name) {
176
185
  let search = this;
@@ -5,6 +5,7 @@ const Expressions = require("../../2_statements/expressions");
5
5
  const dynamic_1 = require("../expressions/dynamic");
6
6
  const database_table_1 = require("../expressions/database_table");
7
7
  const source_1 = require("../expressions/source");
8
+ const _reference_1 = require("../_reference");
8
9
  class ModifyDatabase {
9
10
  runSyntax(node, scope, filename) {
10
11
  for (const d of node.findAllExpressions(Expressions.Dynamic)) {
@@ -12,14 +13,18 @@ class ModifyDatabase {
12
13
  }
13
14
  const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
14
15
  if (dbtab !== undefined) {
15
- try {
16
- new database_table_1.DatabaseTable().runSyntax(dbtab, scope, filename);
17
- }
18
- catch (e) {
19
- if (scope.findVariable(dbtab.concatTokens()) === undefined) {
20
- throw e;
16
+ if (node.getChildren().length === 5) {
17
+ const found = scope.findVariable(dbtab.concatTokens());
18
+ if (found) {
19
+ scope.addReference(dbtab.getFirstToken(), found, _reference_1.ReferenceType.DataWriteReference, filename);
20
+ }
21
+ else {
22
+ new database_table_1.DatabaseTable().runSyntax(dbtab, scope, filename);
21
23
  }
22
24
  }
25
+ else {
26
+ new database_table_1.DatabaseTable().runSyntax(dbtab, scope, filename);
27
+ }
23
28
  }
24
29
  for (const s of node.findAllExpressions(Expressions.Source)) {
25
30
  new source_1.Source().runSyntax(s, scope, filename);
@@ -121,7 +121,7 @@ class Table extends _abstract_object_1.AbstractObject {
121
121
  }
122
122
  }
123
123
  else if (comptype === "S" && field.FIELDNAME.startsWith(".INCLU-")) {
124
- const lookup = ddic.lookupTableOrView(field.ROLLNAME);
124
+ const lookup = ddic.lookupTableOrView(field.PRECFIELD);
125
125
  if (lookup.object) {
126
126
  references.push({ object: lookup.object });
127
127
  }
@@ -63,7 +63,7 @@ class Registry {
63
63
  }
64
64
  static abaplintVersion() {
65
65
  // magic, see build script "version.sh"
66
- return "2.94.5";
66
+ return "2.94.7";
67
67
  }
68
68
  getDDICReferences() {
69
69
  return this.references;
@@ -29,7 +29,9 @@ class ChangeIfToCase extends _abap_rule_1.ABAPRule {
29
29
  title: "Change IF to CASE",
30
30
  shortDescription: `Finds IF constructs that can be changed to CASE`,
31
31
  // eslint-disable-next-line max-len
32
- extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-case-to-else-if-for-multiple-alternative-conditions`,
32
+ extendedInformation: `https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#prefer-case-to-else-if-for-multiple-alternative-conditions
33
+
34
+ If the first comparison is a boolean compare, no issue is reported.`,
33
35
  tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Styleguide],
34
36
  badExample: `IF l_fcat-fieldname EQ 'FOO'.
35
37
  ELSEIF l_fcat-fieldname = 'BAR'
@@ -60,6 +62,9 @@ ENDCASE.`,
60
62
  if (ifStatement === undefined) {
61
63
  continue;
62
64
  }
65
+ if (ifStatement.concatTokens().match(/ (abap_true|abap_false)\s*\./i)) {
66
+ continue;
67
+ }
63
68
  conds.push(ifStatement === null || ifStatement === void 0 ? void 0 : ifStatement.findDirectExpression(Expressions.Cond));
64
69
  for (const ei of i.findDirectStructures(Structures.ElseIf)) {
65
70
  conds.push((_a = ei.findDirectStatement(Statements.ElseIf)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.Cond));
@@ -4,9 +4,10 @@ exports.ModifyOnlyOwnDBTables = exports.ModifyOnlyOwnDBTablesConf = void 0;
4
4
  const Statements = require("../abap/2_statements/statements");
5
5
  const Expressions = require("../abap/2_statements/expressions");
6
6
  const issue_1 = require("../issue");
7
- const _abap_rule_1 = require("./_abap_rule");
8
7
  const _basic_rule_config_1 = require("./_basic_rule_config");
9
8
  const _irule_1 = require("./_irule");
9
+ const _abap_object_1 = require("../objects/_abap_object");
10
+ const syntax_1 = require("../abap/5_syntax/syntax");
10
11
  class ModifyOnlyOwnDBTablesConf extends _basic_rule_config_1.BasicRuleConfig {
11
12
  constructor() {
12
13
  super(...arguments);
@@ -16,9 +17,8 @@ class ModifyOnlyOwnDBTablesConf extends _basic_rule_config_1.BasicRuleConfig {
16
17
  }
17
18
  }
18
19
  exports.ModifyOnlyOwnDBTablesConf = ModifyOnlyOwnDBTablesConf;
19
- class ModifyOnlyOwnDBTables extends _abap_rule_1.ABAPRule {
20
+ class ModifyOnlyOwnDBTables {
20
21
  constructor() {
21
- super(...arguments);
22
22
  this.conf = new ModifyOnlyOwnDBTablesConf();
23
23
  }
24
24
  getMetadata() {
@@ -26,8 +26,8 @@ class ModifyOnlyOwnDBTables extends _abap_rule_1.ABAPRule {
26
26
  key: "modify_only_own_db_tables",
27
27
  title: "Modify only own DB tables",
28
28
  shortDescription: `Modify only own DB tables`,
29
- extendedInformation: "https://docs.abapopenchecks.org/checks/26/",
30
- tags: [_irule_1.RuleTag.Security, _irule_1.RuleTag.SingleFile],
29
+ extendedInformation: `https://docs.abapopenchecks.org/checks/26/`,
30
+ tags: [_irule_1.RuleTag.Security],
31
31
  };
32
32
  }
33
33
  getConfig() {
@@ -36,33 +36,52 @@ class ModifyOnlyOwnDBTables extends _abap_rule_1.ABAPRule {
36
36
  setConfig(conf) {
37
37
  this.conf = conf;
38
38
  }
39
- runParsed(file) {
39
+ initialize(reg) {
40
+ this.reg = reg;
41
+ return this;
42
+ }
43
+ run(obj) {
40
44
  var _a;
41
- const output = [];
42
- const struc = file.getStructure();
43
- if (struc === undefined) {
45
+ if (!(obj instanceof _abap_object_1.ABAPObject)) {
44
46
  return [];
45
47
  }
46
- const regExp = new RegExp(this.getConfig().ownTables, "i");
47
- for (const s of file.getStatements()) {
48
- const g = s.get();
49
- if (g instanceof Statements.DeleteDatabase
50
- || g instanceof Statements.UpdateDatabase
51
- || g instanceof Statements.InsertDatabase
52
- || g instanceof Statements.ModifyDatabase) {
53
- const databaseTable = s.findFirstExpression(Expressions.DatabaseTable);
54
- if (databaseTable === undefined) {
55
- continue;
56
- }
57
- if (((_a = databaseTable.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Dynamic) {
58
- if (this.getConfig().reportDynamic === true) {
59
- output.push(issue_1.Issue.atStatement(file, s, this.getMetadata().title, this.getMetadata().key, this.getConfig().severity));
48
+ let spaghetti = undefined;
49
+ const output = [];
50
+ for (const file of obj.getABAPFiles()) {
51
+ const struc = file.getStructure();
52
+ if (struc === undefined) {
53
+ return [];
54
+ }
55
+ const regExp = new RegExp(this.getConfig().ownTables, "i");
56
+ for (const s of file.getStatements()) {
57
+ const g = s.get();
58
+ if (g instanceof Statements.DeleteDatabase
59
+ || g instanceof Statements.UpdateDatabase
60
+ || g instanceof Statements.InsertDatabase
61
+ || g instanceof Statements.ModifyDatabase) {
62
+ const databaseTable = s.findFirstExpression(Expressions.DatabaseTable);
63
+ if (databaseTable === undefined) {
64
+ continue;
65
+ }
66
+ if (((_a = databaseTable.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Dynamic) {
67
+ if (this.getConfig().reportDynamic === true) {
68
+ output.push(issue_1.Issue.atStatement(file, s, this.getMetadata().title, this.getMetadata().key, this.getConfig().severity));
69
+ }
70
+ continue;
71
+ }
72
+ const concat = databaseTable.concatTokens().toUpperCase();
73
+ if (regExp.test(concat) === false) {
74
+ // must contain a ReferenceType.TableVoidReference
75
+ if (spaghetti === undefined) {
76
+ spaghetti = new syntax_1.SyntaxLogic(this.reg, obj).run().spaghetti;
77
+ }
78
+ const start = databaseTable.getFirstToken().getStart();
79
+ const scope = spaghetti.lookupPosition(start, file.getFilename());
80
+ const found = scope === null || scope === void 0 ? void 0 : scope.findTableVoidReference(start);
81
+ if (found) {
82
+ output.push(issue_1.Issue.atStatement(file, s, this.getMetadata().title, this.getMetadata().key, this.getConfig().severity));
83
+ }
60
84
  }
61
- continue;
62
- }
63
- const concat = databaseTable.concatTokens().toUpperCase();
64
- if (regExp.test(concat) === false && concat !== "SCREEN") {
65
- output.push(issue_1.Issue.atStatement(file, s, this.getMetadata().title, this.getMetadata().key, this.getConfig().severity));
66
85
  }
67
86
  }
68
87
  }
@@ -10,6 +10,7 @@ const syntax_1 = require("../abap/5_syntax/syntax");
10
10
  const _reference_1 = require("../abap/5_syntax/_reference");
11
11
  const method_definition_1 = require("../abap/types/method_definition");
12
12
  const edit_helper_1 = require("../edit_helper");
13
+ const _builtin_1 = require("../abap/5_syntax/_builtin");
13
14
  class OmitParameterNameConf extends _basic_rule_config_1.BasicRuleConfig {
14
15
  }
15
16
  exports.OmitParameterNameConf = OmitParameterNameConf;
@@ -74,7 +75,7 @@ EXPORTING must already be omitted for this rule to take effect, https://rules.ab
74
75
  if (ref === undefined) {
75
76
  continue;
76
77
  }
77
- const i = ref.getParameters().getDefaultImporting();
78
+ const i = ref.getDefaultImporting();
78
79
  if (i === undefined) {
79
80
  continue;
80
81
  }
@@ -101,12 +102,17 @@ EXPORTING must already be omitted for this rule to take effect, https://rules.ab
101
102
  return undefined;
102
103
  }
103
104
  for (const r of scope.getData().references) {
104
- if (r.referenceType !== _reference_1.ReferenceType.MethodReference) {
105
+ if (r.referenceType !== _reference_1.ReferenceType.MethodReference
106
+ && r.referenceType !== _reference_1.ReferenceType.BuiltinMethodReference) {
105
107
  continue;
106
108
  }
107
- else if (r.position.getStart().equals(token.getStart())
108
- && r.resolved instanceof method_definition_1.MethodDefinition) {
109
- return r.resolved;
109
+ else if (r.position.getStart().equals(token.getStart())) {
110
+ if (r.resolved instanceof _builtin_1.BuiltInMethod) {
111
+ return r.resolved;
112
+ }
113
+ else if (r.resolved instanceof method_definition_1.MethodDefinition) {
114
+ return r.resolved.getParameters();
115
+ }
110
116
  }
111
117
  }
112
118
  return undefined;
@@ -10,6 +10,11 @@ const syntax_1 = require("../abap/5_syntax/syntax");
10
10
  const _reference_1 = require("../abap/5_syntax/_reference");
11
11
  const types_1 = require("../abap/types");
12
12
  class StaticCallViaInstanceConf extends _basic_rule_config_1.BasicRuleConfig {
13
+ constructor() {
14
+ super(...arguments);
15
+ /** Allow in test class includes */
16
+ this.allowInTestclassIncludes = false;
17
+ }
13
18
  }
14
19
  exports.StaticCallViaInstanceConf = StaticCallViaInstanceConf;
15
20
  class StaticCallViaInstance extends _abap_rule_1.ABAPRule {
@@ -34,6 +39,9 @@ class StaticCallViaInstance extends _abap_rule_1.ABAPRule {
34
39
  }
35
40
  runParsed(file, obj) {
36
41
  const issues = [];
42
+ if (this.getConfig().allowInTestclassIncludes === true && file.getFilename().includes(".testclasses.")) {
43
+ return [];
44
+ }
37
45
  const staticMethodCalls = this.listMethodCalls(file.getFilename(), new syntax_1.SyntaxLogic(this.reg, obj).run().spaghetti.getTop());
38
46
  const tokens = file.getTokens();
39
47
  for (let i = 0; i < tokens.length - 1; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.94.5",
3
+ "version": "2.94.7",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",
@@ -49,9 +49,9 @@
49
49
  "@microsoft/api-extractor": "^7.33.7",
50
50
  "@types/chai": "^4.3.4",
51
51
  "@types/mocha": "^10.0.1",
52
- "@types/node": "^18.11.15",
52
+ "@types/node": "^18.11.17",
53
53
  "chai": "^4.3.7",
54
- "eslint": "^8.29.0",
54
+ "eslint": "^8.30.0",
55
55
  "mocha": "^10.2.0",
56
56
  "c8": "^7.12.0",
57
57
  "source-map-support": "^0.5.21",
@@ -60,7 +60,7 @@
60
60
  },
61
61
  "dependencies": {
62
62
  "fast-xml-parser": "^4.0.12",
63
- "json5": "^2.2.1",
63
+ "json5": "^2.2.2",
64
64
  "vscode-languageserver-types": "^3.17.2"
65
65
  }
66
66
  }