Bug 79163 - [compiler] Dependency on indirectly referenced types not correctly computed
Summary: [compiler] Dependency on indirectly referenced types not correctly computed
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1 M4   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-11-22 04:53 EST by Donna Malayeri CLA
Modified: 2004-12-14 11:25 EST (History)
0 users

See Also:


Attachments
Add report type reference when type cannot be seen. (2.09 KB, patch)
2004-11-23 11:11 EST, Frederic Fusier CLA
no flags Details | Diff
Test cases added to LookupTests (7.67 KB, patch)
2004-11-23 11:14 EST, Frederic Fusier CLA
no flags Details | Diff
Improved patch (4.85 KB, patch)
2004-11-23 11:44 EST, Frederic Fusier CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Donna Malayeri CLA 2004-11-22 04:53:55 EST
Suppose in Foo.java we have
public class Foo { void bar(); } 

and in FooFactory.java
public class FooFactory { public static Foo createFoo(); }

and somewhere in Client.java
createFoo().bar();

Suppose also that Client.java does not reference Foo directly.  In such a case, 
the search engine will NOT find the Client.java reference to Foo OR to Foo.bar()
.  And, more importantly, the compiler dependency analyzer also seems to be 
missing the dependency between the two files, so if Foo.java is changed, Client.
java is NOT recompiled.
Comment 1 Philipe Mulet CLA 2004-11-22 05:29:26 EST
The incremental compiler has nothing to do with the search engine.
Comment 2 Donna Malayeri CLA 2004-11-22 05:33:58 EST
Then the same bug exists in both places. Should this be filed as two bug 
reports?
Comment 3 Philipe Mulet CLA 2004-11-22 06:00:34 EST
We will investigate, and take care of it. Thanks for reporting.
Comment 4 Frederic Fusier CLA 2004-11-22 06:47:24 EST
It currently works as it does. Perhaps did you miss some points in your test case...

Let say that Client.java is:
public class Client {
	void foo() {
		FooFactory.createFoo().bar();
	}
}
As you said, it does not reference directly Foo, so it is absolutely normal that
search engine does not find reference to Foo. But, it does find reference to
Foo.bar()...

Now for the incremental builder... If you change something in Foo which does not
concern bar() signature, then Client will not be recompiled. This is the
optimized expected behavior.
For example, if you add method foo() to Foo:
public class Foo {
	void bar() {}
	void foo() {}
}
there's obviously no need to recompile Client...

However, if now you modify signature of bar() like:
public class Foo {
	int bar() { return 0; }
	void foo() {}
}
then, you'll see that builder recompiles Client as it may be impacted by this
change...
Comment 5 Frederic Fusier CLA 2004-11-22 07:33:46 EST
Just a precision on my previous comment...

While adding method foo() to Foo, builder in fact recompile Client class but
does not write .class file as:
1) source was not modified
2) contents of .class was unchanged

You can see this behavior in detail by activating build trace:

Starting build of _Test @ Mon Nov 22 13:26:21 CET 2004
Found source delta for: _Test
Clearing last state : State for _Test (#0 @ Mon Nov 22 13:26:00 CET 2004)
INCREMENTAL build
Compile this changed source file Foo.java
About to compile Foo.java
Type has structural changes Foo
  will look for dependents of Foo in 
Writing changed class file Foo.class
Found match in well known package to Foo
  adding affected source file FooFactory.java
Found match in well known package to Foo
Found match in well known package to Foo
  adding affected source file Client.java
About to compile FooFactory.java
About to compile Client.java
Skipped over unchanged class file FooFactory.class
Skipped over unchanged class file Client.class
Recording new state : State for _Test (#1 @ Mon Nov 22 13:26:21 CET 2004)
Finished build of _Test @ Mon Nov 22 13:26:21 CET 2004
Comment 6 Donna Malayeri CLA 2004-11-22 13:31:36 EST
It looks like the bug occurs in a very limited circumstance. In the same test 
case mentioned above, change the accessibility of class Foo to default (package-
private) access, and put Client.java in a different package.  When Foo is 
changed from public to default access, Client.java is correctly recompiled, and 
will then have a compilation error (since it cannot access Foo).  Now change Foo 
back to public.  Client.java is not recompiled.

Comment 7 Frederic Fusier CLA 2004-11-23 08:06:29 EST
ok, I can reproduce the problem, thanks for the input.
Here's the modified test case:
q/Foo.java:
package q;
public class Foo {
	public void bar() {}
}
q/FooFactory.java:
package q;
public class FooFactory {
	public static Foo createFoo() {
		return new Foo();
	}
}
p/Client.java:
package p;
import q.FooFactory;
public class Client {
	void foo() {
		FooFactory.createFoo().bar();
	}
}

To reproduce:
1) Edit Foo.java and remove public in class declaration
2) save+build => get a compiler error on Client: OK
3) Put back public in Foo class declaration
4) save+build => compiler error is still there: KO

