Bug 191092 - [compiler] Misleading compiler error on single line if statement
Summary: [compiler] Misleading compiler error on single line if statement
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 485275 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-06-05 14:36 EDT by Will Horn CLA
Modified: 2016-01-07 00:24 EST (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Will Horn CLA 2007-06-05 14:36:32 EDT
Build ID: I20070525-1350

Steps To Reproduce:
1. Create a Java class with the following code
public class Test {
public void test() {
if (true) 
String string = new String();
}
}

More information:
The error annotations for the syntax error are misleading:

Multiple markers at this line
    - Syntax error, insert ";" to complete Statement
    - String cannot be resolved
    - string cannot be resolved
    - Syntax error, insert "AssignmentOperator Expression" to complete Assignment

The red squiggly lines are below the type (String) and the variable name (string) and imply that there is a problem resolving the type. 

On javac, the error is slightly more helpful since it draws attention to the entire object construction being invalid:

Test.java:3: not a statement
if (true) String string = new String();
^
Test.java:3: ';' expected
if (true) String string = new String();


Olivier Thomann responded on the org.eclipse.jdt newsgroup:
"The problem comes from the grammar.
Technically speaking your code is a syntax error. We might try to see 
how we can modify the grammar in order to digest such syntax and reject 
the case later."
Comment 1 Olivier Thomann CLA 2007-06-05 14:40:42 EDT
I consider this as an enhancement. Not a bug since the code is invalid and we reject it.
Comment 2 Sknu ijver CLA 2016-01-06 10:42:57 EST
class Test {
public void test() {
String string;
if (true) 
string = new String();
}
}

does compile without issue. Is String string = new String();  shorthand for two statements?
Comment 3 Sknu ijver CLA 2016-01-06 10:44:48 EST
*** Bug 485275 has been marked as a duplicate of this bug. ***
Comment 4 Olivier Thomann CLA 2016-01-06 10:55:15 EST
(In reply to Sknu ijver from comment #3)
> *** Bug 485275 has been marked as a duplicate of this bug. ***

public class X {
	public void test() {
		if (true) 
			String string = new String();
	}
}

With that code, javac reports:

X.java:4: error: variable declaration not allowed here
                        String string = new String();
                               ^
1 error

This is not different from your example. Why do you believe this is valid java? Could you please point me to where you found out this is valid? Thanks.
As far as I know, variable declaration statements are not valid statements as an if then clause.

Stephan, anything to add?

class Test {
public void test() {
String string;
if (true) 
string = new String();
}
}
is completely different. string = new String(); is an assignment which is part of an expression statement which is perfectly fine as an if then clause.
This should be closed as invalid. The only way to get a better message would be to modify the grammar to consume variable declaration statement as part of an if then clause and reject it then.

Stephan, Jay, I let you take care of this. Thx.
Comment 5 Stephan Herrmann CLA 2016-01-06 17:11:13 EST
Thanks Olivier,

Yep, see http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.2

A LocalVariableDeclarationStatement is a BlockStatement and hence can only occur in a Block.

The then branch of an if-then statement (14.9.1) is a Statement. Productions for Statement include Assignment (via StatementWithoutTrailingSubstatement -> ExpressionStatement -> StatementExpression -> Assignment), but no direct option for LocalVariableDeclarationStatement. Local vars are legal in a then statement only if enclosed in a Block.

Besides: if you were allowed to create a local variable in a then statement, the scope of the variable would be only its own declaring statement => no code location would be able to read the variable. Not very useful :)


Grammar modification is also the first I could think of for reporting a more useful error message. If that works without creating LALR(1) conflicts, I'd agree to that, but if further tweaking of the grammar is required, I don't see this worth the effort, honestly.
Comment 6 Sknu ijver CLA 2016-01-06 17:20:52 EST
That was my point. This bug here initially got a short reply from Olivier Thomann, where he said the code was syntactically wrong but there could be an enhancement. I had just filed a similar bug when I realized that this was a compound / block statement. I just added a comment in addition to Olivier's response.