@abaplint/core 2.109.0 → 2.109.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.
@@ -3217,10 +3217,14 @@ declare interface ILookupResult {
3217
3217
  }
3218
3218
 
3219
3219
  declare interface IMacroReferences {
3220
- addDefinition(ref: IFilenameAndToken): void;
3220
+ addDefinition(ref: IFilenameAndToken, start: Position, end: Position): void;
3221
3221
  addReference(ref: IFilenameAndToken): void;
3222
- listDefinitionsByFile(filename: string): IFilenameAndToken[];
3222
+ listDefinitionsByFile(filename: string): Token[];
3223
3223
  listUsagesbyMacro(filename: string, token: Token): IFilenameAndToken[];
3224
+ getDefinitionPosition(filename: string, token: Token): {
3225
+ start: Position;
3226
+ end: Position;
3227
+ } | undefined;
3224
3228
  clear(filename: string): void;
3225
3229
  }
3226
3230
 
@@ -54,18 +54,22 @@ class ExpandMacros {
54
54
  this.globalMacros = globalMacros;
55
55
  this.reg = reg;
56
56
  }
57
- find(statements, file) {
57
+ find(statements, file, clear = true) {
58
58
  var _a, _b, _c;
59
59
  let nameToken = undefined;
60
+ let start = undefined;
60
61
  let contents = [];
61
62
  const macroReferences = (_a = this.reg) === null || _a === void 0 ? void 0 : _a.getMacroReferences();
62
- macroReferences === null || macroReferences === void 0 ? void 0 : macroReferences.clear(file.getFilename());
63
+ if (clear) {
64
+ macroReferences === null || macroReferences === void 0 ? void 0 : macroReferences.clear(file.getFilename());
65
+ }
63
66
  for (let i = 0; i < statements.length; i++) {
64
67
  const statement = statements[i];
65
68
  const type = statement.get();
66
69
  if (type instanceof Statements.Define) {
67
70
  // todo, will this break if first token is a pragma?
68
71
  nameToken = statement.getTokens()[1];
72
+ start = statement.getFirstToken().getStart();
69
73
  contents = [];
70
74
  }
71
75
  else if (type instanceof Statements.Include) {
@@ -77,14 +81,14 @@ class ExpandMacros {
77
81
  const includeMainFile = prog.getMainABAPFile();
78
82
  if (includeMainFile) {
79
83
  // slow, this copies everything,
80
- this.find([...includeMainFile.getStatements()], includeMainFile);
84
+ this.find([...includeMainFile.getStatements()], includeMainFile, false);
81
85
  }
82
86
  }
83
87
  }
84
88
  else if (nameToken) {
85
89
  if (type instanceof Statements.EndOfDefinition) {
86
90
  this.macros.addMacro(nameToken.getStr(), contents, file.getFilename());
87
- macroReferences === null || macroReferences === void 0 ? void 0 : macroReferences.addDefinition({ filename: file.getFilename(), token: nameToken });
91
+ macroReferences === null || macroReferences === void 0 ? void 0 : macroReferences.addDefinition({ filename: file.getFilename(), token: nameToken }, start, statement.getLastToken().getEnd());
88
92
  nameToken = undefined;
89
93
  }
90
94
  else if (!(type instanceof _statement_1.Comment)) {
@@ -7,6 +7,7 @@ const LServer = require("vscode-languageserver-types");
7
7
  const _abap_object_1 = require("../objects/_abap_object");
8
8
  const _lsp_utils_1 = require("./_lsp_utils");
9
9
  const _lookup_1 = require("./_lookup");
10
+ const _statement_1 = require("../abap/2_statements/statements/_statement");
10
11
  class Hover {
11
12
  constructor(reg) {
12
13
  this.reg = reg;
@@ -30,6 +31,9 @@ class Hover {
30
31
  || found.token instanceof Tokens.StringTemplateMiddle) {
31
32
  return { kind: LServer.MarkupKind.Markdown, value: "String Template" };
32
33
  }
34
+ else if (found.snode.get() instanceof _statement_1.MacroCall) {
35
+ return { kind: LServer.MarkupKind.Markdown, value: "Macro Call" };
36
+ }
33
37
  else if (found.snode.get() instanceof Statements.Define && found.stack.length === 2) {
34
38
  return { kind: LServer.MarkupKind.Markdown, value: "Macro Name" };
35
39
  }
@@ -6,11 +6,22 @@ class MacroReferences {
6
6
  this.definitions = {};
7
7
  this.references = {};
8
8
  }
9
- addDefinition(ref) {
9
+ addDefinition(ref, start, end) {
10
10
  if (this.definitions[ref.filename] === undefined) {
11
11
  this.definitions[ref.filename] = [];
12
12
  }
13
- this.definitions[ref.filename].push(ref);
13
+ else if (this.definitions[ref.filename].find((d) => d.token.getStart().equals(ref.token.getStart()))) {
14
+ return;
15
+ }
16
+ this.definitions[ref.filename].push({ token: ref.token, start, end });
17
+ }
18
+ getDefinitionPosition(filename, token) {
19
+ for (const d of this.definitions[filename] || []) {
20
+ if (d.token.getStart().equals(token.getStart())) {
21
+ return { start: d.start, end: d.end };
22
+ }
23
+ }
24
+ return undefined;
14
25
  }
15
26
  addReference(ref) {
16
27
  if (this.references[ref.filename] === undefined) {
@@ -19,7 +30,11 @@ class MacroReferences {
19
30
  this.references[ref.filename].push(ref);
20
31
  }
21
32
  listDefinitionsByFile(filename) {
22
- return this.definitions[filename] || [];
33
+ const ret = [];
34
+ for (const d of this.definitions[filename] || []) {
35
+ ret.push(d.token);
36
+ }
37
+ return ret;
23
38
  }
24
39
  listUsagesbyMacro(filename, token) {
25
40
  const ret = [];
@@ -67,7 +67,7 @@ class Registry {
67
67
  }
68
68
  static abaplintVersion() {
69
69
  // magic, see build script "version.sh"
70
- return "2.109.0";
70
+ return "2.109.2";
71
71
  }
72
72
  getDDICReferences() {
73
73
  return this.ddicReferences;
@@ -5,6 +5,7 @@ const issue_1 = require("../issue");
5
5
  const _basic_rule_config_1 = require("./_basic_rule_config");
6
6
  const _irule_1 = require("./_irule");
7
7
  const _abap_object_1 = require("../objects/_abap_object");
8
+ const edit_helper_1 = require("../edit_helper");
8
9
  class UnusedMacrosConf extends _basic_rule_config_1.BasicRuleConfig {
9
10
  constructor() {
10
11
  super(...arguments);
@@ -25,6 +26,14 @@ class UnusedMacros {
25
26
  title: "Unused macros",
26
27
  shortDescription: `Checks for unused macro definitions definitions`,
27
28
  tags: [_irule_1.RuleTag.Quickfix],
29
+ badExample: `DEFINE foobar1.
30
+ WRITE 'hello'.
31
+ END-OF-DEFINITION.`,
32
+ goodExample: `DEFINE foobar2.
33
+ WRITE 'hello'.
34
+ END-OF-DEFINITION.
35
+
36
+ foobar2.`,
28
37
  };
29
38
  }
30
39
  getConfig() {
@@ -48,11 +57,13 @@ class UnusedMacros {
48
57
  }
49
58
  const references = this.reg.getMacroReferences();
50
59
  for (const file of obj.getABAPFiles()) {
51
- for (const macro of references.listDefinitionsByFile(file.getFilename())) {
52
- const usages = references.listUsagesbyMacro(file.getFilename(), macro.token);
53
- if (usages.length === 0 && ((_a = this.conf.skipNames) === null || _a === void 0 ? void 0 : _a.includes(macro.token.getStr().toUpperCase())) === false) {
54
- const message = "Unused macro definition: " + macro.token.getStr();
55
- result.push(issue_1.Issue.atToken(file, macro.token, message, this.getMetadata().key, this.conf.severity));
60
+ for (const macroToken of references.listDefinitionsByFile(file.getFilename())) {
61
+ const usages = references.listUsagesbyMacro(file.getFilename(), macroToken);
62
+ if (usages.length === 0 && ((_a = this.conf.skipNames) === null || _a === void 0 ? void 0 : _a.includes(macroToken.getStr().toUpperCase())) === false) {
63
+ const message = "Unused macro definition: " + macroToken.getStr();
64
+ const pos = references.getDefinitionPosition(file.getFilename(), macroToken);
65
+ const fix = edit_helper_1.EditHelper.deleteRange(file, pos.start, pos.end);
66
+ result.push(issue_1.Issue.atToken(file, macroToken, message, this.getMetadata().key, this.conf.severity, fix));
56
67
  }
57
68
  }
58
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/core",
3
- "version": "2.109.0",
3
+ "version": "2.109.2",
4
4
  "description": "abaplint - Core API",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/abaplint.d.ts",