This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
The error checker does not read the file from the editor (when modified) in some cases (it seems that this happens when there seems to be a class file that is newer than the java file). Steps to reproduce: 1) create a new Java Application project 2) add NewClass (into the same package as Main class) 3) add "public void methodA(){}" to NewClass and do not save it 4) switch to Main class and add "new NewClass().methodA()" to the body of the main method -> errors underlining works correctly - error checker has read the NewClass from the editor - OK 5) now build the project (both Main and NewClass are automatically saved and built) 6) go back to NewClass, add "public void methodB(){}" and *do not save* 7) switch to Main class and replace call to methodA by a call to methodB -> the call is underlined -> error checker has not read the NewClass from the editor although it is modified
Fixing this without changing javacore's error checking interface requires yet another API enhancement to ECRequestDesc, "long lastModified(String filename);" which either returns the current time for unsaved editor buffers, or the lastModified time of the source file. This is necessary since currently only the lastModified times of the source and class files are compared. This may impact performance, however, since both ECRequestDescImpl.getReader(filename) and ASTProvider.getRealSource() show that a lot of work goes into fetching a source file. Currently this only happens for those secondary source files which are actually required for attribution and whose source files have a later lastModified time than their class file, so only those classes actually needed for error checking are fetched. However, the lastModified time is called during package listing, so *all* project source files will need to get their lastModified times for each error check invocation. A more practical possibility is for the editor to pass in a list of the filenames or DataObjects of buffers that have pending changes. This eliminates the overhead of polling all source files to see which ones have an incorrect lastModified date. So let me know what option you want, if any. If you decide to go with the polling option, please know that any later issues complaining that it is slow and memory-intensive will be closed, since that is the expected cost for this algorithm.
I tried to look up some API in NetBeans that we could use to get all modified files and I think I found something - DataObject.getRegistry().getModified() returns an array of modified dataobjects. We could use that to get all modified JavaDataObjects and extract the names of the underlying files from those. ErrorChecker could then ask for those names. Let me know what API would be most convenient for you - e.g. would adding "String[] getModifiedFiles()" method (returning names of modified files) to ECRequestDesc be ok? Or should the method return a Set/*<String>*/ (for faster "contains()" queries)? Or something else?
DataObject.getRegistry().getModified() looks perfect. Would you mind verifying with the editor team that modified Java sources are always included in this list? If so, adding something like "boolean isModified(String filename)" to the ECRequest interface should provide all the information the error checker will need.
Tom, I have added the isModified(filename) method to the ECRequestDesc. ECRequestDesc impl now creates a map filename->dataobject for modified dataobjects. Besides implementing the isModified() method, I used this map to improve the getReader() method so that it can quickly get a dataobject for a given filename if a file is modified. So, one more improvement can be considered - would it be possible for ErrorChecker to call the getReader() method only for filenames where isModified() returns true and otherwise use javac's standard mechanism? This could improve the performance since the complicated lookup code for dataobject in getReader() method would not need to be used.
I modified the error checker's ClassReader so it uses the new isModified(file) method, and only load source files from the IDE when that method returns true. Thanks for your help, Martin.
Reorganization of java component