History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: IDEADEV-11089
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Critical Critical
Assignee: Eugene Zhuravlev
Reporter: Sascha Weinreuter
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
IDEA: Development

ClassInstrumentingCompiler is not invoked on recompiled files that didn't change

Created: 05 Sep 06 23:50   Updated: 23 Oct 06 20:45
Component/s: Compiling Project
Fix Version/s: Demetra 6.0.2

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown

Build: 5,650
Fixed in build: 6,066
Severity: Medium


 Description  « Hide
... but the class is actually compiled and therefore the instrumentation is gone.

The effect that can be observed in the code is that the item for such a file file which has been returned from com.intellij.openapi.compiler.FileProcessingCompiler.getProcessingItems() is not passed to the process() method of the compiler.

This effect can be reproduced with the @NotNull instrumentation as well: When compiling and running the following class (with @NotNull assertions enabled), the expected exception is thrown, but when invoking "Compile" on the file again (from the editor context menu) without having changed it since the last compilation, the instrumentation and the exception are gone during the next run.

A workaround seems to be to return a ValidityState that always returns false from its equalsTo() method, but I don't know if that has some other bad effect and it shouldn't really be necessary to do this in an instrumenting compiler: If the class has been re-compiled, it should always be re-instrumented.

import org.jetbrains.annotations.NotNull;

public class NotNullTest {
    public static void main(String[] args) {
        testNotNull(null);
    }
    
    private static void testNotNull(@NotNull String s) {
    }
}


 All   Comments   Work Log   Change History      Sort Order:
Eugene Zhuravlev - 21 Oct 06 21:55
What kind of file does your "ProcessingItem.getFile()" return?

Concerning ValidityState that always is not equalsTo() : that way your files will be be compiled always, no matter were there changes or not, so this is not a solution


Sascha Weinreuter - 21 Oct 06 22:37
My ProcessingItem.getFile() returns a VirtualFile that points to the Java source file that produces the class files to be instrumented. This is the same the NotNullVerifyingCompiler does, and which also seems to still suffer from this problem in #6043.

Concerning ValidityState that always is not equalsTo() : that way your files will be be compiled always, no matter were there changes or not, so this is not a solution

Yes, this is what I noticed as well and which resulted in duplicate instrumentation which was even worse

BTW: You can find the complete code in the IntelliLang plugin. Let me know if you need any more details.

Sascha


Eugene Zhuravlev - 23 Oct 06 20:10
ProcessingItem.getFile() should return class file (the file that will be instrumented). I've updated the NotNullVerifier accordingly.
In this case IDEA's make will check timestamp of the class file (which changes) and not of the source file (which remans unchenged in this scenario). However, if the file is instrumented by several instrumenters, each of them will change the file timestamp and make will record a different timestamp for every instrumenter. This will lead to another problem: the file will be re-instrimented on every invocation of make.

So another fix that has been implemented is to keep the timestamp of the class file the same as it was when the file was generated by javac, no matter how many instrumenters are applied to it.


Sascha Weinreuter - 23 Oct 06 20:45
Ah, that's what I already suspected. Thanks for the details!