@abaplint/core 2.120.29 → 2.120.31

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.
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Color = void 0;
4
4
  const combi_1 = require("../combi");
5
- const source_1 = require("./source");
5
+ const simple_source3_1 = require("./simple_source3");
6
6
  class Color extends combi_1.Expression {
7
7
  getRunnable() {
8
- const eq = (0, combi_1.seq)("=", source_1.Source);
8
+ const eq = (0, combi_1.seq)("=", simple_source3_1.SimpleSource3);
9
9
  const integers = (0, combi_1.altPrio)("1", "2", "3", "4", "5", "6", "7");
10
10
  const texts = (0, combi_1.altPrio)("COL_BACKGROUND", "COL_HEADING", "COL_NORMAL", "COL_TOTAL", "COL_KEY", "COL_POSITIVE", "COL_NEGATIVE", "COL_GROUP");
11
11
  const value = (0, combi_1.alt)(eq, (0, combi_1.altPrio)("ON", "OFF", "COLOR OFF", (0, combi_1.altPrio)(integers, texts)));
@@ -50,6 +50,7 @@ const types_1 = require("../types");
50
50
  const expressions_1 = require("../2_statements/expressions");
51
51
  const _builtin_1 = require("./_builtin");
52
52
  const position_1 = require("../../position");
53
+ const _syntax_input_1 = require("./_syntax_input");
53
54
  class BasicTypes {
54
55
  constructor(input) {
55
56
  this.input = input;
@@ -990,6 +991,13 @@ class BasicTypes {
990
991
  }
991
992
  const chain = val.findFirstExpression(Expressions.SimpleFieldChain);
992
993
  if (chain) {
994
+ // todo, hardcoded for now, should be a generic check that the chain is a constant
995
+ const concat = chain.concatTokens().toUpperCase();
996
+ if (concat === "SY-DATUM" || concat === "SY-UZEIT") {
997
+ const message = "VALUE, " + concat.toLowerCase() + " is not a constant";
998
+ this.input.issues.push((0, _syntax_input_1.syntaxIssue)(this.input, chain.getFirstToken(), message));
999
+ return undefined;
1000
+ }
993
1001
  return this.resolveConstantValue(chain);
994
1002
  }
995
1003
  throw new Error("findValue, unexpected");
@@ -38,11 +38,20 @@ class FormParam {
38
38
  return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, basic_1.AnyType.get(), ["form_parameter" /* IdentifierMeta.FormParameter */]);
39
39
  }
40
40
  let bfound = new basic_types_1.BasicTypes(input).parseType(node);
41
- const isTypeC = ((_c = node.findFirstExpression(expressions_1.TypeName)) === null || _c === void 0 ? void 0 : _c.concatTokens().toUpperCase()) === "C";
41
+ const typeName = (_c = node.findFirstExpression(expressions_1.TypeName)) === null || _c === void 0 ? void 0 : _c.concatTokens().toUpperCase();
42
42
  const hasExplicitLength = node.findFirstExpression(expressions_1.Length) !== undefined
43
43
  || node.findFirstExpression(expressions_1.ConstantFieldLength) !== undefined;
44
- if (isTypeC && hasExplicitLength === false && bfound instanceof basic_1.CharacterType) {
45
- bfound = basic_1.CGenericType.get();
44
+ // the length cannot be specified for FORM parameters, so these types are generic
45
+ if (hasExplicitLength === false) {
46
+ if (typeName === "C" && bfound instanceof basic_1.CharacterType) {
47
+ bfound = basic_1.CGenericType.get();
48
+ }
49
+ else if (typeName === "X" && bfound instanceof basic_1.HexType) {
50
+ bfound = basic_1.XGenericType.get();
51
+ }
52
+ else if (typeName === "P" && bfound instanceof basic_1.PackedType) {
53
+ bfound = basic_1.PGenericType.get();
54
+ }
46
55
  }
47
56
  if (nameToken && bfound) {
48
57
  return new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, bfound, ["form_parameter" /* IdentifierMeta.FormParameter */]);
@@ -7,13 +7,17 @@ const expressions_1 = require("../../2_statements/expressions");
7
7
  const _syntax_input_1 = require("../_syntax_input");
8
8
  class Form {
9
9
  runSyntax(node, input) {
10
- var _a;
11
- const name = (_a = node.findDirectExpression(expressions_1.FormName)) === null || _a === void 0 ? void 0 : _a.concatTokens();
12
- if (name === undefined) {
10
+ const nameExpression = node.findDirectExpression(expressions_1.FormName);
11
+ const name = nameExpression === null || nameExpression === void 0 ? void 0 : nameExpression.concatTokens();
12
+ if (nameExpression === undefined || name === undefined) {
13
13
  const message = "Form, could not find name";
14
14
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
15
15
  return;
16
16
  }
17
+ if (name.length > 30) {
18
+ const message = "FORM name longer than 30 characters";
19
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, nameExpression.getFirstToken(), message));
20
+ }
17
21
  input.scope.push(_scope_type_1.ScopeType.Form, name, node.getFirstToken().getStart(), input.filename);
18
22
  const form = new form_definition_1.FormDefinition(node, input);
19
23
  input.scope.addList(form.getUsingParameters());
@@ -38,7 +38,7 @@ const Expressions = __importStar(require("../../2_statements/expressions"));
38
38
  const source_1 = require("../expressions/source");
39
39
  class Format {
40
40
  runSyntax(node, input) {
41
- for (const s of node.findAllExpressions(Expressions.Source)) {
41
+ for (const s of node.findAllExpressionsMulti([Expressions.Source, Expressions.SimpleSource3])) {
42
42
  source_1.Source.runSyntax(s, input);
43
43
  }
44
44
  }
@@ -62,6 +62,16 @@ class Parameter {
62
62
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
63
63
  return;
64
64
  }
65
+ const radioGroup = node.findFirstExpression(Expressions.RadioGroupName);
66
+ if (radioGroup && radioGroup.concatTokens().length > 4) {
67
+ const message = "Radio button group name too long, " + radioGroup.concatTokens();
68
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, radioGroup.getFirstToken(), message));
69
+ }
70
+ if (this.hasUserCommand(node) && this.hasLength(node)) {
71
+ const message = "USER-COMMAND and LENGTH not possible together";
72
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
73
+ return;
74
+ }
65
75
  const bfound = new basic_types_1.BasicTypes(input).parseType(node);
66
76
  if (bfound) {
67
77
  input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(nameToken, input.filename, bfound));
@@ -73,6 +83,30 @@ class Parameter {
73
83
  const magicToken = new tokens_1.Identifier(nameToken.getStart(), magicName);
74
84
  input.scope.addIdentifier(new _typed_identifier_1.TypedIdentifier(magicToken, input.filename, basic_1.VoidType.get("PARAMETER-MAGIC")));
75
85
  }
86
+ // "USER-COMMAND" is lexed as three tokens
87
+ hasUserCommand(node) {
88
+ const tokens = node.getTokens();
89
+ for (let i = 0; i < tokens.length - 2; i++) {
90
+ if (tokens[i].getStr().toUpperCase() === "USER"
91
+ && tokens[i + 1].getStr() === "-"
92
+ && tokens[i + 2].getStr().toUpperCase() === "COMMAND") {
93
+ return true;
94
+ }
95
+ }
96
+ return false;
97
+ }
98
+ // "VISIBLE LENGTH" is not the same as "LENGTH"
99
+ hasLength(node) {
100
+ var _a;
101
+ const tokens = node.getTokens();
102
+ for (let i = 0; i < tokens.length; i++) {
103
+ if (tokens[i].getStr().toUpperCase() === "LENGTH"
104
+ && ((_a = tokens[i - 1]) === null || _a === void 0 ? void 0 : _a.getStr().toUpperCase()) !== "VISIBLE") {
105
+ return true;
106
+ }
107
+ }
108
+ return false;
109
+ }
76
110
  }
77
111
  exports.Parameter = Parameter;
78
112
  //# sourceMappingURL=parameter.js.map
@@ -42,6 +42,7 @@ const target_1 = require("../expressions/target");
42
42
  const _syntax_input_1 = require("../_syntax_input");
43
43
  const assert_error_1 = require("../assert_error");
44
44
  const dynamic_1 = require("../expressions/dynamic");
45
+ const _type_utils_1 = require("../_type_utils");
45
46
  class Perform {
46
47
  runSyntax(node, input) {
47
48
  if (!(node.get() instanceof Statements.Perform)) {
@@ -49,19 +50,22 @@ class Perform {
49
50
  }
50
51
  ////////////////////////////
51
52
  // check parameters are defined
53
+ const changing = [];
52
54
  for (const c of node.findDirectExpressions(Expressions.PerformChanging)) {
53
55
  for (const s of c.findDirectExpressions(Expressions.Target)) {
54
- target_1.Target.runSyntax(s, input);
56
+ changing.push({ node: s, type: target_1.Target.runSyntax(s, input) });
55
57
  }
56
58
  }
59
+ const tables = [];
57
60
  for (const t of node.findDirectExpressions(Expressions.PerformTables)) {
58
61
  for (const s of t.findDirectExpressions(Expressions.Source)) {
59
- source_1.Source.runSyntax(s, input);
62
+ tables.push({ node: s, type: source_1.Source.runSyntax(s, input) });
60
63
  }
61
64
  }
65
+ const using = [];
62
66
  for (const u of node.findDirectExpressions(Expressions.PerformUsing)) {
63
67
  for (const s of u.findDirectExpressions(Expressions.SimpleSource3)) {
64
- source_1.Source.runSyntax(s, input);
68
+ using.push({ node: s, type: source_1.Source.runSyntax(s, input) });
65
69
  }
66
70
  }
67
71
  ////////////////////////////
@@ -86,7 +90,36 @@ class Perform {
86
90
  return;
87
91
  }
88
92
  input.scope.addReference(expr.getFirstToken(), found, _reference_1.ReferenceType.FormReference, input.filename);
89
- // todo, also check parameters match
93
+ ////////////////////////////
94
+ // check parameters match
95
+ // USING and CHANGING are interchangeable, the actual parameters form a single positional list
96
+ if (this.checkParameters(node, tables, found.getTablesParameters(), "TABLES", input) === false) {
97
+ return;
98
+ }
99
+ const formal = found.getUsingParameters().concat(found.getChangingParameters());
100
+ this.checkParameters(node, using.concat(changing), formal, "USING/CHANGING", input);
101
+ }
102
+ // returns false if an issue was reported
103
+ checkParameters(node, actual, formal, kind, input) {
104
+ if (actual.length !== formal.length) {
105
+ const message = `PERFORM, expected ${formal.length} ${kind} parameters, found ${actual.length}`;
106
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
107
+ return false;
108
+ }
109
+ const typeUtils = new _type_utils_1.TypeUtils(input.scope);
110
+ for (let i = 0; i < actual.length; i++) {
111
+ const { node: source, type } = actual[i];
112
+ if (type === undefined) {
113
+ continue;
114
+ }
115
+ const parameter = formal[i];
116
+ if (typeUtils.isAssignableStrict(type, parameter.getType(), source) === false) {
117
+ const message = `PERFORM parameter type not compatible, ${parameter.getName()}`;
118
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, source.getFirstToken(), message));
119
+ return false;
120
+ }
121
+ }
122
+ return true;
90
123
  }
91
124
  }
92
125
  exports.Perform = Perform;
@@ -75,7 +75,7 @@ class Registry {
75
75
  }
76
76
  static abaplintVersion() {
77
77
  // magic, see build script "version.js"
78
- return "2.120.29";
78
+ return "2.120.31";
79
79
  }
80
80
  getDDICReferences() {
81
81
  return this.ddicReferences;
@@ -83,6 +83,7 @@ class CloudTypes {
83
83
  || obj instanceof Objects.BehaviorDefinition
84
84
  || obj instanceof Objects.BusinessCatalog
85
85
  || obj instanceof Objects.BusinessCatalogAppAssignment
86
+ || obj instanceof Objects.BusinessConfigurationMaintenanceObject
86
87
  || obj instanceof Objects.CDSMetadataExtension
87
88
  || obj instanceof Objects.Class
88
89
  || obj instanceof Objects.CDSType
@@ -99,11 +100,13 @@ class CloudTypes {
99
100
  || obj instanceof Objects.EventBinding
100
101
  || obj instanceof Objects.EventConsumer
101
102
  || obj instanceof Objects.FunctionGroup
103
+ || obj instanceof Objects.GatewayODataGroupAndAssignment
102
104
  || obj instanceof Objects.HttpService
103
105
  || obj instanceof Objects.IAMApp
104
106
  || obj instanceof Objects.InboundService
105
107
  || obj instanceof Objects.Interface
106
108
  || obj instanceof Objects.LockObject
109
+ || obj instanceof Objects.MaintenanceAndTransportObject
107
110
  || obj instanceof Objects.MessageClass
108
111
  || obj instanceof Objects.NumberRange
109
112
  || obj instanceof Objects.OutboundService
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.120.29",
3
+ "version": "2.120.31",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",