Here's the corresponding builder trace:

Starting build of _Test @ Tue Nov 23 08:57:18 CET 2004
Found source delta for: _Test
Clearing last state : State for _Test (#0 @ Tue Nov 23 08:56:55 CET 2004)
INCREMENTAL build
Compile this changed source file q/Foo.java
About to compile q/Foo.java
Type has structural changes q/Foo
  will look for dependents of Foo in q
Writing changed class file Foo.class
Found match in q to Foo
  adding affected source file p/Client.java
Found match in q to Foo
  adding affected source file q/FooFactory.java
Found match in q to Foo
About to compile p/Client.java
About to compile q/FooFactory.java
Writing changed class file Client.class
Skipped over unchanged class file FooFactory.class
Recording new state : State for _Test (#1 @ Tue Nov 23 08:57:18 CET 2004)
Finished build of _Test @ Tue Nov 23 08:57:18 CET 2004

Starting build of _Test @ Tue Nov 23 08:57:33 CET 2004
Found source delta for: _Test
Clearing last state : State for _Test (#1 @ Tue Nov 23 08:57:18 CET 2004)
INCREMENTAL build
Compile this changed source file q/Foo.java
About to compile q/Foo.java
Type has structural changes q/Foo
  will look for dependents of Foo in q
Writing changed class file Foo.class
Found match in q to Foo
  adding affected source file q/FooFactory.java
Found match in q to Foo
About to compile q/FooFactory.java
Skipped over unchanged class file FooFactory.class
Recording new state : State for _Test (#2 @ Tue Nov 23 08:57:33 CET 2004)
Finished build of _Test @ Tue Nov 23 08:57:33 CET 2004
Comment 8 Philipe Mulet CLA 2004-11-23 09:21:54 EST
Kent - we have a fix for this one. Frederic is going to implement tests and
release fix. Problem is that when diagnosing a non-visible receiver type, we
omit to record a type dependency on it, which breaks the negative scenario. 
Please still double check the fix.
Comment 9 Frederic Fusier CLA 2004-11-23 11:11:00 EST
Created attachment 16075 [details]
Add report type reference when type cannot be seen.

Kent, may you let me know if you're happy with this fix?
Thanks
Comment 10 Frederic Fusier CLA 2004-11-23 11:14:56 EST
Created attachment 16076 [details]
Test cases added to LookupTests

These 3 test cases to verify that all potential problems are really fixed with
this patch...
Comment 11 Frederic Fusier CLA 2004-11-23 11:44:04 EST
Created attachment 16077 [details]
Improved patch

Add report type reference systematically in modified methods.
Note that findMethod(...) already reported type reference. That's why it was
not necessary to report reference at the beginning of findMethodForArray(...)
and getMethod(...) as they were calling it.
Comment 12 Kent Johnson CLA 2004-11-24 12:11:25 EST
Added DependencyTests.testTypeVisibility2().
Comment 13 Olivier Thomann CLA 2004-12-14 11:25:49 EST
Verified in 200412140800