Skip to content

Commit f80a9e1

Browse files
authored
fix: no-*-definitions rules show original label and identifier (#515)
* fix: no-*-definitions rules show original label instead of normalized identifier * expose identifier and label in message * refactor no-duplicate-definitions
1 parent a90e4cd commit f80a9e1

File tree

6 files changed

+249
-61
lines changed

6 files changed

+249
-61
lines changed

src/rules/no-duplicate-definitions.js

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { normalizeIdentifier } from "micromark-util-normalize-identifier";
1414
//-----------------------------------------------------------------------------
1515

1616
/**
17+
* @import { Definition, FootnoteDefinition } from "mdast";
1718
* @import { MarkdownRuleDefinition } from "../types.js";
1819
* @typedef {"duplicateDefinition" | "duplicateFootnoteDefinition"} NoDuplicateDefinitionsMessageIds
1920
* @typedef {[{ allowDefinitions?: string[], allowFootnoteDefinitions?: string[] }]} NoDuplicateDefinitionsOptions
@@ -37,9 +38,9 @@ export default {
3738

3839
messages: {
3940
duplicateDefinition:
40-
"Unexpected duplicate definition `{{ identifier }}` found.",
41+
"Unexpected duplicate definition `{{ identifier }}` (label: `{{ label }}`) found. First defined at line {{ firstLine }} (label: `{{ firstLabel }}`).",
4142
duplicateFootnoteDefinition:
42-
"Unexpected duplicate footnote definition `{{ identifier }}` found.",
43+
"Unexpected duplicate footnote definition `{{ identifier }}` (label: `{{ label }}`) found. First defined at line {{ firstLine }} (label: `{{ firstLabel }}`).",
4344
},
4445

4546
schema: [
@@ -85,11 +86,11 @@ export default {
8586
),
8687
);
8788

88-
/** @type {Set<string>} */
89-
const definitions = new Set();
89+
/** @type {Map<string, Definition>} */
90+
const definitions = new Map();
9091

91-
/** @type {Set<string>} */
92-
const footnoteDefinitions = new Set();
92+
/** @type {Map<string, FootnoteDefinition>} */
93+
const footnoteDefinitions = new Map();
9394

9495
return {
9596
definition(node) {
@@ -98,13 +99,22 @@ export default {
9899
}
99100

100101
if (definitions.has(node.identifier)) {
102+
const firstDefinitionNode = definitions.get(
103+
node.identifier,
104+
);
101105
context.report({
102106
node,
103107
messageId: "duplicateDefinition",
104-
data: { identifier: node.identifier },
108+
data: {
109+
identifier: node.identifier,
110+
label: node.label.trim(),
111+
firstLine:
112+
firstDefinitionNode.position.start.line.toString(),
113+
firstLabel: firstDefinitionNode.label.trim(),
114+
},
105115
});
106116
} else {
107-
definitions.add(node.identifier);
117+
definitions.set(node.identifier, node);
108118
}
109119
},
110120

@@ -114,13 +124,22 @@ export default {
114124
}
115125

116126
if (footnoteDefinitions.has(node.identifier)) {
127+
const firstFootnoteDefinitionNode = footnoteDefinitions.get(
128+
node.identifier,
129+
);
117130
context.report({
118131
node,
119132
messageId: "duplicateFootnoteDefinition",
120-
data: { identifier: node.identifier },
133+
data: {
134+
identifier: node.identifier,
135+
label: node.label,
136+
firstLine:
137+
firstFootnoteDefinitionNode.position.start.line.toString(),
138+
firstLabel: firstFootnoteDefinitionNode.label,
139+
},
121140
});
122141
} else {
123-
footnoteDefinitions.add(node.identifier);
142+
footnoteDefinitions.set(node.identifier, node);
124143
}
125144
},
126145
};

