@abaplint/core 2.120.33 → 2.120.35

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.
@@ -429,6 +429,8 @@ declare class Attributes implements IAttributes {
429
429
  private parse;
430
430
  private parseSection;
431
431
  private parseAlias;
432
+ /** does the component exist in the interface, or in one of its aliases or included interfaces? */
433
+ private existsInInterface;
432
434
  private parseAttribute;
433
435
  }
434
436
 
@@ -204,6 +204,11 @@ class ObjectOriented {
204
204
  if (found) {
205
205
  return found;
206
206
  }
207
+ if (name.includes("~")) {
208
+ // event of an implemented interface, ie. "if_name~event_name"
209
+ const [interfaceName, eventName] = name.split("~");
210
+ return this.searchEvent(this.scope.findInterfaceDefinition(interfaceName), eventName);
211
+ }
207
212
  for (const a of def.getAliases() || []) {
208
213
  if (a.getName().toUpperCase() === name.toUpperCase()) {
209
214
  const comp = a.getComponent();
@@ -454,6 +454,11 @@ class TypeUtils {
454
454
  }
455
455
  return false;
456
456
  }
457
+ else if (target instanceof basic_1.TableType
458
+ || target instanceof basic_1.DataReference
459
+ || target instanceof basic_1.ObjectReferenceType) {
460
+ return false;
461
+ }
457
462
  return true;
458
463
  }
459
464
  else if (source instanceof basic_1.StructureType) {
@@ -478,7 +483,8 @@ class TypeUtils {
478
483
  }
479
484
  else if (target instanceof basic_1.VoidType
480
485
  || target instanceof basic_1.AnyType
481
- || target instanceof basic_1.DataType) {
486
+ || target instanceof basic_1.DataType
487
+ || target instanceof basic_1.UnknownType) {
482
488
  return true;
483
489
  }
484
490
  return false;
@@ -52,6 +52,7 @@ const constants_1 = require("../5_syntax/structures/constants");
52
52
  const type_definitions_1 = require("./type_definitions");
53
53
  const types_1 = require("../5_syntax/structures/types");
54
54
  const type_1 = require("../5_syntax/statements/type");
55
+ const _syntax_input_1 = require("../5_syntax/_syntax_input");
55
56
  const _reference_1 = require("../5_syntax/_reference");
56
57
  const alias_1 = require("./alias");
57
58
  class Attributes {
@@ -273,6 +274,13 @@ class Attributes {
273
274
  if (foundAttribute) {
274
275
  input.scope.addNamedIdentifier(aliasName.getStr(), foundAttribute);
275
276
  }
277
+ const component = compName.split("~")[1];
278
+ if (foundType === undefined
279
+ && foundAttribute === undefined
280
+ && this.existsInInterface(idef, component, input, []) === false) {
281
+ const message = "Component " + component + " not found in interface " + idef.getName();
282
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, compToken, message));
283
+ }
276
284
  }
277
285
  else if (this.declaredInterfaces.includes(name.toUpperCase()) || input.scope.getDDIC().inErrorNamespace(name) === false) {
278
286
  input.scope.addReference(compToken, undefined, _reference_1.ReferenceType.ObjectOrientedVoidReference, input.filename);
@@ -282,6 +290,33 @@ class Attributes {
282
290
  }
283
291
  }
284
292
  }
