Skip to content

Commit b6dc9f6

Browse files
committed
Include file name and line number in error messages (fixes #87)
1 parent 42e8aee commit b6dc9f6

File tree

4 files changed

+70
-24
lines changed

4 files changed

+70
-24
lines changed

lib/error.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
var format = require('util').format;
4+
var path = require('path');
5+
6+
/**
7+
* Format an error message regarding a comment, prefixed with file name and line number.
8+
*
9+
* @param comment
10+
* @param error
11+
*/
12+
module.exports = function(comment, error) {
13+
var relativePath = path.relative(process.cwd(), comment.context.file);
14+
return format.apply(format, ['%s:%d: ' + error, relativePath, comment.context.loc.start.line]
15+
.concat(Array.prototype.slice.call(arguments, 2)));
16+
};

streams/hierarchy.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
var through = require('through');
4+
var error = require('../lib/error');
45

56
/**
67
* Infer a hierarchy of documentation from a stream of documentation
@@ -55,10 +56,10 @@ function inferHierarchy(comments) {
5556
// as members of other docs.
5657
comments.splice(i, 1);
5758
} else {
58-
console.error('found memberof but no @scope, @static, or @instance tag');
59+
console.error(error(comments[i], 'found memberof but no @scope, @static, or @instance tag'));
5960
}
6061
} else {
61-
console.error('memberof reference to %s not found', comments[i].memberof);
62+
console.error(error(comments[i], 'memberof reference to %s not found', comments[i].memberof));
6263
}
6364
}
6465
}

streams/lint.js

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
var through = require('through');
4+
var error = require('../lib/error');
45

56
var CANON = [
67
'string',
@@ -21,28 +22,6 @@ var CANONICAL = CANON.reduce(function (memo, name) {
2122
memo[name] = true; return memo;
2223
}, {});
2324

24-
function nameInvariant(name) {
25-
if (CANONICAL_LOWER[name.toLowerCase()] &&
26-
!CANONICAL[name]) {
27-
console.log('type %s found, %s is standard',
28-
name, CANONICAL_LOWER[name.toLowerCase()]);
29-
}
30-
}
31-
32-
function checkCanonical(type) {
33-
if (!type) return;
34-
if (type.type === 'NameExpression') {
35-
nameInvariant(type.name);
36-
} else if (type.type === 'UnionType') {
37-
type.elements.forEach(checkCanonical);
38-
} else if (type.type === 'OptionalType') {
39-
checkCanonical(type.expression);
40-
} else if (type.type === 'TypeApplication') {
41-
checkCanonical(type.expression);
42-
type.applications.map(checkCanonical);
43-
}
44-
}
45-
4625
/**
4726
* Create a transform stream that passively lints and checks documentation data.
4827
*
@@ -52,6 +31,27 @@ function checkCanonical(type) {
5231
module.exports = function () {
5332

5433
return through(function (comment) {
34+
function nameInvariant(name) {
35+
if (CANONICAL_LOWER[name.toLowerCase()] &&
36+
!CANONICAL[name]) {
37+
console.log(error(comment, 'type %s found, %s is standard',
38+
name, CANONICAL_LOWER[name.toLowerCase()]));
39+
}
40+
}
41+
42+
function checkCanonical(type) {
43+
if (!type) return;
44+
if (type.type === 'NameExpression') {
45+
nameInvariant(type.name);
46+
} else if (type.type === 'UnionType') {
47+
type.elements.forEach(checkCanonical);
48+
} else if (type.type === 'OptionalType') {
49+
checkCanonical(type.expression);
50+
} else if (type.type === 'TypeApplication') {
51+
checkCanonical(type.expression);
52+
type.applications.map(checkCanonical);
53+
}
54+
}
5555

5656
comment.tags.forEach(function (tag) {
5757
if (tag.title === 'param' && tag.type) {

test/lib/error.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
3+
var test = require('prova'),
4+
util = require('util'),
5+
path = require('path'),
6+
error = require('../../lib/error');
7+
8+
test('error', function (t) {
9+
var comment = {
10+
context: {
11+
file: path.join(process.cwd(), 'file.js'),
12+
loc: {
13+
start: {
14+
line: 1,
15+
column: 2
16+
},
17+
end: {
18+
line: 3,
19+
column: 4
20+
}
21+
}
22+
}
23+
};
24+
25+
t.deepEqual(error(comment, 'test'), 'file.js:1: test');
26+
t.deepEqual(error(comment, '%s', 'test'), 'file.js:1: test');
27+
28+
t.end();
29+
});

0 commit comments

Comments
 (0)