@abaplint/core 2.90.12 → 2.91.0

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.
@@ -1262,6 +1262,7 @@ declare class DataDefinition extends AbstractObject {
1262
1262
  findSourceFile(): IFile | undefined;
1263
1263
  hasParserError(): boolean | undefined;
1264
1264
  parse(): IParseResult;
1265
+ getTree(): ExpressionNode | undefined;
1265
1266
  private findSQLViewName;
1266
1267
  private findFieldNames;
1267
1268
  private findSourcesAndRelations;
@@ -6,7 +6,7 @@ const combi_1 = require("../../abap/2_statements/combi");
6
6
  class CDSWithParameters extends combi_1.Expression {
7
7
  getRunnable() {
8
8
  const param = (0, combi_1.seq)(_1.CDSName, ":", _1.CDSType);
9
- return (0, combi_1.seq)("wITH PARAMETERS", param, (0, combi_1.star)((0, combi_1.seq)(",", param)));
9
+ return (0, combi_1.seq)("WITH PARAMETERS", param, (0, combi_1.star)((0, combi_1.seq)(",", param)));
10
10
  }
11
11
  }
12
12
  exports.CDSWithParameters = CDSWithParameters;
@@ -85,6 +85,10 @@ class DataDefinition extends _abstract_object_1.AbstractObject {
85
85
  this.dirty = false;
86
86
  return { updated: true, runtime: Date.now() - start };
87
87
  }
88
+ getTree() {
89
+ var _a;
90
+ return (_a = this.parsedData) === null || _a === void 0 ? void 0 : _a.tree;
91
+ }
88
92
  //////////
89
93
  findSQLViewName() {
90
94
  var _a;
@@ -208,6 +208,12 @@ class Table extends _abstract_object_1.AbstractObject {
208
208
  type: new Types.UnknownType("Table " + this.getName() + ", unknown component type \"" + comptype + "\"")
209
209
  });
210
210
  }
211
+ if (field.CHECKTABLE) {
212
+ const lookup = ddic.lookupTableOrView(field.CHECKTABLE);
213
+ if (lookup.object) {
214
+ references.push({ object: lookup.object });
215
+ }
216
+ }
211
217
  }
212
218
  if (components.length === 0) {
213
219
  return new Types.UnknownType("Table/Structure " + this.getName() + " does not contain any components");
@@ -266,6 +272,7 @@ class Table extends _abstract_object_1.AbstractObject {
266
272
  DECIMALS: field.DECIMALS,
267
273
  KEYFLAG: field.KEYFLAG,
268
274
  GROUPNAME: field.GROUPNAME,
275
+ CHECKTABLE: field.CHECKTABLE,
269
276
  REFTYPE: field.REFTYPE,
270
277
  });
271
278
  }
@@ -68,7 +68,7 @@ class Registry {
68
68
  }
69
69
  static abaplintVersion() {
70
70
  // magic, see build script "version.sh"
71
- return "2.90.12";
71
+ return "2.91.0";
72
72
  }
73
73
  getDDICReferences() {
74
74
  return this.references;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CDSLegacyView = exports.CDSLegacyViewConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const _irule_1 = require("./_irule");
6
+ const version_1 = require("../version");
7
+ const _basic_rule_config_1 = require("./_basic_rule_config");
8
+ const objects_1 = require("../objects");
9
+ class CDSLegacyViewConf extends _basic_rule_config_1.BasicRuleConfig {
10
+ }
11
+ exports.CDSLegacyViewConf = CDSLegacyViewConf;
12
+ class CDSLegacyView {
13
+ constructor() {
14
+ this.conf = new CDSLegacyViewConf();
15
+ }
16
+ getMetadata() {
17
+ return {
18
+ key: "cds_legacy_view",
19
+ title: "CDS Legacy View",
20
+ shortDescription: `Identify CDS Legacy Views`,
21
+ // eslint-disable-next-line max-len
22
+ extendedInformation: `https://blogs.sap.com/2021/10/16/a-new-generation-of-cds-views-how-to-migrate-your-cds-views-to-cds-view-entities/
23
+
24
+ v755 and up`,
25
+ tags: [_irule_1.RuleTag.SingleFile],
26
+ };
27
+ }
28
+ getConfig() {
29
+ return this.conf;
30
+ }
31
+ setConfig(conf) {
32
+ this.conf = conf;
33
+ }
34
+ initialize(reg) {
35
+ this.reg = reg;
36
+ return this;
37
+ }
38
+ run(o) {
39
+ const issues = [];
40
+ if (this.reg.getConfig().getVersion() < version_1.Version.v755
41
+ && this.reg.getConfig().getVersion() !== version_1.Version.Cloud) {
42
+ return [];
43
+ }
44
+ if (o.getType() !== "DDLS") {
45
+ return [];
46
+ }
47
+ if (o instanceof objects_1.DataDefinition) {
48
+ const tree = o.getTree();
49
+ if (tree === undefined) {
50
+ return []; // parser error
51
+ }
52
+ if (tree.findDirectTokenByText("ENTITY") === undefined) {
53
+ const file = o.findSourceFile();
54
+ if (file) {
55
+ issues.push(issue_1.Issue.atRow(file, 1, "CDS Legacy View", this.getMetadata().key, this.getConfig().severity));
56
+ }
57
+ }
58
+ }
59
+ return issues;
60
+ }
61
+ }
62
+ exports.CDSLegacyView = CDSLegacyView;
63
+ //# sourceMappingURL=cds_legacy_view.js.map
@@ -18,7 +18,7 @@ class CDSParserError {
18
18
  title: "CDS Parser Error",
19
19
  shortDescription: `CDS parsing, experimental`,
20
20
  extendedInformation: ``,
21
- tags: [_irule_1.RuleTag.Syntax, _irule_1.RuleTag.Experimental],
21
+ tags: [_irule_1.RuleTag.Syntax],
22
22
  };
23
23
  }
