eclipse-xtext / eclipse-xtext/xtext

"Statement unnecessarily nested within else clause" warning when returning or (re-)throwing in a catch block

Open
#2,289 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
831
Forks
330
Avg merge
3d 7h
Merged PRs (30d)
12

Description

When catching a Throwable (or a subclass) in Xtend, the compiled code catches a Throwable and then casts it to the corresponding type (even if the type caught is Throwable!) using a if/else block. If the catch block contains an unconditional throw statement (see below for an example) or an unconditional return statement, the compiled code will have a then-clause not completing normally, causing IDEs such as Eclipse to issue a "statement unnecessarily nested within else clause" warning.

Fixing this issue can be done by the compiler checking whether the code contains an unconditional throw or return statement and then removing else (braces can be left but should be removed or at least moved to a new line).

As a side note, in a future version of Java this issue could be addressed using pattern matching (see JEP 305)

Sample code

Xtend code:
def static method(Object ec){
    var Class<E> e 
    try {
        e=ec as Class<E>
    } catch (ClassCastException ex) {
        throw ex // Unconditional throw
    }
}
Compiled Java code:
public static void method(Object ec){
    Class<E> e = null;
    try {
        e = ((Class<E>) ec);
    } catch (final Throwable _t) {
        if (_t instanceof ClassCastException) {
            final ClassCastException ex = (ClassCastException)_t;
            throw ex;  // Unconditional throw
        } else {  // Warning here
            throw Exceptions.sneakyThrow(_t);
        }
    }
}
Correct Java code:
public static void method(Object ec){
   Class<E> e = null;
   try {
       e = ((Class<E>) ec);
    } catch (final Throwable _t) {
       if (_t instanceof ClassCastException) {
            final ClassCastException ex = (ClassCastException)_t;
            throw ex;
        }  
        {  // Note: no else here, but (optional) braces left in place
           // No warning
            throw Exceptions.sneakyThrow(_t);
        }
    }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the Xtend compiler logic that generates the catch-handling if/else structure, using the sample method in the issue as a regression case. Check how unconditional throw and return statements are represented, then verify that generated Java omits the unnecessary else while preserving the fallback Throwable path.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.