@abaplint/core 2.114.0 → 2.114.2

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.
@@ -1,7 +1,7 @@
1
1
  import * as LServer from 'vscode-languageserver-types';
2
2
  import { WorkspaceEdit } from 'vscode-languageserver-types';
3
3
 
4
- export declare class ABAPFile extends AbstractFile {
4
+ export declare class ABAPFile extends AbstractFile implements IABAPFile {
5
5
  private readonly tokens;
6
6
  private readonly statements;
7
7
  private readonly structure;
@@ -9,8 +9,8 @@ export declare class ABAPFile extends AbstractFile {
9
9
  private readonly info;
10
10
  constructor(file: IFile, tokens: readonly Token[], statements: readonly StatementNode[], structure: StructureNode | undefined, info: IABAPFileInformation);
11
11
  getRaw(): string;
12
- getInfo(): IABAPFileInformation;
13
12
  getRawRows(): string[];
13
+ getInfo(): IABAPFileInformation;
14
14
  getStructure(): StructureNode | undefined;
15
15
  getTokens(withPragmas?: boolean): readonly Token[];
16
16
  getStatements(): readonly StatementNode[];
@@ -3073,6 +3073,13 @@ declare class HttpService extends AbstractObject {
3073
3073
  getDescription(): string | undefined;
3074
3074
  }
3075
3075
 
3076
+ export declare interface IABAPFile {
3077
+ getInfo(): IABAPFileInformation;
3078
+ getStructure(): StructureNode | undefined;
3079
+ getTokens(withPragmas?: boolean): readonly Token[];
3080
+ getStatements(): readonly StatementNode[];
3081
+ }
3082
+
3076
3083
  declare interface IABAPFileInformation {
3077
3084
  listInterfaceDefinitions(): readonly InfoInterfaceDefinition[];
3078
3085
  getInterfaceDefinitionByName(name: string): InfoInterfaceDefinition | undefined;
@@ -1,27 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ABAPFileInformation = void 0;
4
- const Structures = require("../3_structures/structures");
5
- const Expressions = require("../2_statements/expressions");
6
- const Statements = require("../2_statements/statements");
7
- const _abap_file_information_1 = require("./_abap_file_information");
8
- const _identifier_1 = require("./_identifier");
9
- const Tokens = require("../1_lexer/tokens");
10
- const visibility_1 = require("./visibility");
11
4
  class ABAPFileInformation {
12
- constructor(structure, filename) {
13
- this.forms = [];
14
- this.implementations = [];
15
- this.interfaces = [];
16
- this.classes = [];
17
- this.filename = filename;
18
- this.parse(structure);
5
+ constructor(parsed) {
6
+ this.parsed = parsed;
19
7
  }
20
8
  listClassImplementations() {
21
- return this.implementations;
9
+ return this.parsed.implementations;
22
10
  }
23
11
  listInterfaceDefinitions() {
24
- return this.interfaces;
12
+ return this.parsed.interfaces;
25
13
  }
26
14
  getInterfaceDefinitionByName(name) {
27
15
  const upper = name.toUpperCase();
@@ -33,7 +21,7 @@ class ABAPFileInformation {
33
21
  return undefined;
34
22
  }
35
23
  listClassDefinitions() {
36
- return this.classes;
24
+ return this.parsed.classes;
37
25
  }
38
26
  getClassDefinitionByName(name) {
39
27
  const upper = name.toUpperCase();
@@ -54,322 +42,7 @@ class ABAPFileInformation {
54
42
  return undefined;
55
43
  }
56
44
  listFormDefinitions() {
57
- return this.forms;
58
- }
59
- ///////////////////////
60
- parse(structure) {
61
- var _a;
62
- if (structure === undefined) {
63
- return;
64
- }
65
- this.parseClasses(structure);
66
- this.parseInterfaces(structure);
67
- for (const found of structure.findAllStructures(Structures.ClassImplementation)) {
68
- const methods = [];
69
- for (const method of found.findAllStructures(Structures.Method)) {
70
- const methodName = (_a = method.findFirstExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
71
- if (methodName) {
72
- methods.push(new _identifier_1.Identifier(methodName, this.filename));
73
- }
74
- }
75
- const name = found.findFirstStatement(Statements.ClassImplementation).findFirstExpression(Expressions.ClassName).getFirstToken();
76
- this.implementations.push({
77
- name: name.getStr(),
78
- identifier: new _identifier_1.Identifier(name, this.filename),
79
- methods,
80
- });
81
- }
82
- for (const statement of structure.findAllStructures(Structures.Form)) {
83
- // FORMs can contain a dash in the name
84
- const pos = statement.findFirstExpression(Expressions.FormName).getFirstToken().getStart();
85
- const name = statement.findFirstExpression(Expressions.FormName).concatTokens();
86
- const nameToken = new Tokens.Identifier(pos, name);
87
- this.forms.push({
88
- name: nameToken.getStr(),
89
- identifier: new _identifier_1.Identifier(nameToken, this.filename),
90
- });
91
- }
92
- }
93
- parseInterfaces(structure) {
94
- for (const found of structure.findDirectStructures(Structures.Interface)) {
95
- const i = found.findFirstStatement(Statements.Interface);
96
- if (i === undefined) {
97
- throw new Error("Interface expected, parseInterfaces");
98
- }
99
- const interfaceName = i.findDirectExpression(Expressions.InterfaceName).getFirstToken();
100
- const methods = this.parseMethodDefinition(found, visibility_1.Visibility.Public);
101
- const attributes = this.parseAttributes(found, visibility_1.Visibility.Public);
102
- const aliases = this.parseAliases(found, visibility_1.Visibility.Public);
103
- const constants = this.parseConstants(found, visibility_1.Visibility.Public);
104
- const g = i.findDirectExpression(Expressions.ClassGlobal);
105
- this.interfaces.push({
106
- name: interfaceName.getStr(),
107
- identifier: new _identifier_1.Identifier(interfaceName, this.filename),
108
- isLocal: g === undefined,
109
- isGlobal: g !== undefined,
110
- interfaces: this.getImplementing(found),
111
- aliases,
112
- methods,
113
- constants,
114
- attributes,
115
- });
116
- }
117
- }
118
- parseClasses(structure) {
119
- var _a;
120
- for (const found of structure.findAllStructures(Structures.ClassDefinition)) {
121
- const className = found.findFirstStatement(Statements.ClassDefinition).findFirstExpression(Expressions.ClassName).getFirstToken();
122
- const methods = this.parseMethodDefinition(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
123
- methods.push(...this.parseMethodDefinition(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
124
- methods.push(...this.parseMethodDefinition(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
125
- const attributes = this.parseAttributes(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
126
- attributes.push(...this.parseAttributes(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
127
- attributes.push(...this.parseAttributes(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
128
- const aliases = this.parseAliases(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
129
- aliases.push(...this.parseAliases(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
130
- aliases.push(...this.parseAliases(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
131
- const constants = this.parseConstants(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
132
- constants.push(...this.parseConstants(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
133
- constants.push(...this.parseConstants(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
134
- const superClassName = (_a = found.findFirstExpression(Expressions.SuperClassName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
135
- const containsGlobal = found.findFirstExpression(Expressions.ClassGlobal);
136
- const cdef = found.findFirstStatement(Statements.ClassDefinition);
137
- const concat = (cdef === null || cdef === void 0 ? void 0 : cdef.concatTokens().toUpperCase()) || "";
138
- let riskLevel;
139
- if (concat.includes("RISK LEVEL CRITICAL")) {
140
- riskLevel = _abap_file_information_1.RiskLevel.critical;
141
- }
142
- else if (concat.includes("RISK LEVEL DANGEROUS")) {
143
- riskLevel = _abap_file_information_1.RiskLevel.dangerous;
144
- }
145
- else if (concat.includes("RISK LEVEL HARMLESS")) {
146
- riskLevel = _abap_file_information_1.RiskLevel.harmless;
147
- }
148
- let duration;
149
- if (concat.includes("DURATION SHORT")) {
150
- duration = _abap_file_information_1.Duration.short;
151
- }
152
- else if (concat.includes("DURATION LONG")) {
153
- duration = _abap_file_information_1.Duration.long;
154
- }
155
- else if (concat.includes("DURATION MEDIUM")) {
156
- duration = _abap_file_information_1.Duration.medium;
157
- }
158
- this.classes.push({
159
- name: className.getStr(),
160
- identifier: new _identifier_1.Identifier(className, this.filename),
161
- isLocal: containsGlobal === undefined,
162
- isGlobal: containsGlobal !== undefined,
163
- methods,
164
- superClassName,
165
- interfaces: this.getImplementing(found),
166
- isForTesting: concat.includes(" FOR TESTING"),
167
- duration,
168
- riskLevel,
169
- isAbstract: (cdef === null || cdef === void 0 ? void 0 : cdef.findDirectTokenByText("ABSTRACT")) !== undefined,
170
- isSharedMemory: concat.includes(" SHARED MEMORY ENABLED"),
171
- isFinal: found.findFirstExpression(Expressions.ClassFinal) !== undefined,
172
- aliases,
173
- attributes,
174
- constants,
175
- });
176
- }
177
- }
178
- ///////////////////
179
- getImplementing(input) {
180
- const ret = [];
181
- for (const node of input.findAllStatements(Statements.InterfaceDef)) {
182
- const abstract = node.findDirectExpression(Expressions.AbstractMethods);
183
- const abstractMethods = [];
184
- if (abstract) {
185
- for (const m of abstract.findDirectExpressions(Expressions.MethodName)) {
186
- abstractMethods.push(m.concatTokens().toUpperCase());
187
- }
188
- }
189
- const final = node.findDirectExpression(Expressions.FinalMethods);
190
- const finalMethods = [];
191
- if (final) {
192
- for (const m of final.findDirectExpressions(Expressions.MethodName)) {
193
- finalMethods.push(m.concatTokens().toUpperCase());
194
- }
195
- }
196
- const concat = node.concatTokens().toUpperCase();
197
- const allAbstract = concat.includes(" ALL METHODS ABSTRACT");
198
- const partial = concat.includes(" PARTIALLY IMPLEMENTED");
199
- const name = node.findFirstExpression(Expressions.InterfaceName).getFirstToken().getStr().toUpperCase();
200
- ret.push({
201
- name,
202
- partial,
203
- allAbstract,
204
- abstractMethods,
205
- finalMethods,
206
- });
207
- }
208
- return ret;
209
- }
210
- parseAliases(node, visibility) {
211
- if (node === undefined) {
212
- return [];
213
- }
214
- const ret = [];
215
- for (const a of node.findAllStatements(Statements.Aliases)) {
216
- const name = a.findFirstExpression(Expressions.SimpleName).getFirstToken();
217
- const comp = a.findFirstExpression(Expressions.Field).getFirstToken();
218
- ret.push({
219
- name: name.getStr(),
220
- identifier: new _identifier_1.Identifier(name, this.filename),
221
- visibility,
222
- component: comp.getStr(),
223
- });
224
- }
225
- return ret;
226
- }
227
- parseConstants(node, visibility) {
228
- var _a, _b;
229
- if (node === undefined) {
230
- return [];
231
- }
232
- const results = [];
233
- for (const constant of node.findAllStatements(Statements.Constant)) {
234
- const name = constant.findFirstExpression(Expressions.DefinitionName).getFirstToken();
235
- const typeName = constant.findFirstExpression(Expressions.TypeName);
236
- // VALUE `const_value` -> `const_value`
237
- const literal = (_b = (_a = constant.findFirstExpression(Expressions.Value)) === null || _a === void 0 ? void 0 : _a.getTokens()[1].getStr()) !== null && _b !== void 0 ? _b : "``";
238
- // `const_value` -> const_value
239
- const value = literal.slice(1, (literal === null || literal === void 0 ? void 0 : literal.length) - 1);
240
- results.push({
241
- name: name.getStr(),
242
- typeName: typeName ? typeName.getFirstToken().getStr() : "",
243
- value: value,
244
- identifier: new _identifier_1.Identifier(name, this.filename),
245
- visibility,
246
- });
247
- }
248
- return results;
249
- }
250
- parseAttributes(node, visibility) {
251
- if (node === undefined) {
252
- return [];
253
- }
254
- const contents = node.findFirstStructure(Structures.SectionContents);
255
- if (contents === undefined) {
256
- return [];
257
- }
258
- const ret = [];
259
- for (const d of contents.findDirectStatements(Statements.Data)) {
260
- const name = d.findFirstExpression(Expressions.DefinitionName).getFirstToken();
261
- ret.push({
262
- name: name.getStr(),
263
- identifier: new _identifier_1.Identifier(name, this.filename),
264
- level: _abap_file_information_1.AttributeLevel.Instance,
265
- readOnly: d.concatTokens().toUpperCase().includes(" READ-ONLY"),
266
- visibility,
267
- });
268
- }
269
- for (const d of contents.findDirectStatements(Statements.ClassData)) {
270
- const name = d.findFirstExpression(Expressions.DefinitionName).getFirstToken();
271
- ret.push({
272
- name: name.getStr(),
273
- identifier: new _identifier_1.Identifier(name, this.filename),
274
- level: _abap_file_information_1.AttributeLevel.Static,
275
- readOnly: d.concatTokens().toUpperCase().includes(" READ-ONLY"),
276
- visibility,
277
- });
278
- }
279
- for (const d of contents.findDirectStatements(Statements.Constant)) {
280
- const name = d.findFirstExpression(Expressions.DefinitionName).getFirstToken();
281
- ret.push({
282
- name: name.getStr(),
283
- identifier: new _identifier_1.Identifier(name, this.filename),
284
- level: _abap_file_information_1.AttributeLevel.Constant,
285
- readOnly: true,
286
- visibility,
287
- });
288
- }
289
- return ret;
290
- }
291
- parseMethodDefinition(node, visibility) {
292
- var _a;
293
- if (node === undefined) {
294
- return [];
295
- }
296
- const methods = [];
297
- for (const def of node.findAllStatements(Statements.MethodDef)) {
298
- const methodName = (_a = def.findDirectExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
299
- if (methodName === undefined) {
300
- continue;
301
- }
302
- const parameters = this.parseMethodParameters(def);
303
- methods.push({
304
- name: methodName.getStr(),
305
- identifier: new _identifier_1.Identifier(methodName, this.filename),
306
- isRedefinition: def.findDirectExpression(Expressions.Redefinition) !== undefined,
307
- isForTesting: def.concatTokens().toUpperCase().includes(" FOR TESTING"),
308
- isFinal: def.concatTokens().toUpperCase().includes(" FINAL"),
309
- isAbstract: def.findDirectExpression(Expressions.Abstract) !== undefined,
310
- isEventHandler: def.findDirectExpression(Expressions.EventHandler) !== undefined,
311
- visibility,
312
- parameters,
313
- exceptions: [], // todo
314
- });
315
- }
316
- return methods;
317
- }
318
- // todo, refactor this method, it is too long
319
- parseMethodParameters(node) {
320
- var _a, _b, _c, _d;
321
- const ret = [];
322
- const importing = node.findFirstExpression(Expressions.MethodDefImporting);
323
- if (importing) {
324
- for (const param of importing.findAllExpressions(Expressions.MethodParam)) {
325
- const name = (_a = param.findDirectExpression(Expressions.MethodParamName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
326
- if (name) {
327
- ret.push({
328
- name: name.getStr().replace("!", ""),
329
- identifier: new _identifier_1.Identifier(name, this.filename),
330
- direction: _abap_file_information_1.MethodParameterDirection.Importing,
331
- });
332
- }
333
- }
334
- }
335
- const exporting = node.findFirstExpression(Expressions.MethodDefExporting);
336
- if (exporting) {
337
- for (const param of exporting.findAllExpressions(Expressions.MethodParam)) {
338
- const name = (_b = param.findDirectExpression(Expressions.MethodParamName)) === null || _b === void 0 ? void 0 : _b.getFirstToken();
339
- if (name) {
340
- ret.push({
341
- name: name.getStr().replace("!", ""),
342
- identifier: new _identifier_1.Identifier(name, this.filename),
343
- direction: _abap_file_information_1.MethodParameterDirection.Exporting,
344
- });
345
- }
346
- }
347
- }
348
- const changing = node.findFirstExpression(Expressions.MethodDefChanging);
349
- if (changing) {
350
- for (const param of changing.findAllExpressions(Expressions.MethodParam)) {
351
- const name = (_c = param.findDirectExpression(Expressions.MethodParamName)) === null || _c === void 0 ? void 0 : _c.getFirstToken();
352
- if (name) {
353
- ret.push({
354
- name: name.getStr().replace("!", ""),
355
- identifier: new _identifier_1.Identifier(name, this.filename),
356
- direction: _abap_file_information_1.MethodParameterDirection.Changing,
357
- });
358
- }
359
- }
360
- }
361
- const returning = node.findFirstExpression(Expressions.MethodDefReturning);
362
- if (returning) {
363
- const name = (_d = returning.findDirectExpression(Expressions.MethodParamName)) === null || _d === void 0 ? void 0 : _d.getFirstToken();
364
- if (name) {
365
- ret.push({
366
- name: name.getStr().replace("!", ""),
367
- identifier: new _identifier_1.Identifier(name, this.filename),
368
- direction: _abap_file_information_1.MethodParameterDirection.Returning,
369
- });
370
- }
371
- }
372
- return ret;
45
+ return this.parsed.forms;
373
46
  }
374
47
  }
375
48
  exports.ABAPFileInformation = ABAPFileInformation;
@@ -0,0 +1,352 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ABAPFileInformationParser = void 0;
4
+ const Structures = require("../3_structures/structures");
5
+ const Expressions = require("../2_statements/expressions");
6
+ const Statements = require("../2_statements/statements");
7
+ const _identifier_1 = require("./_identifier");
8
+ const Tokens = require("../1_lexer/tokens");
9
+ const visibility_1 = require("./visibility");
10
+ const _abap_file_information_1 = require("./_abap_file_information");
11
+ class ABAPFileInformationParser {
12
+ constructor(filename) {
13
+ this.filename = filename;
14
+ }
15
+ parse(structure) {
16
+ const result = {
17
+ interfaces: [],
18
+ classes: [],
19
+ forms: [],
20
+ implementations: [],
21
+ };
22
+ if (structure === undefined) {
23
+ return result;
24
+ }
25
+ result.classes = this.parseClasses(structure);
26
+ result.interfaces = this.parseInterfaces(structure);
27
+ result.implementations = this.parseClassImplementations(structure);
28
+ result.forms = this.parseForms(structure);
29
+ return result;
30
+ }
31
+ parseClassImplementations(structure) {
32
+ var _a;
33
+ const implementations = [];
34
+ for (const found of structure.findAllStructures(Structures.ClassImplementation)) {
35
+ const methods = [];
36
+ for (const method of found.findAllStructures(Structures.Method)) {
37
+ const methodName = (_a = method.findFirstExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
38
+ if (methodName) {
39
+ methods.push(new _identifier_1.Identifier(methodName, this.filename));
40
+ }
41
+ }
42
+ const name = found.findFirstStatement(Statements.ClassImplementation).findFirstExpression(Expressions.ClassName).getFirstToken();
43
+ implementations.push({
44
+ name: name.getStr(),
45
+ identifier: new _identifier_1.Identifier(name, this.filename),
46
+ methods,
47
+ });
48
+ }
49
+ return implementations;
50
+ }
51
+ parseForms(structure) {
52
+ const forms = [];
53
+ for (const statement of structure.findAllStructures(Structures.Form)) {
54
+ // FORMs can contain a dash in the name
55
+ const pos = statement.findFirstExpression(Expressions.FormName).getFirstToken().getStart();
56
+ const name = statement.findFirstExpression(Expressions.FormName).concatTokens();
57
+ const nameToken = new Tokens.Identifier(pos, name);
58
+ forms.push({
59
+ name: nameToken.getStr(),
60
+ identifier: new _identifier_1.Identifier(nameToken, this.filename),
61
+ });
62
+ }
63
+ return forms;
64
+ }
65
+ parseInterfaces(structure) {
66
+ const interfaces = [];
67
+ for (const found of structure.findDirectStructures(Structures.Interface)) {
68
+ const i = found.findFirstStatement(Statements.Interface);
69
+ if (i === undefined) {
70
+ throw new Error("Interface expected, parseInterfaces");
71
+ }
72
+ const interfaceName = i.findDirectExpression(Expressions.InterfaceName).getFirstToken();
73
+ const methods = this.parseMethodDefinition(found, visibility_1.Visibility.Public);
74
+ const attributes = this.parseAttributes(found, visibility_1.Visibility.Public);
75
+ const aliases = this.parseAliases(found, visibility_1.Visibility.Public);
76
+ const constants = this.parseConstants(found, visibility_1.Visibility.Public);
77
+ const g = i.findDirectExpression(Expressions.ClassGlobal);
78
+ interfaces.push({
79
+ name: interfaceName.getStr(),
80
+ identifier: new _identifier_1.Identifier(interfaceName, this.filename),
81
+ isLocal: g === undefined,
82
+ isGlobal: g !== undefined,
83
+ interfaces: this.getImplementing(found),
84
+ aliases,
85
+ methods,
86
+ constants,
87
+ attributes,
88
+ });
89
+ }
90
+ return interfaces;
91
+ }
92
+ parseClasses(structure) {
93
+ var _a;
94
+ const classes = [];
95
+ for (const found of structure.findAllStructures(Structures.ClassDefinition)) {
96
+ const className = found.findFirstStatement(Statements.ClassDefinition).findFirstExpression(Expressions.ClassName).getFirstToken();
97
+ const methods = this.parseMethodDefinition(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
98
+ methods.push(...this.parseMethodDefinition(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
99
+ methods.push(...this.parseMethodDefinition(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
100
+ const attributes = this.parseAttributes(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
101
+ attributes.push(...this.parseAttributes(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
102
+ attributes.push(...this.parseAttributes(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
103
+ const aliases = this.parseAliases(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
104
+ aliases.push(...this.parseAliases(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
105
+ aliases.push(...this.parseAliases(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
106
+ const constants = this.parseConstants(found.findFirstStructure(Structures.PublicSection), visibility_1.Visibility.Public);
107
+ constants.push(...this.parseConstants(found.findFirstStructure(Structures.ProtectedSection), visibility_1.Visibility.Protected));
108
+ constants.push(...this.parseConstants(found.findFirstStructure(Structures.PrivateSection), visibility_1.Visibility.Private));
109
+ const superClassName = (_a = found.findFirstExpression(Expressions.SuperClassName)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
110
+ const containsGlobal = found.findFirstExpression(Expressions.ClassGlobal);
111
+ const cdef = found.findFirstStatement(Statements.ClassDefinition);
112
+ const concat = (cdef === null || cdef === void 0 ? void 0 : cdef.concatTokens().toUpperCase()) || "";
113
+ let riskLevel;
114
+ if (concat.includes("RISK LEVEL CRITICAL")) {
115
+ riskLevel = _abap_file_information_1.RiskLevel.critical;
116
+ }
117
+ else if (concat.includes("RISK LEVEL DANGEROUS")) {
118
+ riskLevel = _abap_file_information_1.RiskLevel.dangerous;
119
+ }
120
+ else if (concat.includes("RISK LEVEL HARMLESS")) {
121
+ riskLevel = _abap_file_information_1.RiskLevel.harmless;
122
+ }
123
+ let duration;
124
+ if (concat.includes("DURATION SHORT")) {
125
+ duration = _abap_file_information_1.Duration.short;
126
+ }
127
+ else if (concat.includes("DURATION LONG")) {
128
+ duration = _abap_file_information_1.Duration.long;
129
+ }
130
+ else if (concat.includes("DURATION MEDIUM")) {
131
+ duration = _abap_file_information_1.Duration.medium;
132
+ }
133
+ classes.push({
134
+ name: className.getStr(),
135
+ identifier: new _identifier_1.Identifier(className, this.filename),
136
+ isLocal: containsGlobal === undefined,
137
+ isGlobal: containsGlobal !== undefined,
138
+ methods,
139
+ superClassName,
140
+ interfaces: this.getImplementing(found),
141
+ isForTesting: concat.includes(" FOR TESTING"),
142
+ duration,
143
+ riskLevel,
144
+ isAbstract: (cdef === null || cdef === void 0 ? void 0 : cdef.findDirectTokenByText("ABSTRACT")) !== undefined,
145
+ isSharedMemory: concat.includes(" SHARED MEMORY ENABLED"),
146
+ isFinal: found.findFirstExpression(Expressions.ClassFinal) !== undefined,
147
+ aliases,
148
+ attributes,
149
+ constants,
150
+ });
151
+ }
152
+ return classes;
153
+ }
154
+ ///////////////////
155
+ getImplementing(input) {
156
+ const ret = [];
157
+ for (const node of input.findAllStatements(Statements.InterfaceDef)) {
158
+ const abstract = node.findDirectExpression(Expressions.AbstractMethods);
159
+ const abstractMethods = [];
160
+ if (abstract) {
161
+ for (const m of abstract.findDirectExpressions(Expressions.MethodName)) {
162
+ abstractMethods.push(m.concatTokens().toUpperCase());
163
+ }
164
+ }
165
+ const final = node.findDirectExpression(Expressions.FinalMethods);
166
+ const finalMethods = [];
167
+ if (final) {
168
+ for (const m of final.findDirectExpressions(Expressions.MethodName)) {
169
+ finalMethods.push(m.concatTokens().toUpperCase());
170
+ }
171
+ }
172
+ const concat = node.concatTokens().toUpperCase();
173
+ const allAbstract = concat.includes(" ALL METHODS ABSTRACT");
174
+ const partial = concat.includes(" PARTIALLY IMPLEMENTED");
175
+ const name = node.findFirstExpression(Expressions.InterfaceName).getFirstToken().getStr().toUpperCase();
176
+ ret.push({
177
+ name,
178
+ partial,
179
+ allAbstract,
180
+ abstractMethods,
181
+ finalMethods,
182
+ });
183
+ }
184
+ return ret;
185
+ }
186
+ parseAliases(node, visibility) {
187
+ if (node === undefined) {
188
+ return [];
189
+ }
190
+ const ret = [];
191
+ for (const a of node.findAllStatements(Statements.Aliases)) {
192
+ const name = a.findFirstExpression(Expressions.SimpleName).getFirstToken();
193
+ const comp = a.findFirstExpression(Expressions.Field).getFirstToken();
194
+ ret.push({
195
+ name: name.getStr(),
196
+ identifier: new _identifier_1.Identifier(name, this.filename),
197
+ visibility,
198
+ component: comp.getStr(),
199
+ });
200
+ }
201
+ return ret;
202
+ }
203
+ parseConstants(node, visibility) {
204
+ var _a, _b;
205
+ if (node === undefined) {
206
+ return [];
207
+ }
208
+ const results = [];
209
+ for (const constant of node.findAllStatements(Statements.Constant)) {
210
+ const name = constant.findFirstExpression(Expressions.DefinitionName).getFirstToken();
211
+ const typeName = constant.findFirstExpression(Expressions.TypeName);
212
+ // VALUE `const_value` -> `const_value`
213
+ const literal = (_b = (_a = constant.findFirstExpression(Expressions.Value)) === null || _a === void 0 ? void 0 : _a.getTokens()[1].getStr()) !== null && _b !== void 0 ? _b : "``";
214
+ // `const_value` -> const_value
215
+ const value = literal.slice(1, (literal === null || literal === void 0 ? void 0 : literal.length) - 1);
216
+ results.push({
217
+ name: name.getStr(),
218
+ typeName: typeName ? typeName.getFirstToken().getStr() : "",
219
+ value: value,
220
+ identifier: new _identifier_1.Identifier(name, this.filename),
221
+ visibility,
222
+ });
223
+ }
224
+ return results;
225
+ }
226
+ parseAttributes(node, visibility) {
227
+ if (node === undefined) {
228
+ return [];
229
+ }
230
+ const contents = node.findFirstStructure(Structures.SectionContents);
231
+ if (contents === undefined) {
232
+ return [];
233
+ }
234
+ const ret = [];
235
+ for (const d of contents.findDirectStatements(Statements.Data)) {
236
+ const name = d.findFirstExpression(Expressions.DefinitionName).getFirstToken();
237
+ ret.push({
238
+ name: name.getStr(),
239
+ identifier: new _identifier_1.Identifier(name, this.filename),
240
+ level: _abap_file_information_1.AttributeLevel.Instance,
241
+ readOnly: d.concatTokens().toUpperCase().includes(" READ-ONLY"),
242
+ visibility,
243
+ });
244
+ }
245
+ for (const d of contents.findDirectStatements(Statements.ClassData)) {
246
+ const name = d.findFirstExpression(Expressions.DefinitionName).getFirstToken();
247
+ ret.push({
248
+ name: name.getStr(),
249
+ identifier: new _identifier_1.Identifier(name, this.filename),
250
+ level: _abap_file_information_1.AttributeLevel.Static,
251
+ readOnly: d.concatTokens().toUpperCase().includes(" READ-ONLY"),
252
+ visibility,
253
+ });
254
+ }
255
+ for (const d of contents.findDirectStatements(Statements.Constant)) {
256
+ const name = d.findFirstExpression(Expressions.DefinitionName).getFirstToken();
257
+ ret.push({
258
+ name: name.getStr(),
259
+ identifier: new _identifier_1.Identifier(name, this.filename),
260
+ level: _abap_file_information_1.AttributeLevel.Constant,
261
+ readOnly: true,
262
+ visibility,
263
+ });
264
+ }
265
+ return ret;
266
+ }
267
+ parseMethodDefinition(node, visibility) {
268
+ var _a;
269
+ if (node === undefined) {
270
+ return [];
271
+ }
272
+ const methods = [];
273
+ for (const def of node.findAllStatements(Statements.MethodDef)) {
274
+ const methodName = (_a = def.findDirectExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
275
+ if (methodName === undefined) {
276
+ continue;
277
+ }
278
+ const parameters = this.parseMethodParameters(def);
279
+ methods.push({
280
+ name: methodName.getStr(),
281
+ identifier: new _identifier_1.Identifier(methodName, this.filename),
282
+ isRedefinition: def.findDirectExpression(Expressions.Redefinition) !== undefined,
283
+ isForTesting: def.concatTokens().toUpperCase().includes(" FOR TESTING"),
284
+ isFinal: def.concatTokens().toUpperCase().includes(" FINAL"),
285
+ isAbstract: def.findDirectExpression(Expressions.Abstract) !== undefined,
286
+ isEventHandler: def.findDirectExpression(Expressions.EventHandler) !== undefined,
287
+ visibility,
288
+ parameters,
289
+ exceptions: [], // todo
290
+ });
291
+ }
292
+ return methods;
293
+ }
294
+ // todo, refactor this method, it is too long
295
+ parseMethodParameters(node) {
296
+ var _a, _b, _c, _d;
297
+ const ret = [];
298
+ const importing = node.findFirstExpression(Expressions.MethodDefImporting);
299
+ if (importing) {
300
+ for (const param of importing.findAllExpressions(Expressions.MethodParam)) {
301
+ const name = (_a = param.findDirectExpression(Expressions.MethodParamName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
302
+ if (name) {
303
+ ret.push({
304
+ name: name.getStr().replace("!", ""),
305
+ identifier: new _identifier_1.Identifier(name, this.filename),
306
+ direction: _abap_file_information_1.MethodParameterDirection.Importing,
307
+ });
308
+ }
309
+ }
310
+ }
311
+ const exporting = node.findFirstExpression(Expressions.MethodDefExporting);
312
+ if (exporting) {
313
+ for (const param of exporting.findAllExpressions(Expressions.MethodParam)) {
314
+ const name = (_b = param.findDirectExpression(Expressions.MethodParamName)) === null || _b === void 0 ? void 0 : _b.getFirstToken();
315
+ if (name) {
316
+ ret.push({
317
+ name: name.getStr().replace("!", ""),
318
+ identifier: new _identifier_1.Identifier(name, this.filename),
319
+ direction: _abap_file_information_1.MethodParameterDirection.Exporting,
320
+ });
321
+ }
322
+ }
323
+ }
324
+ const changing = node.findFirstExpression(Expressions.MethodDefChanging);
325
+ if (changing) {
326
+ for (const param of changing.findAllExpressions(Expressions.MethodParam)) {
327
+ const name = (_c = param.findDirectExpression(Expressions.MethodParamName)) === null || _c === void 0 ? void 0 : _c.getFirstToken();
328
+ if (name) {
329
+ ret.push({
330
+ name: name.getStr().replace("!", ""),
331
+ identifier: new _identifier_1.Identifier(name, this.filename),
332
+ direction: _abap_file_information_1.MethodParameterDirection.Changing,
333
+ });
334
+ }
335
+ }
336
+ }
337
+ const returning = node.findFirstExpression(Expressions.MethodDefReturning);
338
+ if (returning) {
339
+ const name = (_d = returning.findDirectExpression(Expressions.MethodParamName)) === null || _d === void 0 ? void 0 : _d.getFirstToken();
340
+ if (name) {
341
+ ret.push({
342
+ name: name.getStr().replace("!", ""),
343
+ identifier: new _identifier_1.Identifier(name, this.filename),
344
+ direction: _abap_file_information_1.MethodParameterDirection.Returning,
345
+ });
346
+ }
347
+ }
348
+ return ret;
349
+ }
350
+ }
351
+ exports.ABAPFileInformationParser = ABAPFileInformationParser;
352
+ //# sourceMappingURL=abap_file_information_parser.js.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=parsed_file_information.js.map
@@ -15,12 +15,12 @@ class ABAPFile extends _abstract_file_1.AbstractFile {
15
15
  getRaw() {
16
16
  return this.file.getRaw();
17
17
  }
18
- getInfo() {
19
- return this.info;
20
- }
21
18
  getRawRows() {
22
19
  return this.file.getRawRows();
23
20
  }
21
+ getInfo() {
22
+ return this.info;
23
+ }
24
24
  getStructure() {
25
25
  return this.structure;
26
26
  }
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ABAPParser = void 0;
4
- const version_1 = require("../version");
4
+ const abap_file_1 = require("./abap_file");
5
+ const abap_file_information_1 = require("./4_file_information/abap_file_information");
6
+ const abap_file_information_parser_1 = require("./4_file_information/abap_file_information_parser");
5
7
  const lexer_1 = require("./1_lexer/lexer");
6
8
  const statement_parser_1 = require("./2_statements/statement_parser");
7
9
  const structure_parser_1 = require("./3_structures/structure_parser");
8
- const abap_file_information_1 = require("./4_file_information/abap_file_information");
9
- const abap_file_1 = require("./abap_file");
10
+ const version_1 = require("../version");
10
11
  class ABAPParser {
11
12
  constructor(version, globalMacros, reg) {
12
13
  this.version = version ? version : version_1.defaultVersion;
@@ -31,7 +32,9 @@ class ABAPParser {
31
32
  for (const f of statementResult) {
32
33
  const result = structure_parser_1.StructureParser.run(f);
33
34
  // 4: file information
34
- const info = new abap_file_information_1.ABAPFileInformation(result.node, f.file.getFilename());
35
+ const parser = new abap_file_information_parser_1.ABAPFileInformationParser(f.file.getFilename());
36
+ const parsed = parser.parse(result.node);
37
+ const info = new abap_file_information_1.ABAPFileInformation(parsed);
35
38
  output.push(new abap_file_1.ABAPFile(f.file, f.tokens, f.statements, result.node, info));
36
39
  issues.push(...result.issues);
37
40
  }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=iabap_file.js.map
@@ -27,6 +27,8 @@ class FunctionGroup extends _abap_object_1.ABAPObject {
27
27
  super.setDirty();
28
28
  this.includes = undefined;
29
29
  this.modules = undefined;
30
+ this.description = undefined;
31
+ this.dynpros = undefined;
30
32
  }
31
33
  getAllowedNaming() {
32
34
  return {
@@ -74,7 +74,7 @@ class Registry {
74
74
  }
75
75
  static abaplintVersion() {
76
76
  // magic, see build script "version.sh"
77
- return "2.114.0";
77
+ return "2.114.2";
78
78
  }
79
79
  getDDICReferences() {
80
80
  return this.ddicReferences;
@@ -52,7 +52,7 @@ ENDTRY.`,
52
52
  for (const statNode of file.getStatements()) {
53
53
  const statement = statNode.get();
54
54
  if (statement instanceof Statements.CallTransaction && !statNode.concatTokensWithoutStringsAndComments().toUpperCase().includes("WITH AUTHORITY-CHECK")) {
55
- issues.push(issue_1.Issue.atStatement(file, statNode, this.getMessage(), this.getMetadata().key));
55
+ issues.push(issue_1.Issue.atStatement(file, statNode, this.getMessage(), this.getMetadata().key, this.getConfig().severity));
56
56
  }
57
57
  }
58
58
  return issues;
@@ -8,6 +8,10 @@ const _irule_1 = require("./_irule");
8
8
  const objects_1 = require("../objects");
9
9
  const severity_1 = require("../severity");
10
10
  class CheckIncludeConf extends _basic_rule_config_1.BasicRuleConfig {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.allowUnused = false;
14
+ }
11
15
  }
12
16
  exports.CheckIncludeConf = CheckIncludeConf;
13
17
  class CheckInclude {
@@ -35,7 +39,7 @@ class CheckInclude {
35
39
  }
36
40
  initialize(reg) {
37
41
  this.reg = reg;
38
- this.graph = new include_graph_1.IncludeGraph(this.reg, this.getConfig().severity || severity_1.Severity.Error);
42
+ this.graph = new include_graph_1.IncludeGraph(this.reg, this.getConfig().severity || severity_1.Severity.Error, this.getConfig().allowUnused || false);
39
43
  return this;
40
44
  }
41
45
  run(obj) {
@@ -28,8 +28,7 @@ https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-us/abapstart-of-selectio
28
28
  tags: [_irule_1.RuleTag.SingleFile],
29
29
  badExample: `REPORT zfoo.
30
30
  WRITE 'hello'.`,
31
- goodExample: `
32
- START-OF-SELECTION.
31
+ goodExample: `START-OF-SELECTION.
33
32
  WRITE 'hello'.`,
34
33
  };
35
34
  }
@@ -18,7 +18,7 @@ class IndexCompletelyContained {
18
18
  key: "index_completely_contained",
19
19
  title: "Check if database table indexes are completely contained",
20
20
  shortDescription: `If indexes are completely contained in other indexes, they can be removed to improve performance.`,
21
- tags: [_irule_1.RuleTag.Performance],
21
+ tags: [_irule_1.RuleTag.Performance, _irule_1.RuleTag.SingleFile],
22
22
  };
23
23
  }
24
24
  initialize() {
@@ -60,11 +60,12 @@ class Graph {
60
60
  }
61
61
  }
62
62
  class IncludeGraph {
63
- constructor(reg, severity = severity_1.Severity.Error) {
63
+ constructor(reg, severity = severity_1.Severity.Error, allowUnused = false) {
64
64
  this.reg = reg;
65
65
  this.issues = [];
66
66
  this.graph = new Graph();
67
67
  this.severity = severity;
68
+ this.allowUnused = allowUnused;
68
69
  this.build();
69
70
  }
70
71
  listMainForInclude(filename) {
@@ -88,6 +89,7 @@ class IncludeGraph {
88
89
  }
89
90
  const v = this.graph.findVertexByFilename(file.getFilename());
90
91
  if (v !== undefined
92
+ && this.allowUnused === false
91
93
  && v.include === true
92
94
  && this.listMainForInclude(v.filename).length === 0) {
93
95
  const f = this.reg.getFileByName(v.filename);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.114.0",
3
+ "version": "2.114.2",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",