@abaplint/cli 2.120.35 → 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.
Files changed (2) hide show
  1. package/build/cli.js +48 -7
  2. package/package.json +2 -2
package/build/cli.js CHANGED
@@ -27903,6 +27903,29 @@ class TypeUtils {
27903
27903
  }
27904
27904
  return this.isAssignable(source, target);
27905
27905
  }
27906
+ // Typing with the classic STRUCTURE addition, ie. "FORM foo USING bar STRUCTURE zkey",
27907
+ // is not a compatibility check: ABAP only checks the fragment view up to the end of the
27908
+ // formal structure, so the actual parameter is allowed to be longer. For TABLES parameters
27909
+ // the table key is not part of the check at all.
27910
+ isAssignableStructureTyping(source, target, node) {
27911
+ if (source instanceof basic_1.StructureType && target instanceof basic_1.StructureType) {
27912
+ const sourceComponents = source.getComponents();
27913
+ const targetComponents = target.getComponents();
27914
+ if (sourceComponents.length < targetComponents.length) {
27915
+ return false;
27916
+ }
27917
+ for (let i = 0; i < targetComponents.length; i++) {
27918
+ if (this.isAssignableStrict(sourceComponents[i].type, targetComponents[i].type) === false) {
27919
+ return false;
27920
+ }
27921
+ }
27922
+ return true;
27923
+ }
27924
+ else if (source instanceof basic_1.TableType && target instanceof basic_1.TableType) {
27925
+ return this.isAssignableStructureTyping(source.getRowType(), target.getRowType());
27926
+ }
27927
+ return this.isAssignableStrict(source, target, node);
27928
+ }
27906
27929
  isAssignable(source, target) {
27907
27930
  if (source === undefined || target === undefined) {
27908
27931
  return true;
@@ -28657,7 +28680,7 @@ class BasicTypes {
28657
28680
  return Types.VoidType.get((_f = node.findFirstExpression(Expressions.TypeStructure)) === null || _f === void 0 ? void 0 : _f.concatTokens());
28658
28681
  }
28659
28682
  else if (text.startsWith("LIKE LINE OF ")) {
28660
- const name = (_g = node.findFirstExpression(Expressions.FieldChain)) === null || _g === void 0 ? void 0 : _g.concatTokens();
28683
+ let name = (_g = node.findFirstExpression(Expressions.FieldChain)) === null || _g === void 0 ? void 0 : _g.concatTokens();
28661
28684
  let e = node.findFirstExpression(Expressions.Type);
28662
28685
  if (e === undefined) {
28663
28686
  e = node.findFirstExpression(Expressions.FormParamType);
@@ -28665,19 +28688,32 @@ class BasicTypes {
28665
28688
  if (e === undefined) {
28666
28689
  e = node.findFirstExpression(Expressions.FieldChain);
28667
28690
  }
28691
+ if (e === undefined) {
28692
+ // old style, eg "LIKE LINE OF tab OCCURS 0 WITH HEADER LINE", it is parsed as TypeName
28693
+ e = typeName;
28694
+ name = typeName === null || typeName === void 0 ? void 0 : typeName.concatTokens();
28695
+ }
28668
28696
  const type = this.resolveLikeName(e, false);
28697
+ let row = undefined;
28669
28698
  if (type === undefined) {
28670
28699
  return new Types.UnknownType("Type error, could not resolve \"" + name + "\", parseType");
28671
28700
  }
28672
28701
  else if (type instanceof Types.TableType) {
28673
- return type.getRowType();
28702
+ row = type.getRowType();
28674
28703
  }
28675
28704
  else if (type instanceof Types.VoidType) {
28676
- return type;
28705
+ row = type;
28677
28706
  }
28678
28707
  else {
28679
28708
  return new Types.UnknownType("Type error, not a table type " + name);
28680
28709
  }
28710
+ if (this.isOccurs(node)) {
28711
+ return new Types.TableType(row, {
28712
+ withHeader: text.includes(" WITH HEADER LINE"),
28713
+ keyType: Types.TableKeyType.default
28714
+ }, qualifiedName);
28715
+ }
28716
+ return row;
28681
28717
  }
28682
28718
  else if (text.startsWith("LIKE REF TO ")) {
28683
28719
  const name = (_h = node.findFirstExpression(Expressions.FieldChain)) === null || _h === void 0 ? void 0 : _h.concatTokens();
@@ -31492,7 +31528,7 @@ class FormParam {
31492
31528
  else {
31493
31529
  type = new basic_1.UnknownType("todo, FORM STRUCTURES typing");
31494
31530
  }
31495
- return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, type, ["form_parameter" /* IdentifierMeta.FormParameter */]);
31531
+ return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, type, ["form_parameter" /* IdentifierMeta.FormParameter */, "form_parameter_structure" /* IdentifierMeta.FormParameterStructure */]);
31496
31532
  }
31497
31533
  if (node.getChildren().length === 1 && nameToken) {
31498
31534
  // untyped FORM parameter
@@ -43712,7 +43748,11 @@ class Perform {
43712
43748
  continue;
43713
43749
  }
43714
43750
  const parameter = formal[i];
43715
- if (typeUtils.isAssignableStrict(type, parameter.getType(), source) === false) {
43751
+ const structureTyping = parameter.getMeta().includes("form_parameter_structure" /* IdentifierMeta.FormParameterStructure */);
43752
+ const assignable = structureTyping
43753
+ ? typeUtils.isAssignableStructureTyping(type, parameter.getType(), source)
43754
+ : typeUtils.isAssignableStrict(type, parameter.getType(), source);
43755
+ if (assignable === false) {
43716
43756
  const message = `PERFORM parameter type not compatible, ${parameter.getName()}`;
43717
43757
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, source.getFirstToken(), message));
43718
43758
  return false;
@@ -52595,7 +52635,8 @@ class FormDefinition extends _identifier_1.Identifier {
52595
52635
  else if (!(type instanceof basic_1.UnknownType) && !(type instanceof basic_1.VoidType)) {
52596
52636
  type = new basic_1.UnknownType("FORM TABLES type must be table type");
52597
52637
  }
52598
- ret.push(new _typed_identifier_1.TypedIdentifier(p.getToken(), input.filename, type, ["form_parameter" /* IdentifierMeta.FormParameter */]));
52638
+ // keep the meta from FormParam, so STRUCTURE typing can be recognized later
52639
+ ret.push(new _typed_identifier_1.TypedIdentifier(p.getToken(), input.filename, type, p.getMeta()));
52599
52640
  }
52600
52641
  }
52601
52642
  return ret;
@@ -70106,7 +70147,7 @@ class Registry {
70106
70147
  }
70107
70148
  static abaplintVersion() {
70108
70149
  // magic, see build script "version.js"
70109
- return "2.120.35";
70150
+ return "2.120.37";
70110
70151
  }
70111
70152
  getDDICReferences() {
70112
70153
  return this.ddicReferences;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/cli",
3
- "version": "2.120.35",
3
+ "version": "2.120.37",
4
4
  "description": "abaplint - Command Line Interface",
5
5
  "funding": "https://github.com/sponsors/larshp",
6
6
  "bin": {
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "homepage": "https://abaplint.org",
41
41
  "devDependencies": {
42
- "@abaplint/core": "^2.120.35",
42
+ "@abaplint/core": "^2.120.37",
43
43
  "@types/chai": "^4.3.20",
44
44
  "@types/minimist": "^1.2.5",
45
45
  "@types/mocha": "^10.0.10",