Bug 144858 - [compiler] Should be more resilient with duplicate locals
Summary: [compiler] Should be more resilient with duplicate locals
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: 3.3 M1   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 156731
  Show dependency tree
 
Reported: 2006-06-01 06:02 EDT by Philipe Mulet CLA
Modified: 2006-11-24 06:22 EST (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Philipe Mulet CLA 2006-06-01 06:02:12 EDT
3.2RC6

In presence of duplicate local variables, duplicate fields or methods; the compiler discards all instances of the offending construct.
This means that more secondary errors may arise and be quite misleading outside of context, and other tools based on the AST (DOM AST for instance) may behave suboptimally as lacking some of the binding information.

What if:
- it still created the bindings, and attached them to the AST node
- it would leave at least one entry in binding arrays to reduce amount of secondary errors.

e.g. we currently complain about missing both #foo() and #baz()
public class X {
	void foo() {
	}
	void foo() {
	}
	void bar() {
		foo();
		baz();
	}
}
Comment 1 Philipe Mulet CLA 2006-06-01 06:42:26 EDT
Other related scenario with local variables:

public class X {
	void foo(){
		int x = 0;
		String x = "";
		x.toString();
	}
}

Currently complains about applying #toString() to primitive type int. Considering the last definition to override previous one, we would tolerate the message send (note that variable lookup already does walk the scope backward, we simply need to insert the offending variable in scope). 
Comment 2 Philipe Mulet CLA 2006-06-01 06:47:25 EDT
Other example where variable collision is altering catch block diagnostics (i.e. unable to spot conflicting catch block until renaming local var)

public class X {
        public static void main(String[] args) {
                int x = 2;
                try {
                	
                } catch(Exception x) {
                } catch(Exception e) {
                }
        }
}
Comment 3 Philipe Mulet CLA 2006-06-01 06:52:45 EDT
Other example (variation on bug ) shows that we could also spot assignment with no effect in presence of dup variable:

public class X {
        public static void main(String[] args) {
                int x = x = 0;
                if (true) {
                        int x = x = 1;
                }
        }
}

"int x = x = 1;" could be blamed for assignment with no effect.
Comment 4 Philipe Mulet CLA 2006-06-01 06:53:15 EDT
Previous comment should have mentionned bug 144426
Comment 5 Philipe Mulet CLA 2006-06-01 06:59:36 EDT
One more interesting outcome if fixing this:

Consider the following scenario, where user pasted some code which happen to have a local var name conflict (x). 
Let say, he wants to rename the catch x variable into x2. Move cursor on it, perform "ctrl-2 r" to perform rename in file, observe that only the catch var is renamed, user has to manually go and fix the references which is error prone as it may still bind to the outer one and be valid (so hard to spot, like in case of nested loops).

import java.io.*;

public class X {
        public static void main(String[] args) {
                int x = 2;
                try {
                } catch(Exception x) {
                	if (x instanceof IOException) {
                	}
                } catch(Exception e) {
                }
        }
}
Comment 6 Philipe Mulet CLA 2006-06-01 07:03:00 EDT
More compelling example (maybe) on the same case where renaming all instances at once is interesting:

import java.io.*;

public class X {
        public static void main(String[] args) {
        	for (int i = 0; i < 10; i++) {
        		for (int i = 0; i < 5; i++)  {
        			// do something
        		}
        	}
        }
}

This may occur when pasting some code, which uses same indice variable 'i'.
If being more resilient, rename in file on the dup variable will fix all instances which are in scope.
Comment 7 Philipe Mulet CLA 2006-06-01 07:06:02 EDT
Need DOM AST tests showing difference, and codeassist/select ones as well.
Like here:

import java.io.*;

public class X {
        public static void main(String[] args) {
        	for (int i = 0; i < 10; i++) {
        		for (int i = 0; i < 5; i++)  {
        			if (i == 0) { // select
        				// do something
        			}
        		}
        	}
        }
}

selecting 'i' in "if (i == 0)" statement, and pressing F3 will take to the inner local variable.
Comment 8 Philipe Mulet CLA 2006-06-01 07:07:11 EDT
David/Olivier - once we fix this, pls provide regression tests for codeselect and DOM AST.
Comment 9 Philipe Mulet CLA 2006-06-09 06:07:11 EDT
Released for 3.3.
Added LocalVariableTest#test013-014 (and tuned a few existing ones)
Comment 10 Philipe Mulet CLA 2006-06-13 03:28:50 EDT
Changed title to only mention duplicate locals.
Entered bug 146768 for duplicate field/method issues.
Comment 11 Frederic Fusier CLA 2006-08-03 08:45:48 EDT
Released for 3.3 M1
Comment 12 Frederic Fusier CLA 2006-08-08 07:27:58 EDT
Verified for 3.3 M1 using build I20060807-2000.
Comment 13 Frederic Fusier CLA 2006-08-08 07:29:36 EDT
David and Olivier, please indicate where did you add Code select and DOM/AST tests, thanks
Comment 14 Olivier Thomann CLA 2006-08-28 15:04:47 EDT
In the example from comment 1, variable bindings for both x have the same key.
I would expect them to have a different key since they are different bindings.
Comment 15 Olivier Thomann CLA 2006-08-28 15:05:19 EDT
This can be checked using the ASTView.
Comment 16 Markus Keller CLA 2006-09-04 13:28:38 EDT
Comment 14 and comment 15 are bug 149590 and bug 155858.
Comment 17 Olivier Thomann CLA 2006-11-23 12:18:16 EST
Added regression tests org.eclipse.jdt.core.tests.dom.ASTConverterTestAST3_2#test0660/0663
Comment 18 David Audel CLA 2006-11-24 06:22:51 EST
Added regression tests
  CompletionTests#testDuplicateLocals1() -> testDuplicateLocals5()
  ResolveTests#testDuplicateLocals1() -> testDuplicateLocals5()