This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 436986 - [eslint] implement no-unreachable rule
Summary: [eslint] implement no-unreachable rule
Status: RESOLVED FIXED
Alias: None
Product: Orion (Archived)
Classification: ECD
Component: JS Tools (show other bugs)
Version: 6.0   Edit
Hardware: PC All
: P3 enhancement (vote)
Target Milestone: 6.0 RC1   Edit
Assignee: Michael Rennie CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-06-09 12:30 EDT by Grant Gayed CLA
Modified: 2014-06-10 01:48 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Grant Gayed CLA 2014-06-09 12:30:14 EDT
For a line like the following a "missing semicolon" warning is shown for the return statement.  Its semicolon is there, it's just a few editor lines down.

return
	blocks.length &&
	blocks[0].start === block.start &&
	blocks[0].end === block.end + changeCount &&
	blocks[0].typeId === block.typeId &&
	blocks[0].getBlocks().length === block.getBlocks().length; <-- it's here
Comment 1 Mark Macdonald CLA 2014-06-09 12:39:54 EDT
The warning is valid -- this is a dangerous JS parsing quirk. The code you posted is equivalent to the following:

> return undefined
> blocks.length &&
> blocks[0].start === block.start &&
> blocks[0].end === block.end + changeCount &&
> blocks[0].typeId === block.typeId &&
> blocks[0].getBlocks().length === block.getBlocks().lengthngth === block.getBlocks().length;

IOW, it returns nothing and then there's a no-op Expression statement after the return. We should really have an "unreachable code" warning on the expression statement, which would make the problem here clearer.
Comment 2 Michael Rennie CLA 2014-06-09 13:29:03 EDT
(In reply to Mark Macdonald from comment #1)
 
> IOW, it returns nothing and then there's a no-op Expression statement after
> the return. We should really have an "unreachable code" warning on the
> expression statement, which would make the problem here clearer.

We correctly forward / report the parse error (Illegal return statement) in this case. In tolerant mode we can recover from this problem and produce the following tree:

{
    "type": "Program",
    "body": [
        {
            "type": "ReturnStatement",
            "argument": null
        },
        {
            "type": "ExpressionStatement",
            "expression": {
                "type": "LogicalExpression",
                "operator": "&&",
                "left": {

Notice the return argument is null. I'm not sure there would be any value in a new rule to report on the same problem code with a different error / warning.
Comment 3 Michael Rennie CLA 2014-06-09 13:33:42 EDT
(In reply to Michael Rennie from comment #2)
> (In reply to Mark Macdonald from comment #1)
>  
> > IOW, it returns nothing and then there's a no-op Expression statement after
> > the return. We should really have an "unreachable code" warning on the
> > expression statement, which would make the problem here clearer.
> 
> We correctly forward / report the parse error (Illegal return statement) in
> this case.

Of course if we wrap it all up like:

function f() {
    var blocks = [], block, changeCount;
    return 
        blocks.length && 
        blocks[0].start === block.start && 
        blocks[0].end === block.end + changeCount && 
        blocks[0].typeId === block.typeId && 
        blocks[0].getBlocks().length === block.getBlocks().length;
}
f();

we don't need tolerant mode to produce a null handle to the return statement value. Leading to no parse error.
Comment 4 Michael Rennie CLA 2014-06-09 13:37:02 EDT
(In reply to Michael Rennie from comment #3)

Heres the related spec for fun: http://es5.github.io/#x12.9
Comment 5 Mark Macdonald CLA 2014-06-09 13:40:23 EDT
(In reply to Michael Rennie from comment #3)
Right.. I was assuming Grant's original code was inside a function.
Comment 6 Grant Gayed CLA 2014-06-09 14:23:41 EDT
(In reply to Mark Macdonald from comment #5)
> Right.. I was assuming Grant's original code was inside a function.

Yes, it's in a function.

This characteristic of js parsing was unexpected by me to the point that I assumed a lint error rather than reacting to the warning.  A more specific warning message would have clued me into the real issue.
Comment 7 Michael Rennie CLA 2014-06-09 15:39:28 EDT
(In reply to Grant Gayed from comment #6)
> (In reply to Mark Macdonald from comment #5)
> > Right.. I was assuming Grant's original code was inside a function.
> 
> Yes, it's in a function.
> 
> This characteristic of js parsing was unexpected by me to the point that I
> assumed a lint error rather than reacting to the warning.  A more specific
> warning message would have clued me into the real issue.

This rule would be a bit tricky to implement without inspecting the source. The problem is that there is no token descriptor for a line break. So assuming we have a snippet like:

function f() {
 return
 true;
}

we get tokens like:

    {
        "type": "Keyword",
        "value": "return"
    },
    {
        "type": "Boolean",
        "value": "true"
    },
    {
        "type": "Punctuator",
        "value": ";"
    },

The other option is that I could make this a parse problem, since it does technically violate the spec. We already have a general 'Unexpected <thing>' error in Esprima, I could report 'Unexpected line break' or something.
Comment 8 Michael Rennie CLA 2014-06-10 01:48:53 EDT
Created the eslint rule + tests:

http://git.eclipse.org/c/orion/org.eclipse.orion.client.git/commit/?id=6ca8408f2dd694515acab6fc626a930acfa53db4

The default severity for the new rule is error.