@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.
- package/build/src/abap/2_statements/expressions/color.js +2 -2
- package/build/src/abap/5_syntax/basic_types.js +8 -0
- package/build/src/abap/5_syntax/expressions/form_param.js +12 -3
- package/build/src/abap/5_syntax/statements/form.js +7 -3
- package/build/src/abap/5_syntax/statements/format.js +1 -1
- package/build/src/abap/5_syntax/statements/parameter.js +34 -0
- package/build/src/abap/5_syntax/statements/perform.js +37 -4
- package/build/src/registry.js +1 -1
- package/build/src/rules/cloud_types.js +3 -0
- package/package.json +1 -1
|
@@ -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
|
|
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)("=",
|
|
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
|
|
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
|
-
|
|
45
|
-
|
|
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
|
-
|
|
11
|
-
const name =
|
|
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.
|
|
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
|
-
|
|
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;
|
package/build/src/registry.js
CHANGED
|
@@ -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
|