24
24
  getConfig() {
@@ -36,7 +36,7 @@ class CDSParserError {
36
36
  const hasError = o.hasParserError();
37
37
  const file = o.findSourceFile();
38
38
  if (hasError === true && file) {
39
- issues.push(issue_1.Issue.atRow(file, 1, "CDS Parser error", this.getMetadata().key));
39
+ issues.push(issue_1.Issue.atRow(file, 1, "CDS Parser error", this.getMetadata().key, this.getConfig().severity));
40
40
  }
41
41
  }
42
42
  return issues;
@@ -25,6 +25,7 @@ __exportStar(require("./begin_end_names"), exports);
25
25
  __exportStar(require("./begin_single_include"), exports);
26
26
  __exportStar(require("./call_transaction_authority_check"), exports);
27
27
  __exportStar(require("./cds_parser_error"), exports);
28
+ __exportStar(require("./cds_legacy_view"), exports);
28
29
  __exportStar(require("./chain_mainly_declarations"), exports);
29
30
  __exportStar(require("./check_abstract"), exports);
30
31
  __exportStar(require("./check_comments"), exports);
@@ -36,6 +37,7 @@ __exportStar(require("./check_syntax"), exports);
36
37
  __exportStar(require("./classic_exceptions_overlap"), exports);
37
38
  __exportStar(require("./check_text_elements"), exports);
38
39
  __exportStar(require("./check_transformation_exists"), exports);
40
+ __exportStar(require("./superfluous_value"), exports);
39
41
  __exportStar(require("./class_attribute_names"), exports);
40
42
  __exportStar(require("./cloud_types"), exports);
41
43
  __exportStar(require("./colon_missing_space"), exports);
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SuperfluousValue = exports.SuperfluousValueConf = void 0;
4
+ const issue_1 = require("../issue");
5
+ const _abap_rule_1 = require("./_abap_rule");
6
+ const _basic_rule_config_1 = require("./_basic_rule_config");
7
+ const Expressions = require("../abap/2_statements/expressions");
8
+ const Statements = require("../abap/2_statements/statements");
9
+ const _irule_1 = require("./_irule");
10
+ const version_1 = require("../version");
11
+ class SuperfluousValueConf extends _basic_rule_config_1.BasicRuleConfig {
12
+ }
13
+ exports.SuperfluousValueConf = SuperfluousValueConf;
14
+ class SuperfluousValue extends _abap_rule_1.ABAPRule {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.conf = new SuperfluousValueConf();
18
+ }
19
+ getMetadata() {
20
+ return {
21
+ key: "superfluous_value",
22
+ title: "Superfluous VALUE",
23
+ shortDescription: `Find superfluous VALUE expressions`,
24
+ extendedInformation: `Left hand side is inline, VALUE is inferred, value body is simple, from v740sp02 and up`,
25
+ tags: [_irule_1.RuleTag.SingleFile],
26
+ badExample: `DATA(message_entry) = VALUE #( message_table[ msgno = msgno ] ).`,
27
+ goodExample: `DATA(message_entry) = message_table[ msgno = msgno ].`,
28
+ };
29
+ }
30
+ getConfig() {
31
+ return this.conf;
32
+ }
33
+ setConfig(conf) {
34
+ this.conf = conf;
35
+ }
36
+ runParsed(file) {
37
+ var _a, _b;
38
+ const output = [];
39
+ if (this.reg.getConfig().getVersion() < version_1.Version.v740sp02
40
+ && this.reg.getConfig().getVersion() !== version_1.Version.Cloud) {
41
+ return [];
42
+ }
43
+ const struc = file.getStructure();
44
+ if (struc === undefined) {
45
+ return []; // syntax error
46
+ }
47
+ for (const m of struc.findAllStatements(Statements.Move)) {
48
+ if (((_a = m.findDirectExpression(Expressions.Target)) === null || _a === void 0 ? void 0 : _a.findDirectExpression(Expressions.InlineData)) === undefined) {
49
+ continue;
50
+ }
51
+ const source = m.findDirectExpression(Expressions.Source);
52
+ if (source === undefined) {
53
+ continue;
54
+ }
55
+ const type = (_b = source.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _b === void 0 ? void 0 : _b.concatTokens();
56
+ if (type !== "#") {
57
+ continue;
58
+ }
59
+ const body = source.findDirectExpression(Expressions.ValueBody);
60
+ if (body === undefined) {
61
+ continue;
62
+ }
63
+ if (body.getChildren().length === 1) {
64
+ const message = "Superfluous VALUE expression";
65
+ const issue = issue_1.Issue.atStatement(file, m, message, this.getMetadata().key, this.conf.severity);
66
+ output.push(issue);
67
+ }
68
+ }
69
+ return output;
70
+ }
71
+ }
72
+ exports.SuperfluousValue = SuperfluousValue;
73
+ //# sourceMappingURL=superfluous_value.js.map
@@ -25,20 +25,28 @@ class UnnecessaryPragma extends _abap_rule_1.ABAPRule {
25
25
 
26
26
  * NEEDED without definition
27
27
 
28
- * NO_TEXT without texts`,
28
+ * NO_TEXT without texts
29
+
30
+ * SUBRC_OK where sy-subrc is checked`,
29
31
  tags: [_irule_1.RuleTag.SingleFile],
30
32
  badExample: `TRY.
31
33
  ...
32
34
  CATCH zcx_abapgit_exception ##NO_HANDLER.
33
35
  RETURN. " it has a handler
34
36
  ENDTRY.
35
- MESSAGE w125(zbar) WITH c_foo INTO message ##NEEDED ##NO_TEXT.`,
37
+ MESSAGE w125(zbar) WITH c_foo INTO message ##NEEDED ##NO_TEXT.
38
+ SELECT SINGLE * FROM tadir INTO @DATA(sdfs) ##SUBRC_OK.
39
+ IF sy-subrc <> 0.
40
+ ENDIF.`,
36
41
  goodExample: `TRY.
37
42
  ...
38
43
  CATCH zcx_abapgit_exception.
39
44
  RETURN.
40
45
  ENDTRY.
41
- MESSAGE w125(zbar) WITH c_foo INTO message.`,
46
+ MESSAGE w125(zbar) WITH c_foo INTO message.
47
+ SELECT SINGLE * FROM tadir INTO @DATA(sdfs).
48
+ IF sy-subrc <> 0.
49
+ ENDIF.`,
42
50
  };
43
51
  }
