@abaplint/core 2.120.36 → 2.120.37

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.
@@ -3559,6 +3559,7 @@ export declare const enum IdentifierMeta {
3559
3559
  FunctionModuleTables = "function_module_tables",
3560
3560
  EventParameter = "event_parameter",
3561
3561
  FormParameter = "form_parameter",
3562
+ FormParameterStructure = "form_parameter_structure",
3562
3563
  ReadOnly = "read_only",
3563
3564
  Tables = "tables",
3564
3565
  Abstract = "abstract",
@@ -575,6 +575,29 @@ class TypeUtils {
575
575
  }
576
576
  return this.isAssignable(source, target);
577
577
  }
578
+ // Typing with the classic STRUCTURE addition, ie. "FORM foo USING bar STRUCTURE zkey",
579
+ // is not a compatibility check: ABAP only checks the fragment view up to the end of the
580
+ // formal structure, so the actual parameter is allowed to be longer. For TABLES parameters
581
+ // the table key is not part of the check at all.
582
+ isAssignableStructureTyping(source, target, node) {
583
+ if (source instanceof basic_1.StructureType && target instanceof basic_1.StructureType) {
584
+ const sourceComponents = source.getComponents();
585
+ const targetComponents = target.getComponents();
586
+ if (sourceComponents.length < targetComponents.length) {
587
+ return false;
588
+ }
589
+ for (let i = 0; i < targetComponents.length; i++) {
590
+ if (this.isAssignableStrict(sourceComponents[i].type, targetComponents[i].type) === false) {
591
+ return false;
592
+ }
593
+ }
594
+ return true;
595
+ }
596
+ else if (source instanceof basic_1.TableType && target instanceof basic_1.TableType) {
597
+ return this.isAssignableStructureTyping(source.getRowType(), target.getRowType());
598
+ }
599
+ return this.isAssignableStrict(source, target, node);
600
+ }
578
601
  isAssignable(source, target) {
579
602
  if (source === undefined || target === undefined) {
580
603
  return true;
@@ -31,7 +31,7 @@ class FormParam {
31
31
  else {
32
32
  type = new basic_1.UnknownType("todo, FORM STRUCTURES typing");
33
33
  }
34
- return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, type, ["form_parameter" /* IdentifierMeta.FormParameter */]);
34
+ return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, type, ["form_parameter" /* IdentifierMeta.FormParameter */, "form_parameter_structure" /* IdentifierMeta.FormParameterStructure */]);
35
35
  }
36
36
  if (node.getChildren().length === 1 && nameToken) {
37
37
  // untyped FORM parameter
@@ -113,7 +113,11 @@ class Perform {
113
113
  continue;
114
114
  }
115
115
  const parameter = formal[i];
116
- if (typeUtils.isAssignableStrict(type, parameter.getType(), source) === false) {
116
+ const structureTyping = parameter.getMeta().includes("form_parameter_structure" /* IdentifierMeta.FormParameterStructure */);
117
+ const assignable = structureTyping
118
+ ? typeUtils.isAssignableStructureTyping(type, parameter.getType(), source)
119
+ : typeUtils.isAssignableStrict(type, parameter.getType(), source);
120
+ if (assignable === false) {
117
121
  const message = `PERFORM parameter type not compatible, ${parameter.getName()}`;
118
122
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, source.getFirstToken(), message));
119
123
  return false;
@@ -90,7 +90,8 @@ class FormDefinition extends _identifier_1.Identifier {
90
90
  else if (!(type instanceof basic_1.UnknownType) && !(type instanceof basic_1.VoidType)) {
91
91
  type = new basic_1.UnknownType("FORM TABLES type must be table type");
92
92
  }
93
- ret.push(new _typed_identifier_1.TypedIdentifier(p.getToken(), input.filename, type, ["form_parameter" /* IdentifierMeta.FormParameter */]));
93
+ // keep the meta from FormParam, so STRUCTURE typing can be recognized later
94
+ ret.push(new _typed_identifier_1.TypedIdentifier(p.getToken(), input.filename, type, p.getMeta()));
94
95
  }
95
96
  }
96
97
  return ret;
@@ -75,7 +75,7 @@ class Registry {
75
75
  }
76
76
  static abaplintVersion() {
77
77
  // magic, see build script "version.js"
78
- return "2.120.36";
78
+ return "2.120.37";
79
79
  }
80
80
  getDDICReferences() {
81
81
  return this.ddicReferences;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.120.36",
3
+ "version": "2.120.37",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",