Proposal: add `sourceContext` property to the messages generated by the `eslint` object
See original GitHub issueContext: We would like to port the JSCS default formatter over to ESLint. That formatter prints out the lines around the location of an error/warning. See #5860 for an example output.
Problem Unfortunately, with ESLint, there is currently no way to get those lines of “context” from a formatter, because:
- The formatter is invoked with only one argument - the array of messages to report on, and those do not contain any information about the lines of context around the error.
- The formatter is intentionally made to be “dumb” and shouldn’t/cannot use
SourceCode.getLines()
to retrieve the lines of code of the file being reported on.
Proposal
I would like to add a sourceContext
property to each message object that gets returned by the eslint.verify()
method.
With this new property, the message object would look roughly like the following:
{
ruleId: 'lines-around-comment',
severity: 2,
message: 'Expected line before comment.',
line: 37,
column: 9,
nodeType: 'Line',
source: '// some random comment',
sourceContext: {
before: [
"line of code before line of the error",
"another line of code"
],
after: [
"line of code after the line of the error",
"another line of code"
]
}
}
Each item of the before
/after
array is a line of code directly from the array returned by SourceCode.getLines(code)
.
An alternative would be that each item is instead an object that contains a source
and a line
property, like this:
{
sourceContext: {
before: [
{
source: "line of code before line of the error",
line: 35
},
{
source: "another line of code",
line: 36
}
],
after: [
// ...
]
}
}
The advantage of this alternative approach is that it would prevent delegating the calculation of the line number to the formatter.
Adding this sourceContext
property would solve the problem described, and would allow us to port the JSCS formatter with ease.
I have some proof-of-concept code for this proposal locally that is already able to print out the lines around an error, like this:
$ bin/eslint.js --rulesdir lib/internal-rules/ lib/formatters/stylish.js
35
36 results.forEach(function(result) {
37 // console.log(result);
38 const messages = result.messages;
39
lib/formatters/stylish.js
37:9 error Expected line before comment lines-around-comment
The existing tests also already pass so I would only need to clean up the code a bit and make sure to test some edge cases better.
Questions
- Are there other any other ways to solve the problem described that would be preferable?
- I don’t really like the property name
sourceContext
that much, but couldn’t come up with anything better. Any suggestions?
Issue Analytics
- State:
- Created 7 years ago
- Comments:23 (23 by maintainers)
Top GitHub Comments
Design Summary
This change will be made in two phases:
source
property containing the entire file contents as a string into the linting results for each file that has linting errors. This can be used by formatters to output source code along with lint messages. This is a non-breaking change.source
property from individual linting error messages in order to avoid duplicate information in the results.Just want to double-check that everyone is on the same page with this.
I’m not a fan of adding another property to each message, as it seems like the possibility of adding redundant information to multiple messages is quite high. Before I delve into this, I’d like to offer some background.
Background
The way formatters currently work is that all of the linting is done first and the results are aggregated into a
report
object. Then, thereport
object is used to pass results into the formatter. This sequence is important because allSourceCode
objects are destroyed by that point in time, and further, the execution context in which each individual file’s linting was done is completely lost.Possible Solution
We could keep a map of filename to source code (plain text) as linting is being done. We’d only need entries in that map for files that had errors, so it could be kept relatively small. So basically, somewhere in
CLIEngine
, you’d end up with stuff like:Then,
sourceCache
could be passed into formatters as a second argument, so it’s there if you want to grab stuff from it, but you’re not required to use it.