44
52
  getConfig() {
@@ -53,6 +61,7 @@ MESSAGE w125(zbar) WITH c_foo INTO message.`,
53
61
  const statements = file.getStatements();
54
62
  for (let i = 0; i < statements.length; i++) {
55
63
  const statement = statements[i];
64
+ const nextStatement = statements[i + 1];
56
65
  if (statement.get() instanceof Statements.EndTry) {
57
66
  noHandler = false;
58
67
  }
@@ -70,6 +79,7 @@ MESSAGE w125(zbar) WITH c_foo INTO message.`,
70
79
  }
71
80
  issues.push(...this.checkText(statement, file));
72
81
  issues.push(...this.checkNeeded(statement, file));
82
+ issues.push(...this.checkSubrc(statement, nextStatement, file));
73
83
  }
74
84
  return issues;
75
85
  }
@@ -85,6 +95,18 @@ MESSAGE w125(zbar) WITH c_foo INTO message.`,
85
95
  }
86
96
  return [];
87
97
  }
98
+ checkSubrc(statement, next, file) {
99
+ const p = statement.getPragmas().find(t => t.getStr().toUpperCase() === "##SUBRC_OK");
100
+ if (p === undefined) {
101
+ return [];
102
+ }
103
+ const concat = next.concatTokens().toUpperCase();
104
+ if (concat.includes(" SY-SUBRC")) {
105
+ const message = "SUBRC_OK can be removed as sy-subrc is checked";
106
+ return [issue_1.Issue.atToken(file, p, message, this.getMetadata().key, this.getConfig().severity)];
107
+ }
108
+ return [];
109
+ }
88
110
  checkNeeded(statement, file) {
89
111
  const p = statement.getPragmas().find(t => t.getStr().toUpperCase() === "##NEEDED");
90
112
  if (p === undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.90.12",
3
+ "version": "2.91.0",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",