src/rules/no-empty-definitions.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ export default {
5353

5454
messages: {
5555
emptyDefinition:
56-
"Unexpected empty definition `{{ identifier }}` found.",
56+
"Unexpected empty definition `{{ identifier }}` (label: `{{ label }}`) found.",
5757
emptyFootnoteDefinition:
58-
"Unexpected empty footnote definition `{{ identifier }}` found.",
58+
"Unexpected empty footnote definition `{{ identifier }}` (label: `{{ label }}`) found.",
5959
},
6060

6161
schema: [
@@ -115,7 +115,10 @@ export default {
115115
context.report({
116116
loc: node.position,
117117
messageId: "emptyDefinition",
118-
data: { identifier: node.identifier },
118+
data: {
119+
identifier: node.identifier,
120+
label: node.label.trim(),
121+
},
119122
});
120123
}
121124
},
@@ -134,7 +137,10 @@ export default {
134137
context.report({
135138
loc: node.position,
136139
messageId: "emptyFootnoteDefinition",
137-
data: { identifier: node.identifier },
140+
data: {
141+
identifier: node.identifier,
142+
label: node.label,
143+
},
138144
});
139145
}
140146
},

src/rules/no-unused-definitions.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ export default {
3838

3939
messages: {
4040
unusedDefinition:
41-
"Unexpected unused definition `{{ identifier }}` found.",
41+
"Unexpected unused definition `{{ identifier }}` (label: `{{ label }}`) found.",
4242
unusedFootnoteDefinition:
43-
"Unexpected unused footnote definition `{{ identifier }}` found.",
43+
"Unexpected unused footnote definition `{{ identifier }}` (label: `{{ label }}`) found.",
4444
},
4545

4646
schema: [
@@ -130,7 +130,10 @@ export default {
130130
context.report({
131131
node: definition,
132132
messageId: "unusedDefinition",
133-
data: { identifier: definition.identifier },
133+
data: {
134+
identifier: definition.identifier,
135+
label: definition.label.trim(),
136+
},
134137
});
135138
}
136139
}
@@ -144,7 +147,10 @@ export default {
144147
context.report({
145148
node: footnoteDefinition,
146149
messageId: "unusedFootnoteDefinition",
147-
data: { identifier: footnoteDefinition.identifier },
150+
data: {
151+
identifier: footnoteDefinition.identifier,
152+
label: footnoteDefinition.label,
153+
},
148154
});
149155
}
150156
}

