Skip to content

Commit

Permalink
Add no-unused-definitions rule
Browse files Browse the repository at this point in the history
This new rule detects unused definitions and warns when they’re found.

Closes GH-34.
  • Loading branch information
wooorm committed Jan 9, 2016
1 parent 43042ea commit bde77ab
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 1 deletion.
15 changes: 15 additions & 0 deletions doc/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ See the readme for a [list of external rules](https://github.com/wooorm/remark-l
* [no-shortcut-reference-link](#no-shortcut-reference-link)
* [no-table-indentation](#no-table-indentation)
* [no-tabs](#no-tabs)
* [no-unused-definitions](#no-unused-definitions)
* [ordered-list-marker-style](#ordered-list-marker-style)
* [ordered-list-marker-value](#ordered-list-marker-value)
* [rule-style](#rule-style)
Expand Down Expand Up @@ -1054,6 +1055,20 @@ Options: `boolean`, default: `false`.

Warn when hard-tabs instead of spaces

### no-unused-definitions

```md
<!-- Valid: -->
[foo][]

[foo]: https://example.com

<!-- Invalid: -->
[bar]: https://example.com
```

Warn when unused definitions are found.

### ordered-list-marker-style

```md
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@ module.exports = {
'table-cell-padding': require('./table-cell-padding'),
'table-pipes': require('./table-pipes'),
'no-tabs': require('./no-tabs'),
'unordered-list-marker-style': require('./unordered-list-marker-style')
'unordered-list-marker-style': require('./unordered-list-marker-style'),
'no-unused-definitions': require('./no-unused-definitions.js')
};
94 changes: 94 additions & 0 deletions lib/rules/no-unused-definitions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* @author Titus Wormer
* @copyright 2016 Titus Wormer
* @license MIT
* @module no-unused-definitions
* @fileoverview
* Warn when unused definitions are found.
* @example
* <!-- Valid: -->
* [foo][]
*
* [foo]: https://example.com
*
* <!-- Invalid: -->
* [bar]: https://example.com
*/

'use strict';

/* eslint-env commonjs */

/*
* Dependencies.
*/

var position = require('mdast-util-position');
var visit = require('unist-util-visit');

/**
* Warn when definitions with equal content are found.
*
* Matches case-insensitive.
*
* @param {Node} ast - Root node.
* @param {File} file - Virtual file.
* @param {*} preferred - Ignored.
* @param {Function} done - Callback.
*/
function noUnusedDefinitions(ast, file, preferred, done) {
var map = {};
var identifier;

/**
* Check `node`.
*
* @param {Node} node - Node.
*/
function find(node) {
if (position.generated(node)) {
return;
}

map[node.identifier.toUpperCase()] = {
'node': node,
'used': false
};
}

/**
* Mark `node`.
*
* @param {Node} node - Node.
*/
function mark(node) {
var info = map[node.identifier.toUpperCase()];

if (position.generated(node) || !info) {
return;
}

info.used = true;
}

visit(ast, 'definition', find);
visit(ast, 'footnoteDefinition', find);

visit(ast, 'imageReference', mark);
visit(ast, 'linkReference', mark);
visit(ast, 'footnoteReference', mark);

for (identifier in map) {
if (!map[identifier].used) {
file.warn('Found unused definition', map[identifier].node);
}
}

done();
}

/*
* Expose.
*/

module.exports = noUnusedDefinitions;
1 change: 1 addition & 0 deletions test/fixtures/no-unused-definitions-invalid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[bar]: https://example.com
3 changes: 3 additions & 0 deletions test/fixtures/no-unused-definitions-valid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[foo][]

[foo]: https://example.com
10 changes: 10 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,16 @@ describe('Rules', function () {
});
});

describeRule('no-unused-definitions', function () {
describeSetting(true, function () {
assertFile('no-unused-definitions-invalid.md', [
'no-unused-definitions-invalid.md:1:1-1:27: Found unused definition'
]);

assertFile('no-unused-definitions-valid.md', []);
});
});

describeRule('fenced-code-marker', function () {
describeSetting(true, function () {
assertFile('fenced-code-marker-tick.md', []);
Expand Down

0 comments on commit bde77ab

Please sign in to comment.