293
+ /** does the component exist in the interface, or in one of its aliases or included interfaces? */
294
+ existsInInterface(idef, component, input, visited) {
295
+ const upperName = idef.getName().toUpperCase();
296
+ if (visited.includes(upperName)) {
297
+ return false;
298
+ }
299
+ visited.push(upperName);
300
+ const upper = component.toUpperCase();
301
+ if (idef.getTypeDefinitions().getByName(component) !== undefined
302
+ || idef.getAttributes().findByName(component) !== undefined
303
+ || idef.getMethodDefinitions().getByName(component) !== undefined
304
+ || idef.getEvents().some(e => e.getName().toUpperCase() === upper)
305
+ || idef.getAliases().some(a => a.getName().toUpperCase() === upper)) {
306
+ return true;
307
+ }
308
+ for (const i of idef.getImplementing()) {
309
+ const sub = input.scope.findInterfaceDefinition(i.name);
310
+ if (sub === undefined) {
311
+ // voided or not found, assume the component exists
312
+ return true;
313
+ }
314
+ else if (this.existsInInterface(sub, component, input, visited)) {
315
+ return true;
316
+ }
317
+ }
318
+ return false;
319
+ }
285
320
  parseAttribute(node, visibility, input) {
286
321
  let found = undefined;
287
322
  const s = node.get();
@@ -75,7 +75,7 @@ class Registry {
75
75
  }
76
76
  static abaplintVersion() {
77
77
  // magic, see build script "version.js"
78
- return "2.120.33";
78
+ return "2.120.35";
79
79
  }
80
80
  getDDICReferences() {
81
81
  return this.ddicReferences;
@@ -88,7 +88,8 @@ class CDSFieldOrder {
88
88
  }
89
89
  getAssociationNames(tree) {
90
90
  const names = new Set();
91
- for (const assoc of tree.findAllExpressions(expressions_1.CDSAssociation)) {
91
+ const found = [...tree.findAllExpressions(expressions_1.CDSAssociation), ...tree.findAllExpressions(expressions_1.CDSComposition)];
92
+ for (const assoc of found) {
92
93
  const relation = assoc.findDirectExpression(expressions_1.CDSRelation);
93
94
  if (relation === undefined) {
94
95
  continue;
@@ -6,7 +6,6 @@ const _irule_1 = require("./_irule");
6
6
  const _basic_rule_config_1 = require("./_basic_rule_config");
7
7
  const objects_1 = require("../objects");
8
8
  const expressions_1 = require("../cds/expressions");
9
- const cds_name_1 = require("../cds/expressions/cds_name");
10
9
  class CDSNamingConf extends _basic_rule_config_1.BasicRuleConfig {
11
10
  constructor() {
12
11
  super(...arguments);
@@ -78,7 +77,7 @@ https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee6ff9b281d8448f96b4fe6c89f2bdc8
78
77
  if (file === undefined) {
79
78
  return [];
80
79
  }
81
- const name = this.getCDSName(tree);
80
+ const name = o.getDefinitionName();
82
81
  if (name === undefined) {
83
82
  return [];
84
83
  }
@@ -95,13 +94,6 @@ https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/ee6ff9b281d8448f96b4fe6c89f2bdc8
95
94
  }
96
95
  return [];
97
96
  }
98
- getCDSName(tree) {
99
- const nameNodes = tree.findDirectExpressions(cds_name_1.CDSName);
100
- if (nameNodes.length > 0) {
101
- return nameNodes[0].getFirstToken().getStr();
102
- }
103
- return undefined;
104
- }
105
97
  getAllowedPrefixes(tree) {
106
98
  const root = tree.get();
107
99
  if (root instanceof expressions_1.CDSExtendView) {
@@ -85,17 +85,19 @@ class NoDynamicStuff extends _abap_rule_1.ABAPRule {
85
85
  extendedInformation: `Dynamic constructs cannot be checked statically, they are not found by
86
86
  where-used lists and refactorings, and they can introduce injection vulnerabilities.
87
87
 
88
- Dynamic tokens containing a literal, eg. CALL METHOD ('CL_FOO')=>('BAR'), are not reported,
89
- as these are equivalent to the static variant.
88
+ Dynamic tokens are also reported when containing a literal, eg. CALL METHOD go_calendar->('RESET_DAY_INFO'),
89
+ the syntax check does not resolve these either, so they behave like any other dynamic token.
90
90
 
91
91
  Dynamic SQL is reported by rule dangerous_statement.`,
92
92
  tags: [_irule_1.RuleTag.SingleFile, _irule_1.RuleTag.Security],
93
93
  badExample: `CALL METHOD (lv_class)=>(lv_method).
94
+ CALL METHOD go_calendar->('RESET_DAY_INFO').
94
95
  CALL FUNCTION lv_function_module.
95
96
  CREATE OBJECT ref TYPE (lv_class).
96
97
  ASSIGN (lv_name) TO <fs>.
97
98
  SORT tab BY (lv_field).`,
98
99
  goodExample: `cl_class=>method( ).
100
+ go_calendar->reset_day_info( ).
99
101
  CALL FUNCTION 'ZFOO'.
100
102
  CREATE OBJECT ref TYPE cl_class.
101
103
  ASSIGN foo TO <fs>.
@@ -207,10 +209,8 @@ SORT tab BY field.`,
207
209
  for (const source of node.findAllExpressions(Expressions.MethodSource)) {
208
210
  // Dynamic is always a direct child of MethodSource, dynamics further down
209
211
  // are parameters of the method call and not part of the method name
210
- for (const dynamic of source.findDirectExpressions(Expressions.Dynamic)) {
211
- if (this.isLiteral(dynamic) === false) {
212
- return true;
213
- }
212
+ if (source.findDirectExpression(Expressions.Dynamic) !== undefined) {
213
+ return true;
214
214
  }
215
215
  }
216
216
  return false;
@@ -221,12 +221,7 @@ SORT tab BY field.`,
221
221
  return component !== undefined && this.isLiteral(component) === false;
222
222
  }
223
223
  hasDynamic(node) {
224
- for (const dynamic of node.findAllExpressions(Expressions.Dynamic)) {
225
- if (this.isLiteral(dynamic) === false) {
226
- return true;
227
- }
228
- }
229
- return false;
224
+ return node.findFirstExpression(Expressions.Dynamic) !== undefined;
230
225
  }
231
226
  notLiteral(node) {
232
227
  return node !== undefined && this.isLiteral(node) === false;
@@ -56,6 +56,10 @@ exports.DECLARATION_STUFF = [
56
56
  Statements.DataBegin,
57
57
  Statements.Constant,
58
58
  Statements.ConstantBegin,
59
+ Statements.Static,
60
+ Statements.StaticBegin,
61
+ Statements.FieldSymbol,
62
+ Statements.Ranges,
59
63
  Statements.Tables,
60
64
  Statements.Include, // this is not super correct, but anyhow
61
65
  Statements.Parameter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.120.33",
3
+ "version": "2.120.35",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",