tests/rules/no-duplicate-definitions.test.js

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,12 @@ ruleTester.run("no-duplicate-definitions", rule, {
185185
errors: [
186186
{
187187
messageId: "duplicateDefinition",
188-
data: { identifier: "mercury" },
188+
data: {
189+
identifier: "mercury",
190+
label: "mercury",
191+
firstLine: "2",
192+
firstLabel: "mercury",
193+
},
189194
line: 3,
190195
column: 1,
191196
endLine: 3,
@@ -204,23 +209,38 @@ ruleTester.run("no-duplicate-definitions", rule, {
204209
errors: [
205210
{
206211
messageId: "duplicateDefinition",
207-
data: { identifier: "mercury" },
212+
data: {
213+
identifier: "mercury",
214+
label: "mercury",
215+
firstLine: "2",
216+
firstLabel: "mercury",
217+
},
208218
line: 3,
209219
column: 1,
210220
endLine: 3,
211221
endColumn: 38,
212222
},
213223
{
214224
messageId: "duplicateDefinition",
215-
data: { identifier: "mercury" },
225+
data: {
226+
identifier: "mercury",
227+
label: "mercury",
228+
firstLine: "2",
229+
firstLabel: "mercury",
230+
},
216231
line: 4,
217232
column: 1,
218233
endLine: 4,
219234
endColumn: 38,
220235
},
221236
{
222237
messageId: "duplicateDefinition",
223-
data: { identifier: "mercury" },
238+
data: {
239+
identifier: "mercury",
240+
label: "mercury",
241+
firstLine: "2",
242+
firstLabel: "mercury",
243+
},
224244
line: 5,
225245
column: 1,
226246
endLine: 5,
@@ -237,7 +257,12 @@ ruleTester.run("no-duplicate-definitions", rule, {
237257
errors: [
238258
{
239259
messageId: "duplicateDefinition",
240-
data: { identifier: "mercury" },
260+
data: {
261+
identifier: "mercury",
262+
label: "Mercury",
263+
firstLine: "2",
264+
firstLabel: "mercury",
265+
},
241266
line: 3,
242267
column: 1,
243268
endLine: 3,
@@ -254,7 +279,12 @@ ruleTester.run("no-duplicate-definitions", rule, {
254279
errors: [
255280
{
256281
messageId: "duplicateDefinition",
257-
data: { identifier: "mercury" },
282+
data: {
283+
identifier: "mercury",
284+
label: "mercury",
285+
firstLine: "2",
286+
firstLabel: "mercury",
287+
},
258288
line: 3,
259289
column: 1,
260290
endLine: 3,
@@ -278,7 +308,12 @@ ruleTester.run("no-duplicate-definitions", rule, {
278308
errors: [
279309
{
280310
messageId: "duplicateDefinition",
281-
data: { identifier: "mercury" },
311+
data: {
312+
identifier: "mercury",
313+
label: "mercury",
314+
firstLine: "2",
315+
firstLabel: "mercury",
316+
},
282317
line: 3,
283318
column: 1,
284319
endLine: 3,
@@ -295,7 +330,12 @@ ruleTester.run("no-duplicate-definitions", rule, {
295330
errors: [
296331
{
297332
messageId: "duplicateFootnoteDefinition",
298-
data: { identifier: "mercury" },
333+
data: {
334+
identifier: "mercury",
335+
label: "mercury",
336+
firstLine: "2",
337+
firstLabel: "mercury",
338+
},
299339
line: 3,
300340
column: 1,
301341
endLine: 3,
@@ -314,23 +354,38 @@ ruleTester.run("no-duplicate-definitions", rule, {
314354
errors: [
315355
{
316356
messageId: "duplicateFootnoteDefinition",
317-
data: { identifier: "mercury" },
357+
data: {
358+
identifier: "mercury",
359+
label: "mercury",
360+
firstLine: "2",
361+
firstLabel: "mercury",
362+
},
318363
line: 3,
319364
column: 1,
320365
endLine: 3,
321366
endColumn: 26,
322367
},
323368
{
324369
messageId: "duplicateFootnoteDefinition",
325-
data: { identifier: "mercury" },
370+
data: {
371+
identifier: "mercury",
372+
label: "mercury",
373+
firstLine: "2",
374+
firstLabel: "mercury",
375+
},
326376
line: 4,
327377
column: 1,
328378
endLine: 4,
329379
endColumn: 26,
330380
},
331381
{
332382
messageId: "duplicateFootnoteDefinition",
333-
data: { identifier: "mercury" },
383+
data: {
384+
identifier: "mercury",
385+
label: "mercury",
386+
firstLine: "2",
387+
firstLabel: "mercury",
388+
},
334389
line: 5,
335390
column: 1,
336391
endLine: 5,
@@ -347,7 +402,12 @@ ruleTester.run("no-duplicate-definitions", rule, {
347402
errors: [
348403
{
349404
messageId: "duplicateFootnoteDefinition",
350-
data: { identifier: "mercury" },
405+
data: {
406+
identifier: "mercury",
407+
label: "Mercury",
408+
firstLine: "2",
409+
firstLabel: "mercury",
410+
},
351411
line: 3,
352412
column: 1,
353413
endLine: 3,
@@ -371,7 +431,12 @@ ruleTester.run("no-duplicate-definitions", rule, {
371431
errors: [
372432
{
373433
messageId: "duplicateFootnoteDefinition",
374-
data: { identifier: "mercury" },
434+
data: {
435+
identifier: "mercury",
436+
label: "mercury",
437+
firstLine: "2",
438+
firstLabel: "mercury",
439+
},
375440
line: 3,
376441
column: 1,
377442
endLine: 3,
@@ -397,7 +462,12 @@ ruleTester.run("no-duplicate-definitions", rule, {
397462
errors: [
398463
{
399464
messageId: "duplicateDefinition",
400-
data: { identifier: "mercury" },
465+
data: {
466+
identifier: "mercury",
467+
label: "mercury",
468+
firstLine: "2",
469+
firstLabel: "mercury",
470+
},
401471
line: 12,
402472
column: 1,
403473
endLine: 12,

0 commit comments

Comments
 (0)