@abaplint/core 2.93.2 → 2.93.3
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/adhoc/lexer_performance.ts +17 -0
- package/build/abaplint.d.ts +8 -3
- package/build/adhoc/lexer_performance.d.ts +1 -0
- package/build/adhoc/lexer_performance.js +18 -0
- package/build/src/abap/1_lexer/lexer.js +2 -2
- package/build/src/index.js +3 -1
- package/build/src/objects/_unknown_object.js +1 -1
- package/build/src/registry.js +4 -97
- package/build/src/rules/parser_error.js +34 -26
- package/build/src/rules_runner.js +107 -0
- package/lexer_performance.abap +113325 -0
- package/package.json +3 -2
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {MemoryFile} from "../src";
|
|
2
|
+
import {Lexer} from "../src/abap/1_lexer/lexer";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
|
|
5
|
+
console.log("========================");
|
|
6
|
+
const file = new MemoryFile("abapgit.abap", fs.readFileSync("./lexer_performance.abap", "utf-8"));
|
|
7
|
+
|
|
8
|
+
let total = 0;
|
|
9
|
+
for (let i = 0; i < 10; i++) {
|
|
10
|
+
const before = Date.now();
|
|
11
|
+
const result = Lexer.run(file);
|
|
12
|
+
const runtime = Date.now() - before;
|
|
13
|
+
console.log("Runtime: " + runtime + "ms");
|
|
14
|
+
total += runtime;
|
|
15
|
+
console.log("Tokens: " + result.tokens.length);
|
|
16
|
+
}
|
|
17
|
+
console.log("Total: " + total);
|
package/build/abaplint.d.ts
CHANGED
|
@@ -4488,7 +4488,6 @@ export declare class Registry implements IRegistry {
|
|
|
4488
4488
|
private readonly dependencies;
|
|
4489
4489
|
private readonly references;
|
|
4490
4490
|
private conf;
|
|
4491
|
-
private issues;
|
|
4492
4491
|
constructor(conf?: IConfiguration);
|
|
4493
4492
|
static abaplintVersion(): string;
|
|
4494
4493
|
getDDICReferences(): IDDICReferences;
|
|
@@ -4519,8 +4518,6 @@ export declare class Registry implements IRegistry {
|
|
|
4519
4518
|
parseAsync(input?: IRunInput): Promise<this>;
|
|
4520
4519
|
private parsePrivate;
|
|
4521
4520
|
private isDirty;
|
|
4522
|
-
private runRules;
|
|
4523
|
-
private excludeIssues;
|
|
4524
4521
|
private findOrCreate;
|
|
4525
4522
|
private removeObject;
|
|
4526
4523
|
private find;
|
|
@@ -4602,6 +4599,14 @@ declare class RollbackEntities implements IStatement {
|
|
|
4602
4599
|
getMatcher(): IStatementRunnable;
|
|
4603
4600
|
}
|
|
4604
4601
|
|
|
4602
|
+
export declare class RulesRunner {
|
|
4603
|
+
private readonly reg;
|
|
4604
|
+
constructor(reg: IRegistry);
|
|
4605
|
+
objectsToCheck(objects: Iterable<IObject>): readonly IObject[];
|
|
4606
|
+
runRules(objects: Iterable<IObject>, input?: IRunInput): readonly Issue[];
|
|
4607
|
+
excludeIssues(issues: Issue[]): Issue[];
|
|
4608
|
+
}
|
|
4609
|
+
|
|
4605
4610
|
declare enum RuleTag {
|
|
4606
4611
|
Experimental = "Experimental",
|
|
4607
4612
|
DeprecationCandidate = "DeprecationCandidate",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const src_1 = require("../src");
|
|
4
|
+
const lexer_1 = require("../src/abap/1_lexer/lexer");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
console.log("========================");
|
|
7
|
+
const file = new src_1.MemoryFile("abapgit.abap", fs.readFileSync("./lexer_performance.abap", "utf-8"));
|
|
8
|
+
let total = 0;
|
|
9
|
+
for (let i = 0; i < 10; i++) {
|
|
10
|
+
const before = Date.now();
|
|
11
|
+
const result = lexer_1.Lexer.run(file);
|
|
12
|
+
const runtime = Date.now() - before;
|
|
13
|
+
console.log("Runtime: " + runtime + "ms");
|
|
14
|
+
total += runtime;
|
|
15
|
+
console.log("Tokens: " + result.tokens.length);
|
|
16
|
+
}
|
|
17
|
+
console.log("Total: " + total);
|
|
18
|
+
//# sourceMappingURL=lexer_performance.js.map
|
|
@@ -318,7 +318,7 @@ class Lexer {
|
|
|
318
318
|
&& buf.length > 1
|
|
319
319
|
&& current === "`"
|
|
320
320
|
&& aahead !== "``"
|
|
321
|
-
&& (buf.
|
|
321
|
+
&& (buf.split("`").length - 1) % 2 === 0
|
|
322
322
|
&& ahead !== "`") {
|
|
323
323
|
// end of ping
|
|
324
324
|
this.add();
|
|
@@ -341,7 +341,7 @@ class Lexer {
|
|
|
341
341
|
&& current === "'"
|
|
342
342
|
&& buf.length > 1
|
|
343
343
|
&& aahead !== "''"
|
|
344
|
-
&& (buf.
|
|
344
|
+
&& (buf.split("'").length - 1) % 2 === 0
|
|
345
345
|
&& ahead !== "'") {
|
|
346
346
|
// end of string
|
|
347
347
|
this.add();
|
package/build/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Severity = exports.Visibility = exports.Info = exports.Rename = exports.PrettyPrinter = exports.Position = exports.CurrentScope = exports.ABAPFile = exports.SpaghettiScope = exports.SyntaxLogic = exports.ABAPObject = exports.Tokens = exports.ExpressionsCDS = exports.CDSParser = exports.LanguageServerTypes = exports.DDLParser = exports.applyEditList = exports.applyEditSingle = exports.SpaghettiScopeNode = exports.AbstractFile = exports.Token = exports.ScopeType = exports.BasicTypes = exports.TypedIdentifier = exports.AbstractType = exports.VirtualPosition = exports.Comment = exports.Unknown = exports.Empty = exports.Identifier = exports.Nodes = exports.Types = exports.Expressions = exports.Statements = exports.Structures = exports.Objects = exports.ArtifactsRules = exports.ArtifactsObjects = exports.ArtifactsABAP = exports.BuiltIn = exports.MethodLengthStats = exports.LanguageServer = exports.Registry = exports.ReferenceType = exports.Version = exports.Config = exports.Issue = exports.MemoryFile = void 0;
|
|
3
|
+
exports.Severity = exports.Visibility = exports.Info = exports.Rename = exports.PrettyPrinter = exports.Position = exports.CurrentScope = exports.ABAPFile = exports.RulesRunner = exports.SpaghettiScope = exports.SyntaxLogic = exports.ABAPObject = exports.Tokens = exports.ExpressionsCDS = exports.CDSParser = exports.LanguageServerTypes = exports.DDLParser = exports.applyEditList = exports.applyEditSingle = exports.SpaghettiScopeNode = exports.AbstractFile = exports.Token = exports.ScopeType = exports.BasicTypes = exports.TypedIdentifier = exports.AbstractType = exports.VirtualPosition = exports.Comment = exports.Unknown = exports.Empty = exports.Identifier = exports.Nodes = exports.Types = exports.Expressions = exports.Statements = exports.Structures = exports.Objects = exports.ArtifactsRules = exports.ArtifactsObjects = exports.ArtifactsABAP = exports.BuiltIn = exports.MethodLengthStats = exports.LanguageServer = exports.Registry = exports.ReferenceType = exports.Version = exports.Config = exports.Issue = exports.MemoryFile = void 0;
|
|
4
4
|
const issue_1 = require("./issue");
|
|
5
5
|
Object.defineProperty(exports, "Issue", { enumerable: true, get: function () { return issue_1.Issue; } });
|
|
6
6
|
const config_1 = require("./config");
|
|
@@ -92,4 +92,6 @@ const ddl_parser_1 = require("./ddl/ddl_parser");
|
|
|
92
92
|
Object.defineProperty(exports, "DDLParser", { enumerable: true, get: function () { return ddl_parser_1.DDLParser; } });
|
|
93
93
|
const cds_parser_1 = require("./cds/cds_parser");
|
|
94
94
|
Object.defineProperty(exports, "CDSParser", { enumerable: true, get: function () { return cds_parser_1.CDSParser; } });
|
|
95
|
+
const rules_runner_1 = require("./rules_runner");
|
|
96
|
+
Object.defineProperty(exports, "RulesRunner", { enumerable: true, get: function () { return rules_runner_1.RulesRunner; } });
|
|
95
97
|
//# sourceMappingURL=index.js.map
|
|
@@ -26,7 +26,7 @@ class UnknownObject extends _abstract_object_1.AbstractObject {
|
|
|
26
26
|
const pos = new position_1.Position(1, 1);
|
|
27
27
|
const file = this.getFiles()[0];
|
|
28
28
|
const message = "Unknown object type, currently not supported in abaplint, open issue on github";
|
|
29
|
-
const issue = issue_1.Issue.atPosition(file, pos, message, "
|
|
29
|
+
const issue = issue_1.Issue.atPosition(file, pos, message, "parser_error", severity_1.Severity.Error);
|
|
30
30
|
return [issue];
|
|
31
31
|
}
|
|
32
32
|
}
|
package/build/src/registry.js
CHANGED
|
@@ -3,13 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Registry = void 0;
|
|
4
4
|
const config_1 = require("./config");
|
|
5
5
|
const artifacts_objects_1 = require("./artifacts_objects");
|
|
6
|
-
const artifacts_rules_1 = require("./artifacts_rules");
|
|
7
|
-
const skip_logic_1 = require("./skip_logic");
|
|
8
|
-
const _abap_object_1 = require("./objects/_abap_object");
|
|
9
6
|
const find_global_definitions_1 = require("./abap/5_syntax/global_definitions/find_global_definitions");
|
|
10
|
-
const syntax_1 = require("./abap/5_syntax/syntax");
|
|
11
7
|
const excludeHelper_1 = require("./utils/excludeHelper");
|
|
12
8
|
const ddic_references_1 = require("./ddic_references");
|
|
9
|
+
const rules_runner_1 = require("./rules_runner");
|
|
13
10
|
// todo, this should really be an instance in case there are multiple Registry'ies
|
|
14
11
|
class ParsingPerformance {
|
|
15
12
|
static clear() {
|
|
@@ -61,13 +58,12 @@ class Registry {
|
|
|
61
58
|
this.objects = {};
|
|
62
59
|
this.objectsByType = {};
|
|
63
60
|
this.dependencies = {};
|
|
64
|
-
this.issues = [];
|
|
65
61
|
this.conf = conf ? conf : config_1.Config.getDefault();
|
|
66
62
|
this.references = new ddic_references_1.DDICReferences();
|
|
67
63
|
}
|
|
68
64
|
static abaplintVersion() {
|
|
69
65
|
// magic, see build script "version.sh"
|
|
70
|
-
return "2.93.
|
|
66
|
+
return "2.93.3";
|
|
71
67
|
}
|
|
72
68
|
getDDICReferences() {
|
|
73
69
|
return this.references;
|
|
@@ -245,14 +241,14 @@ class Registry {
|
|
|
245
241
|
if (this.isDirty() === true) {
|
|
246
242
|
this.parse();
|
|
247
243
|
}
|
|
248
|
-
return this.runRules(input);
|
|
244
|
+
return new rules_runner_1.RulesRunner(this).runRules(this.getObjects(), input);
|
|
249
245
|
}
|
|
250
246
|
// todo, this will be changed to async sometime
|
|
251
247
|
findIssuesObject(iobj) {
|
|
252
248
|
if (this.isDirty() === true) {
|
|
253
249
|
this.parse();
|
|
254
250
|
}
|
|
255
|
-
return this.runRules(
|
|
251
|
+
return new rules_runner_1.RulesRunner(this).runRules([iobj]);
|
|
256
252
|
}
|
|
257
253
|
// todo, this will be changed to async sometime
|
|
258
254
|
parse() {
|
|
@@ -260,10 +256,8 @@ class Registry {
|
|
|
260
256
|
return this;
|
|
261
257
|
}
|
|
262
258
|
ParsingPerformance.clear();
|
|
263
|
-
this.issues = [];
|
|
264
259
|
for (const o of this.getObjects()) {
|
|
265
260
|
this.parsePrivate(o);
|
|
266
|
-
this.issues.push(...o.getParsingIssues());
|
|
267
261
|
}
|
|
268
262
|
new find_global_definitions_1.FindGlobalDefinitions(this).run();
|
|
269
263
|
return this;
|
|
@@ -275,11 +269,9 @@ class Registry {
|
|
|
275
269
|
}
|
|
276
270
|
ParsingPerformance.clear();
|
|
277
271
|
(_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(this.getObjectCount(false), "Lexing and parsing");
|
|
278
|
-
this.issues = [];
|
|
279
272
|
for (const o of this.getObjects()) {
|
|
280
273
|
await ((_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick("Lexing and parsing(" + this.conf.getVersion() + ") - " + o.getType() + " " + o.getName()));
|
|
281
274
|
this.parsePrivate(o);
|
|
282
|
-
this.issues.push(...o.getParsingIssues());
|
|
283
275
|
}
|
|
284
276
|
if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {
|
|
285
277
|
ParsingPerformance.output();
|
|
@@ -303,91 +295,6 @@ class Registry {
|
|
|
303
295
|
}
|
|
304
296
|
return false;
|
|
305
297
|
}
|
|
306
|
-
runRules(input, iobj) {
|
|
307
|
-
var _a, _b, _c, _d, _e, _f;
|
|
308
|
-
const rulePerformance = {};
|
|
309
|
-
const issues = this.issues.slice(0);
|
|
310
|
-
const objects = iobj ? [iobj] : this.getObjects();
|
|
311
|
-
const rules = this.conf.getEnabledRules();
|
|
312
|
-
const skipLogic = new skip_logic_1.SkipLogic(this);
|
|
313
|
-
(_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(iobj ? 1 : this.getObjectCount(false), "Run Syntax");
|
|
314
|
-
const check = [];
|
|
315
|
-
for (const obj of objects) {
|
|
316
|
-
(_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick("Run Syntax - " + obj.getName());
|
|
317
|
-
if (skipLogic.skip(obj) || this.isDependency(obj)) {
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
if (obj instanceof _abap_object_1.ABAPObject) {
|
|
321
|
-
new syntax_1.SyntaxLogic(this, obj).run();
|
|
322
|
-
}
|
|
323
|
-
check.push(obj);
|
|
324
|
-
}
|
|
325
|
-
(_c = input === null || input === void 0 ? void 0 : input.progress) === null || _c === void 0 ? void 0 : _c.set(rules.length, "Initialize Rules");
|
|
326
|
-
for (const rule of rules) {
|
|
327
|
-
(_d = input === null || input === void 0 ? void 0 : input.progress) === null || _d === void 0 ? void 0 : _d.tick("Initialize Rules - " + rule.getMetadata().key);
|
|
328
|
-
if (rule.initialize === undefined) {
|
|
329
|
-
throw new Error(rule.getMetadata().key + " missing initialize method");
|
|
330
|
-
}
|
|
331
|
-
rule.initialize(this);
|
|
332
|
-
rulePerformance[rule.getMetadata().key] = 0;
|
|
333
|
-
}
|
|
334
|
-
(_e = input === null || input === void 0 ? void 0 : input.progress) === null || _e === void 0 ? void 0 : _e.set(check.length, "Finding Issues");
|
|
335
|
-
for (const obj of check) {
|
|
336
|
-
(_f = input === null || input === void 0 ? void 0 : input.progress) === null || _f === void 0 ? void 0 : _f.tick("Finding Issues - " + obj.getType() + " " + obj.getName());
|
|
337
|
-
for (const rule of rules) {
|
|
338
|
-
const before = Date.now();
|
|
339
|
-
issues.push(...rule.run(obj));
|
|
340
|
-
const runtime = Date.now() - before;
|
|
341
|
-
rulePerformance[rule.getMetadata().key] = rulePerformance[rule.getMetadata().key] + runtime;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {
|
|
345
|
-
const perf = [];
|
|
346
|
-
for (const p in rulePerformance) {
|
|
347
|
-
if (rulePerformance[p] > 100) { // ignore rules if it takes less than 100ms
|
|
348
|
-
perf.push({ name: p, time: rulePerformance[p] });
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
perf.sort((a, b) => { return b.time - a.time; });
|
|
352
|
-
for (const p of perf) {
|
|
353
|
-
process.stderr.write("\t" + p.time + "ms\t" + p.name + "\n");
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
return this.excludeIssues(issues);
|
|
357
|
-
}
|
|
358
|
-
excludeIssues(issues) {
|
|
359
|
-
var _a;
|
|
360
|
-
const ret = issues;
|
|
361
|
-
const globalNoIssues = this.conf.getGlobal().noIssues || [];
|
|
362
|
-
const globalNoIssuesPatterns = globalNoIssues.map(x => new RegExp(x, "i"));
|
|
363
|
-
if (globalNoIssuesPatterns.length > 0) {
|
|
364
|
-
for (let i = ret.length - 1; i >= 0; i--) {
|
|
365
|
-
const filename = ret[i].getFilename();
|
|
366
|
-
if (excludeHelper_1.ExcludeHelper.isExcluded(filename, globalNoIssuesPatterns)) {
|
|
367
|
-
ret.splice(i, 1);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
// exclude issues, as now we know both the filename and issue key
|
|
372
|
-
for (const rule of artifacts_rules_1.ArtifactsRules.getRules()) {
|
|
373
|
-
const key = rule.getMetadata().key;
|
|
374
|
-
const ruleExclude = (_a = this.conf.readByKey(key, "exclude")) !== null && _a !== void 0 ? _a : [];
|
|
375
|
-
if (ruleExclude.length === 0) {
|
|
376
|
-
continue;
|
|
377
|
-
}
|
|
378
|
-
const ruleExcludePatterns = ruleExclude.map(x => new RegExp(x, "i"));
|
|
379
|
-
for (let i = ret.length - 1; i >= 0; i--) {
|
|
380
|
-
if (ret[i].getKey() !== key) {
|
|
381
|
-
continue;
|
|
382
|
-
}
|
|
383
|
-
const filename = ret[i].getFilename();
|
|
384
|
-
if (excludeHelper_1.ExcludeHelper.isExcluded(filename, ruleExcludePatterns)) {
|
|
385
|
-
ret.splice(i, 1);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
return ret;
|
|
390
|
-
}
|
|
391
298
|
findOrCreate(name, type) {
|
|
392
299
|
try {
|
|
393
300
|
return this.find(name, type);
|
|
@@ -3,17 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ParserError = exports.ParserErrorConf = void 0;
|
|
4
4
|
const issue_1 = require("../issue");
|
|
5
5
|
const _statement_1 = require("../abap/2_statements/statements/_statement");
|
|
6
|
-
const _abap_rule_1 = require("./_abap_rule");
|
|
7
6
|
const _basic_rule_config_1 = require("./_basic_rule_config");
|
|
8
7
|
const statement_parser_1 = require("../abap/2_statements/statement_parser");
|
|
9
8
|
const _irule_1 = require("./_irule");
|
|
10
9
|
const version_1 = require("../version");
|
|
10
|
+
const _abap_object_1 = require("../objects/_abap_object");
|
|
11
11
|
class ParserErrorConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
12
12
|
}
|
|
13
13
|
exports.ParserErrorConf = ParserErrorConf;
|
|
14
|
-
class ParserError
|
|
14
|
+
class ParserError {
|
|
15
15
|
constructor() {
|
|
16
|
-
super(...arguments);
|
|
17
16
|
this.conf = new ParserErrorConf();
|
|
18
17
|
}
|
|
19
18
|
getMetadata() {
|
|
@@ -26,36 +25,45 @@ See recognized syntax at https://syntax.abaplint.org`,
|
|
|
26
25
|
tags: [_irule_1.RuleTag.Syntax, _irule_1.RuleTag.SingleFile],
|
|
27
26
|
};
|
|
28
27
|
}
|
|
28
|
+
initialize(reg) {
|
|
29
|
+
this.reg = reg;
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
29
32
|
getConfig() {
|
|
30
33
|
return this.conf;
|
|
31
34
|
}
|
|
32
35
|
setConfig(conf) {
|
|
33
36
|
this.conf = conf;
|
|
34
37
|
}
|
|
35
|
-
|
|
38
|
+
run(obj) {
|
|
36
39
|
const issues = [];
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
40
|
+
issues.push(...obj.getParsingIssues());
|
|
41
|
+
if (obj instanceof _abap_object_1.ABAPObject) {
|
|
42
|
+
for (const file of obj.getABAPFiles()) {
|
|
43
|
+
for (const statement of file.getStatements()) {
|
|
44
|
+
if (!(statement.get() instanceof _statement_1.Unknown)) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (statement.getTokens().length > statement_parser_1.STATEMENT_MAX_TOKENS) {
|
|
48
|
+
const message = "Statement too long, refactor statement";
|
|
49
|
+
const issue = issue_1.Issue.atToken(file, statement.getTokens()[0], message, this.getMetadata().key, this.conf.severity);
|
|
50
|
+
issues.push(issue);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const tok = statement.getFirstToken();
|
|
54
|
+
const message = "Statement does not exist in ABAP" + this.reg.getConfig().getVersion() + "(or a parser error), \"" + tok.getStr() + "\"";
|
|
55
|
+
const issue = issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity);
|
|
56
|
+
issues.push(issue);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (this.reg.getConfig().getVersion() === version_1.Version.v700) {
|
|
60
|
+
for (const statement of file.getStatements()) {
|
|
61
|
+
if (statement.getPragmas().length > 0) {
|
|
62
|
+
const message = "Pragmas not allowed in v700";
|
|
63
|
+
const issue = issue_1.Issue.atStatement(file, statement, message, this.getMetadata().key, this.conf.severity);
|
|
64
|
+
issues.push(issue);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
59
67
|
}
|
|
60
68
|
}
|
|
61
69
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RulesRunner = void 0;
|
|
4
|
+
const syntax_1 = require("./abap/5_syntax/syntax");
|
|
5
|
+
const artifacts_rules_1 = require("./artifacts_rules");
|
|
6
|
+
const _abap_object_1 = require("./objects/_abap_object");
|
|
7
|
+
const skip_logic_1 = require("./skip_logic");
|
|
8
|
+
const excludeHelper_1 = require("./utils/excludeHelper");
|
|
9
|
+
class RulesRunner {
|
|
10
|
+
constructor(reg) {
|
|
11
|
+
this.reg = reg;
|
|
12
|
+
}
|
|
13
|
+
objectsToCheck(objects) {
|
|
14
|
+
const check = [];
|
|
15
|
+
const skipLogic = new skip_logic_1.SkipLogic(this.reg);
|
|
16
|
+
for (const obj of objects) {
|
|
17
|
+
if (skipLogic.skip(obj) || this.reg.isDependency(obj)) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
check.push(obj);
|
|
21
|
+
}
|
|
22
|
+
return check;
|
|
23
|
+
}
|
|
24
|
+
runRules(objects, input) {
|
|
25
|
+
var _a, _b, _c, _d, _e, _f;
|
|
26
|
+
const rulePerformance = {};
|
|
27
|
+
const issues = [];
|
|
28
|
+
const rules = this.reg.getConfig().getEnabledRules();
|
|
29
|
+
const check = this.objectsToCheck(objects);
|
|
30
|
+
// note: SyntaxLogic is cached, logic is run as first step in order
|
|
31
|
+
// not to penalize the performance of the first rule using SyntaxLogic information
|
|
32
|
+
(_a = input === null || input === void 0 ? void 0 : input.progress) === null || _a === void 0 ? void 0 : _a.set(check.length, "Run Syntax");
|
|
33
|
+
for (const obj of check) {
|
|
34
|
+
(_b = input === null || input === void 0 ? void 0 : input.progress) === null || _b === void 0 ? void 0 : _b.tick("Run Syntax - " + obj.getName());
|
|
35
|
+
if (obj instanceof _abap_object_1.ABAPObject) {
|
|
36
|
+
new syntax_1.SyntaxLogic(this.reg, obj).run();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
(_c = input === null || input === void 0 ? void 0 : input.progress) === null || _c === void 0 ? void 0 : _c.set(rules.length, "Initialize Rules");
|
|
40
|
+
for (const rule of rules) {
|
|
41
|
+
(_d = input === null || input === void 0 ? void 0 : input.progress) === null || _d === void 0 ? void 0 : _d.tick("Initialize Rules - " + rule.getMetadata().key);
|
|
42
|
+
if (rule.initialize === undefined) {
|
|
43
|
+
throw new Error(rule.getMetadata().key + " missing initialize method");
|
|
44
|
+
}
|
|
45
|
+
rule.initialize(this.reg);
|
|
46
|
+
rulePerformance[rule.getMetadata().key] = 0;
|
|
47
|
+
}
|
|
48
|
+
(_e = input === null || input === void 0 ? void 0 : input.progress) === null || _e === void 0 ? void 0 : _e.set(check.length, "Finding Issues");
|
|
49
|
+
for (const obj of check) {
|
|
50
|
+
(_f = input === null || input === void 0 ? void 0 : input.progress) === null || _f === void 0 ? void 0 : _f.tick("Finding Issues - " + obj.getType() + " " + obj.getName());
|
|
51
|
+
for (const rule of rules) {
|
|
52
|
+
const before = Date.now();
|
|
53
|
+
issues.push(...rule.run(obj));
|
|
54
|
+
const runtime = Date.now() - before;
|
|
55
|
+
rulePerformance[rule.getMetadata().key] = rulePerformance[rule.getMetadata().key] + runtime;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if ((input === null || input === void 0 ? void 0 : input.outputPerformance) === true) {
|
|
59
|
+
const perf = [];
|
|
60
|
+
for (const p in rulePerformance) {
|
|
61
|
+
if (rulePerformance[p] > 100) { // ignore rules if it takes less than 100ms
|
|
62
|
+
perf.push({ name: p, time: rulePerformance[p] });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
perf.sort((a, b) => { return b.time - a.time; });
|
|
66
|
+
for (const p of perf) {
|
|
67
|
+
process.stderr.write("\t" + p.time + "ms\t" + p.name + "\n");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return this.excludeIssues(issues);
|
|
71
|
+
}
|
|
72
|
+
excludeIssues(issues) {
|
|
73
|
+
var _a;
|
|
74
|
+
const ret = issues;
|
|
75
|
+
const globalNoIssues = this.reg.getConfig().getGlobal().noIssues || [];
|
|
76
|
+
const globalNoIssuesPatterns = globalNoIssues.map(x => new RegExp(x, "i"));
|
|
77
|
+
if (globalNoIssuesPatterns.length > 0) {
|
|
78
|
+
for (let i = ret.length - 1; i >= 0; i--) {
|
|
79
|
+
const filename = ret[i].getFilename();
|
|
80
|
+
if (excludeHelper_1.ExcludeHelper.isExcluded(filename, globalNoIssuesPatterns)) {
|
|
81
|
+
ret.splice(i, 1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// exclude issues, as now we know both the filename and issue key
|
|
86
|
+
for (const rule of artifacts_rules_1.ArtifactsRules.getRules()) {
|
|
87
|
+
const key = rule.getMetadata().key;
|
|
88
|
+
const ruleExclude = (_a = this.reg.getConfig().readByKey(key, "exclude")) !== null && _a !== void 0 ? _a : [];
|
|
89
|
+
if (ruleExclude.length === 0) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const ruleExcludePatterns = ruleExclude.map(x => new RegExp(x, "i"));
|
|
93
|
+
for (let i = ret.length - 1; i >= 0; i--) {
|
|
94
|
+
if (ret[i].getKey() !== key) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const filename = ret[i].getFilename();
|
|
98
|
+
if (excludeHelper_1.ExcludeHelper.isExcluded(filename, ruleExcludePatterns)) {
|
|
99
|
+
ret.splice(i, 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return ret;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.RulesRunner = RulesRunner;
|
|
107
|
+
//# sourceMappingURL=rules_runner.js.map
|