@abaplint/core 2.90.11 → 2.91.1

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;
@@ -22,6 +22,7 @@ class TypeUtils {
22
22
  else if (type instanceof basic_1.StringType
23
23
  || type instanceof basic_1.AnyType
24
24
  || type instanceof basic_1.CharacterType
25
+ || type instanceof basic_1.SimpleType
25
26
  || type instanceof basic_1.CLikeType
26
27
  || type instanceof basic_1.DateType
27
28
  || type instanceof basic_1.CSequenceType
@@ -55,6 +56,7 @@ class TypeUtils {
55
56
  || type instanceof basic_1.UnknownType
56
57
  || type instanceof basic_1.NumericType
57
58
  || type instanceof basic_1.IntegerType
59
+ || type instanceof basic_1.SimpleType
58
60
  || type instanceof basic_1.FloatType
59
61
  || type instanceof basic_1.FloatingPointType
60
62
  || type instanceof basic_1.DecFloatType
@@ -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.11";
71
+ return "2.91.1";
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;
@@ -1252,14 +1252,6 @@ ${indentation} output = ${topTarget}.`;
1252
1252
  body += indentation + uniqueName + " = " + base.concatTokens() + ".\n";
1253
1253
  }
1254
1254
  let end = "";
1255
- /*
1256
- for (const forLoop of valueBody?.findDirectExpressions(Expressions.For) || []) {
1257
- const outlineFor = this.outlineFor(forLoop, indentation, lowFile, highSyntax);
1258
- body += outlineFor.body;
1259
- end = outlineFor.end + `.\n` + end;
1260
- indentation += " ";
1261
- }
1262
- */
1263
1255
  let structureName = uniqueName;
1264
1256
  let added = false;
1265
1257
  let skip = false;
@@ -1284,6 +1276,9 @@ ${indentation} output = ${topTarget}.`;
1284
1276
  indentation += " ";
1285
1277
  }
1286
1278
  else if (b.get() instanceof Expressions.Source) {
1279
+ if ((valueBody === null || valueBody === void 0 ? void 0 : valueBody.getChildren().length) === 1) {
1280
+ body += indentation + uniqueName + " = " + b.concatTokens() + `.\n`;
1281
+ }
1287
1282
  structureName = b.concatTokens();
1288
1283
  if (base && (valueBody === null || valueBody === void 0 ? void 0 : valueBody.findDirectTokenByText("(")) === undefined) {
1289
1284
  structureName = uniqueName;
@@ -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.11",
3
+ "version": "2.91.1",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",