Index: java/source/apichanges.xml diff -u java/source/apichanges.xml:1.10 java/source/apichanges.xml:1.2.12.3 --- java/source/apichanges.xml:1.10 Tue Jun 5 06:08:54 2007 +++ java/source/apichanges.xml Thu Jun 14 02:34:32 2007 @@ -83,6 +83,19 @@ + + + Support for JSPs and dialogs + + + + + + Adding ability to use Java infrastructure for non-Java file (eg. JSP files) and inside dialogs. + + + + Added a method to obtain top level elements defined in the source/class file. Index: java/source/nbproject/project.properties diff -u java/source/nbproject/project.properties:1.22 java/source/nbproject/project.properties:1.9.4.3 --- java/source/nbproject/project.properties:1.22 Tue Jun 12 06:14:59 2007 +++ java/source/nbproject/project.properties Thu Jun 14 02:34:34 2007 @@ -21,5 +21,5 @@ javadoc.title=Java Source javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml -spec.version.base=0.15.0 +spec.version.base=0.16.0 test.unit.run.cp.extra=${core.dir}/core/core.jar:${core.dir}/lib/boot.jar:../../junit/external/insanelib.jar Index: java/source/preprocessorbridge/manifest.mf diff -u java/source/preprocessorbridge/manifest.mf:1.1 java/source/preprocessorbridge/manifest.mf:1.1.10.1 --- java/source/preprocessorbridge/manifest.mf:1.1 Fri Dec 8 01:36:18 2006 +++ java/source/preprocessorbridge/manifest.mf Thu Jun 14 02:34:33 2007 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.java.preprocessorbridge OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/preprocessorbridge/Bundle.properties -OpenIDE-Module-Specification-Version: 1.0 +OpenIDE-Module-Specification-Version: 1.1 Index: java/source/preprocessorbridge/nbproject/project.xml diff -u java/source/preprocessorbridge/nbproject/project.xml:1.1 java/source/preprocessorbridge/nbproject/project.xml:1.1.10.1 --- java/source/preprocessorbridge/nbproject/project.xml:1.1 Fri Dec 8 01:36:19 2006 +++ java/source/preprocessorbridge/nbproject/project.xml Thu Jan 25 10:51:24 2007 @@ -4,10 +4,20 @@ org.netbeans.modules.java.preprocessorbridge - + + + org.openide.filesystems + + + + 7.0 + + + org.netbeans.modules.java.source org.netbeans.modules.mobility.project + org.netbeans.modules.web.core.syntax org.netbeans.modules.java.preprocessorbridge.spi Index: java/source/preprocessorbridge/src/org/netbeans/modules/java/preprocessorbridge/spi/JavaSourceProvider.java diff -u /dev/null java/source/preprocessorbridge/src/org/netbeans/modules/java/preprocessorbridge/spi/JavaSourceProvider.java:1.1.4.2 --- /dev/null Thu Jun 14 02:35:22 2007 +++ java/source/preprocessorbridge/src/org/netbeans/modules/java/preprocessorbridge/spi/JavaSourceProvider.java Thu Jun 14 02:34:32 2007 @@ -0,0 +1,62 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + */ +package org.netbeans.modules.java.preprocessorbridge.spi; + +import org.openide.filesystems.FileObject; + +/**Allows creation of JavaSource instances for non-Java files. + * Is expected to produce "virtual" Java source, which is then parsed + * by the Java parser and used by selected Java features. + * + * @author Jan Lahoda, Dusan Balek + */ +public interface JavaSourceProvider { + + /**Create {@link PositionTranslatingJavaFileFilterImplementation} for given file. + * + * @param fo file for which the implementation should be created + * @return PositionTranslatingJavaFileFilterImplementation or null if which provider + * cannot create one for this file + */ + public PositionTranslatingJavaFileFilterImplementation forFileObject(FileObject fo); + + /**"Virtual" Java source provider + * + * Currently, only {@link JavaFileFilterImplementation#filterCharSequence}, + * {@link JavaFileFilterImplementation#getOriginalPosition}, + * {@link JavaFileFilterImplementation#getJavaSourcePosition} are called. + */ + public static interface PositionTranslatingJavaFileFilterImplementation extends JavaFileFilterImplementation { + /**Compute position in the document for given position in the virtual + * Java source. + * + * @param javaSourcePosition position in the virtual Java Source + * @return position in the document + */ + public int getOriginalPosition(int javaSourcePosition); + + /**Compute position in the virtual Java source for given position + * in the document. + * + * @param originalPosition position in the document + * @return position in the virtual Java source + */ + public int getJavaSourcePosition(int originalPosition); + } +} Index: java/source/src/org/netbeans/api/java/source/CompilationController.java diff -u java/source/src/org/netbeans/api/java/source/CompilationController.java:1.7 java/source/src/org/netbeans/api/java/source/CompilationController.java:1.4.8.3 --- java/source/src/org/netbeans/api/java/source/CompilationController.java:1.7 Tue Jun 5 06:08:55 2007 +++ java/source/src/org/netbeans/api/java/source/CompilationController.java Thu Jun 14 01:43:19 2007 @@ -30,8 +30,8 @@ import javax.swing.text.Document; import javax.tools.Diagnostic; import org.netbeans.api.lexer.TokenHierarchy; -import static org.netbeans.api.java.source.JavaSource.Phase.*; import org.openide.filesystems.FileObject; +import static org.netbeans.api.java.source.JavaSource.Phase.*; /** Class for explicit invocation of compilation phases on a java source. * The implementation delegates to the {@link CompilationInfo} to get the data, @@ -175,10 +175,15 @@ public FileObject getFileObject() { return this.delegate.getFileObject(); } - + @Override public Document getDocument() throws IOException { return this.delegate.getDocument(); + } + + @Override + public ConversionInfo getConversionInfo() { + return this.delegate.getConversionInfo(); } @Override Index: java/source/src/org/netbeans/api/java/source/CompilationInfo.java diff -u java/source/src/org/netbeans/api/java/source/CompilationInfo.java:1.12 java/source/src/org/netbeans/api/java/source/CompilationInfo.java:1.6.8.4 --- java/source/src/org/netbeans/api/java/source/CompilationInfo.java:1.12 Wed Jun 6 04:32:38 2007 +++ java/source/src/org/netbeans/api/java/source/CompilationInfo.java Thu Jun 14 02:34:31 2007 @@ -41,14 +41,12 @@ import org.netbeans.api.lexer.TokenHierarchy; import org.netbeans.modules.java.source.parsing.FileObjects; import org.netbeans.modules.java.source.parsing.SourceFileObject; -import org.netbeans.modules.java.preprocessorbridge.spi.JavaFileFilterImplementation; import org.openide.ErrorManager; import org.openide.cookies.EditorCookie; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; - /** Asorted information about the JavaSource. * * @author Petr Hrebejk, Tomas Zezula @@ -60,7 +58,7 @@ private List errors; private JavacTaskImpl javacTask; - private FileObject fo; + private ConversionInfo binding; final JavaFileObject jfo; final JavaSource javaSource; boolean needsRestart; @@ -76,11 +74,11 @@ this.errors = null; } - CompilationInfo ( final JavaSource javaSource, final FileObject fo, final JavaFileFilterImplementation filter, final JavacTaskImpl javacTask) throws IOException { + CompilationInfo ( final JavaSource javaSource, final ConversionInfo binding, final JavacTaskImpl javacTask) throws IOException { assert javaSource != null; this.javaSource = javaSource; - this.fo = fo; - this.jfo = fo != null ? javaSource.jfoProvider.createJavaFileObject(fo, filter) : null; + this.binding = binding; + this.jfo = this.binding != null ? javaSource.jfoProvider.createJavaFileObject(binding.getFileObject(), this.binding.getFilter()) : null; this.javacTask = javacTask; this.errors = new ArrayList(); } @@ -172,7 +170,7 @@ Elements elements = getElements(); assert elements != null; assert this.javaSource.rootFo != null; - String name = FileObjects.convertFolder2Package(FileObjects.stripExtension(FileUtil.getRelativePath(javaSource.rootFo, fo))); + String name = FileObjects.convertFolder2Package(FileObjects.stripExtension(FileUtil.getRelativePath(javaSource.rootFo, getFileObject()))); TypeElement e = ((JavacElements)elements).getTypeElementByBinaryName(name); if (e != null) { if (!isLocal(e)) { @@ -237,17 +235,28 @@ return javaSource.getClasspathInfo(); } - public FileObject getFileObject() { - return fo; + public FileObject getFileObject() { + return this.binding != null ? this.binding.getFileObject() : null; + } + + /**Return {@link ConversionInfo} binding virtual Java source and the real source. + * Please note that this method is needed only for clients that need to work + * in non-Java files (eg. JSP files) or in dialogs, like code completion. + * Most clients do not need to use {@link ConversionInfo}. + * + * @return ConversionInfo binding the virtual Java source and the real source. + */ + public ConversionInfo getConversionInfo() { + return binding; } public Document getDocument() throws IOException { - if (this.fo == null) { + if (this.binding == null || this.binding.getFileObject() == null) { return null; } - DataObject od = DataObject.find(fo); - EditorCookie ec = (EditorCookie) od.getCookie(EditorCookie.class); - if (ec != null) { + DataObject od = DataObject.find(this.binding.getFileObject()); + EditorCookie ec = od.getCookie(EditorCookie.class); + if (ec != null) { return ec.getDocument(); } else { return null; Index: java/source/src/org/netbeans/api/java/source/ConversionInfo.java diff -u /dev/null java/source/src/org/netbeans/api/java/source/ConversionInfo.java:1.1.2.2 --- /dev/null Thu Jun 14 02:35:22 2007 +++ java/source/src/org/netbeans/api/java/source/ConversionInfo.java Thu Jun 14 02:34:31 2007 @@ -0,0 +1,154 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.api.java.source; + +import java.io.Reader; +import java.io.Writer; +import java.util.concurrent.CopyOnWriteArrayList; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.JTextComponent; +import org.netbeans.modules.java.preprocessorbridge.spi.JavaFileFilterImplementation; +import org.netbeans.modules.java.preprocessorbridge.spi.JavaSourceProvider; +import org.openide.filesystems.FileObject; + +/**Binding between virtual Java source and the real source. + * Please note that this class is needed only for clients that need to work + * in non-Java files (eg. JSP files) or in dialogs, like code completion. + * Most clients do not need to use this class. + * + * @author Dusan Balek + */ +public final class ConversionInfo { + + private FileObject fo; + private JavaFileFilterImplementation filter; + private int offset; + private int length; + private JTextComponent component; + + ConversionInfo (final FileObject fo, final JavaFileFilterImplementation filter) { + this.fo = fo; + this.filter = filter; + } + + ConversionInfo (final FileObject fo, int offset, int length, final JTextComponent component) { + this.fo = fo; + this.offset = offset; + this.length = length; + this.component = component; + this.filter = new Filter(); + } + // API of the class -------------------------------------------------------- + + /**Compute position in the document for given position in the virtual + * Java source. + * + * @param javaSourcePosition position in the virtual Java Source + * @return position in the document + */ + public int getOriginalPosition(int javaSourcePosition) { + if (filter instanceof JavaSourceProvider.PositionTranslatingJavaFileFilterImplementation) { + return ((JavaSourceProvider.PositionTranslatingJavaFileFilterImplementation)filter).getOriginalPosition(javaSourcePosition); + } + return javaSourcePosition; + } + + /**Compute position in the virtual Java source for given position + * in the document. + * + * @param originalPosition position in the document + * @return position in the virtual Java source + */ + public int getJavaSourcePosition(int originalPosition) { + if (filter instanceof JavaSourceProvider.PositionTranslatingJavaFileFilterImplementation) { + return ((JavaSourceProvider.PositionTranslatingJavaFileFilterImplementation)filter).getJavaSourcePosition(originalPosition); + } + return originalPosition; + } + + // Package private methods ------------------------------------------------- + + JavaFileFilterImplementation getFilter() { + return filter; + } + + FileObject getFileObject() { + return fo; + } + + // Nested classes ---------------------------------------------------------- + + private class Filter implements JavaSourceProvider.PositionTranslatingJavaFileFilterImplementation, DocumentListener { + + CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); + + public Filter() { + component.getDocument().addDocumentListener(this); + } + + public Reader filterReader(Reader r) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public CharSequence filterCharSequence(CharSequence charSequence) { + return charSequence.subSequence(0, offset) + + component.getText() + + charSequence.subSequence(offset + length, charSequence.length()); + } + + public Writer filterWriter(Writer w) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void addChangeListener(ChangeListener listener) { + listeners.addIfAbsent(listener); + } + + public void removeChangeListener(ChangeListener listener) { + listeners.remove(listener); + } + + public int getOriginalPosition(int javaSourcePosition) { + if (javaSourcePosition < offset) + return -1; + int diff = javaSourcePosition - offset; + return diff <= component.getText().length() ? diff : -1; + } + + public int getJavaSourcePosition(int originalPosition) { + return offset + originalPosition; + } + + public void insertUpdate(DocumentEvent event) { + this.changedUpdate(event); + } + + public void removeUpdate(DocumentEvent event) { + this.changedUpdate(event); + } + + public void changedUpdate(DocumentEvent event) { + for (ChangeListener changeListener : listeners) + changeListener.stateChanged(null); + } + } +} Index: java/source/src/org/netbeans/api/java/source/JavaSource.java diff -u java/source/src/org/netbeans/api/java/source/JavaSource.java:1.60 java/source/src/org/netbeans/api/java/source/JavaSource.java:1.31.2.5 --- java/source/src/org/netbeans/api/java/source/JavaSource.java:1.60 Tue Jun 5 06:08:55 2007 +++ java/source/src/org/netbeans/api/java/source/JavaSource.java Thu Jun 14 02:34:32 2007 @@ -92,10 +92,13 @@ import javax.tools.JavaFileObject; import javax.tools.ToolProvider; import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.api.java.lexer.JavaTokenId; import org.netbeans.api.java.platform.JavaPlatformManager; import org.netbeans.api.java.queries.SourceLevelQuery; import org.netbeans.api.java.source.ClasspathInfo.PathKind; import org.netbeans.api.java.source.ModificationResult.Difference; +import org.netbeans.api.lexer.Language; +import org.netbeans.api.timers.TimesCollector; import org.netbeans.editor.Registry; import org.netbeans.modules.java.source.JavaFileFilterQuery; import org.netbeans.modules.java.source.builder.ASTService; @@ -106,6 +109,7 @@ import org.netbeans.modules.java.source.engine.RootTree; import org.netbeans.modules.java.source.parsing.FileObjects; import org.netbeans.modules.java.preprocessorbridge.spi.JavaFileFilterImplementation; +import org.netbeans.modules.java.preprocessorbridge.spi.JavaSourceProvider; import org.netbeans.modules.java.source.TreeLoader; import org.netbeans.modules.java.source.builder.DefaultEnvironment; import org.netbeans.modules.java.source.tasklist.CompilerSettings; @@ -129,6 +133,7 @@ import org.openide.loaders.DataObjectNotFoundException; import org.openide.modules.SpecificationVersion; import org.openide.util.Exceptions; +import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; import org.openide.util.WeakListeners; @@ -279,6 +284,8 @@ //Preprocessor support private FilterListener filterListener; + private ConversionInfo binding; + private static final Logger LOGGER = Logger.getLogger(JavaSource.class.getName()); static { @@ -298,14 +305,7 @@ if (files == null || cpInfo == null) { throw new IllegalArgumentException (); } - try { - return new JavaSource(cpInfo, files); - } catch (DataObjectNotFoundException donf) { - LOGGER.warning("Ignoring non existent file: " + FileUtil.getFileDisplayName(donf.getFileObject())); //NOI18N - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } - return null; + return create(cpInfo, null, files); } @@ -321,7 +321,18 @@ if (files == null || cpInfo == null) { throw new IllegalArgumentException (); } - return create(cpInfo, Arrays.asList(files)); + return create(cpInfo, null, Arrays.asList(files)); + } + + private static JavaSource create(final ClasspathInfo cpInfo, final ConversionInfo binding, final Collection files) throws IllegalArgumentException { + try { + return new JavaSource(cpInfo, binding, files); + } catch (DataObjectNotFoundException donf) { + Logger.getLogger("global").warning("Ignoring non existent file: " + FileUtil.getFileDisplayName(donf.getFileObject())); //NOI18N + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + return null; } private static Map> file2JavaSource = new WeakHashMap>(); @@ -340,43 +351,55 @@ if (!fileObject.isValid()) { return null; } - if ("text/x-java".equals(FileUtil.getMIMEType(fileObject)) || "java".equals(fileObject.getExt())) { //NOI18N - Reference ref = file2JavaSource.get(fileObject); - JavaSource js = ref != null ? ref.get() : null; - if (js == null) { - file2JavaSource.put(fileObject, new WeakReference(js = create(ClasspathInfo.create(fileObject), fileObject))); - } - return js; - } - if ("application/x-class-file".equals(FileUtil.getMIMEType(fileObject)) || "class".equals(fileObject.getExt())) { //NOI18N - ClassPath bootPath = ClassPath.getClassPath(fileObject, ClassPath.BOOT); - ClassPath compilePath = ClassPath.getClassPath(fileObject, ClassPath.COMPILE); - if (compilePath == null) { - compilePath = ClassPathSupport.createClassPath(new URL[0]); - } - ClassPath srcPath = ClassPath.getClassPath(fileObject, ClassPath.SOURCE); - if (srcPath == null) { - srcPath = ClassPathSupport.createClassPath(new URL[0]); - } - ClassPath execPath = ClassPath.getClassPath(fileObject, ClassPath.EXECUTE); - if (execPath != null) { - bootPath = ClassPathSupport.createProxyClassPath(execPath, bootPath); + + Reference ref = file2JavaSource.get(fileObject); + JavaSource js = ref != null ? ref.get() : null; + if (js == null) { + if ("application/x-class-file".equals(FileUtil.getMIMEType(fileObject)) || "class".equals(fileObject.getExt())) { //NOI18N + ClassPath bootPath = ClassPath.getClassPath(fileObject, ClassPath.BOOT); + ClassPath compilePath = ClassPath.getClassPath(fileObject, ClassPath.COMPILE); + if (compilePath == null) { + compilePath = ClassPathSupport.createClassPath(new URL[0]); + } + ClassPath srcPath = ClassPath.getClassPath(fileObject, ClassPath.SOURCE); + if (srcPath == null) { + srcPath = ClassPathSupport.createClassPath(new URL[0]); + } + ClassPath execPath = ClassPath.getClassPath(fileObject, ClassPath.EXECUTE); + if (execPath != null) { + bootPath = ClassPathSupport.createProxyClassPath(execPath, bootPath); + } + final ClasspathInfo info = ClasspathInfo.create(bootPath, compilePath, srcPath); + FileObject root = ClassPathSupport.createProxyClassPath(bootPath,compilePath,srcPath).findOwnerRoot(fileObject); + try { + js = new JavaSource (info,fileObject,root); + } catch (IOException ioe) { + Exceptions.printStackTrace(ioe); + } + } else { + ConversionInfo binding = null; + if (!"text/x-java".equals(FileUtil.getMIMEType(fileObject)) && !"java".equals(fileObject.getExt())) { //NOI18N + for (JavaSourceProvider provider : Lookup.getDefault().lookupAll(JavaSourceProvider.class)) { + JavaFileFilterImplementation filter = provider.forFileObject(fileObject); + if (filter != null) { + binding = new ConversionInfo(fileObject, filter); + break; + } + } + if (binding == null) + return null; } - final ClasspathInfo info = ClasspathInfo.create(bootPath, compilePath, srcPath); - FileObject root = ClassPathSupport.createProxyClassPath(bootPath,compilePath,srcPath).findOwnerRoot(fileObject); - try { - return new JavaSource (info,fileObject,root); - } catch (IOException ioe) { - Exceptions.printStackTrace(ioe); + js = create(ClasspathInfo.create(fileObject), binding, Collections.singletonList(fileObject)); } + file2JavaSource.put(fileObject, new WeakReference(js)); } - return null; + return js; } /** - * Returns a {@link JavaSource} instance associated to {@link org.openide.filesystems.FileObject} - * the {@link Document} was created from, it returns null if the {@link Document} is not - * associanted with data type providing the {@link JavaSource}. + * Returns a {@link JavaSource} instance associated to the given {@link javax.swing.Document}, + * it returns null if the {@link Document} is not + * associated with data type providing the {@link JavaSource}. * @param doc {@link Document} for which the {@link JavaSource} should be found/created. * @return {@link JavaSource} or null * @throws {@link IllegalArgumentException} if doc is null @@ -385,8 +408,7 @@ if (doc == null) { throw new IllegalArgumentException ("doc == null"); //NOI18N } - Reference ref = (Reference) doc.getProperty(JavaSource.class); - JavaSource js = ref != null ? (JavaSource) ref.get() : null; + JavaSource js = (JavaSource)doc.getProperty(JavaSource.class); if (js == null) { DataObject dObj = (DataObject)doc.getProperty(Document.StreamDescriptionProperty); if (dObj != null) @@ -396,14 +418,52 @@ } /** + * Bind given component and given file together. + * @param fileObject to bind + * @param offset position at which content of the component will be virtually placed + * @param length how many characters replace from the original file + * @param component component to bind + * @return {@link JavaSource} or null + * @throws {@link IllegalArgumentException} if fileObject is null + */ + public static JavaSource forFileObjectBinding(FileObject fileObject, int offset, int length, JTextComponent component) throws IllegalArgumentException { + if (fileObject == null) { + throw new IllegalArgumentException ("fileObject == null"); //NOI18N + } + if (!fileObject.isValid()) { + return null; + } + if (!"text/x-java".equals(FileUtil.getMIMEType(fileObject)) && !"java".equals(fileObject.getExt())) { //NOI18N + //TODO: JavaSource cannot be created for all kinds of files, but text/x-java is too restrictive: + return null; + } + Document doc = component.getDocument(); + + if (doc.getProperty(JavaSource.class) != null) { + throw new IllegalArgumentException("A JavaSource is already attached to the given component."); + } + + JavaSource js = create(ClasspathInfo.create(fileObject), new ConversionInfo(fileObject, offset, length, component), Collections.singletonList(fileObject)); + + doc.putProperty(JavaSource.class, js); + + if (doc.getProperty(Language.class) == null) { + doc.putProperty(Language.class, JavaTokenId.language()); + } + + return js; + } + + /** * Creates a new instance of JavaSource * @param files to create JavaSource for * @param cpInfo classpath info */ - private JavaSource (ClasspathInfo cpInfo, Collection files) throws IOException { + private JavaSource (ClasspathInfo cpInfo, ConversionInfo binding, Collection files) throws IOException { this.reparseDelay = REPARSE_DELAY; this.files = Collections.unmodifiableList(new ArrayList(files)); //Create a defensive copy, prevent modification this.fileChangeListener = new FileChangeListenerImpl (); + this.binding = binding; boolean multipleSources = this.files.size() > 1, filterAssigned = false; for (Iterator it = this.files.iterator(); it.hasNext();) { FileObject file = it.next(); @@ -417,7 +477,10 @@ } if (!filterAssigned) { filterAssigned = true; - JavaFileFilterImplementation filter = JavaFileFilterQuery.getFilter(file); + if (this.binding == null) { + this.binding = new ConversionInfo(file, JavaFileFilterQuery.getFilter(file)); + } + JavaFileFilterImplementation filter = this.binding.getFilter(); if (filter != null) { this.filterListener = new FilterListener (filter); } @@ -432,7 +495,7 @@ } } } - this.classpathInfo = cpInfo; + this.classpathInfo = cpInfo; if (this.files.size() == 1) { this.rootFo = classpathInfo.getClassPath(PathKind.SOURCE).findOwnerRoot(this.files.iterator().next()); } @@ -485,7 +548,7 @@ assert !holdsDocumentWriteLock(files) : "JavaSource.runCompileControlTask called under Document write lock."; //NOI18N boolean a = false; - assert a = true; + assert a = true; if (a && javax.swing.SwingUtilities.isEventDispatchThread()) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2]; if (warnedAboutRunInEQ.add(stackTraceElement)) { @@ -511,7 +574,7 @@ } } if (currentInfo == null) { - currentInfo = createCurrentInfo(this,this.files.isEmpty() ? null : this.files.iterator().next(), filterListener, null); + currentInfo = createCurrentInfo(this, binding, null); if (shared) { synchronized (this) { if (this.currentInfo == null || (this.flags & INVALID) != 0) { @@ -580,7 +643,7 @@ else { restarted = true; } - CompilationInfo ci = createCurrentInfo(this,activeFile,filterListener,jt); + CompilationInfo ci = createCurrentInfo(this, new ConversionInfo(activeFile, null), jt); task.run(new CompilationController(ci)); if (!ci.needsRestart) { jt = ci.getJavacTask(); @@ -731,7 +794,7 @@ } } if (currentInfo == null) { - currentInfo = createCurrentInfo(this,this.files.isEmpty() ? null : this.files.iterator().next(), filterListener, null); + currentInfo = createCurrentInfo(this, binding, null); synchronized (this) { if (this.currentInfo == null || (this.flags & INVALID) != 0) { this.currentInfo = currentInfo; @@ -790,7 +853,7 @@ else { restarted = true; } - CompilationInfo ci = createCurrentInfo(this,activeFile, filterListener, jt); + CompilationInfo ci = createCurrentInfo(this, new ConversionInfo(activeFile, null), jt); WorkingCopy copy = new WorkingCopy(ci); task.run(copy); if (!ci.needsRestart) { @@ -863,7 +926,7 @@ currentInfo = this.currentInfo; } if (currentInfo == null) { - currentInfo = createCurrentInfo (this, this.files.isEmpty() ? null : this.files.iterator().next(), filterListener, null); + currentInfo = createCurrentInfo (this, binding, null); } synchronized (this) { if (this.currentInfo == null) { @@ -1406,7 +1469,7 @@ try { //createCurrentInfo has to be out of synchronized block, it aquires an editor lock if (jsInvalid) { - ci = createCurrentInfo (js,js.files.isEmpty() ? null : js.files.iterator().next(), js.filterListener, null); + ci = createCurrentInfo (js, js.binding, null); synchronized (js) { if ((js.flags & INVALID) != 0) { js.currentInfo = ci; @@ -1709,11 +1772,8 @@ private final class FilterListener implements ChangeListener { - private final JavaFileFilterImplementation filter; - public FilterListener (final JavaFileFilterImplementation filter) { - this.filter = filter; - this.filter.addChangeListener(WeakListeners.change(this, this.filter)); + filter.addChangeListener(WeakListeners.change(this, filter)); } public void stateChanged(ChangeEvent event) { @@ -1721,10 +1781,12 @@ } } - private static CompilationInfo createCurrentInfo (final JavaSource js, final FileObject fo, final FilterListener filterListener, final JavacTaskImpl javac) throws IOException { - CompilationInfo info = new CompilationInfo (js, fo, filterListener == null ? null : filterListener.filter, javac); - Logger.getLogger("TIMER").log(Level.FINE, "CompilationInfo", - new Object[] {fo, info}); + private static CompilationInfo createCurrentInfo (final JavaSource js, final ConversionInfo binding, final JavacTaskImpl javac) throws IOException { + CompilationInfo info = new CompilationInfo (js, binding, javac); + if (binding != null) { + Logger.getLogger("TIMER").log(Level.FINE, "CompilationInfo", + new Object[] {binding.getFileObject(), info}); + } return info; } @@ -2168,7 +2230,7 @@ String dumpDir = System.getProperty("netbeans.user") + "/var/log/"; //NOI18N String src = info.getText(); FileObject file = info.getFileObject(); - String fileName = FileUtil.getFileDisplayName(info.getFileObject()); + String fileName = FileUtil.getFileDisplayName(file); String origName = file.getName(); File f = new File(dumpDir + origName + ".dump"); // NOI18N boolean dumpSucceeded = false; Index: java/source/src/org/netbeans/api/java/source/SourceUtils.java diff -u java/source/src/org/netbeans/api/java/source/SourceUtils.java:1.33 java/source/src/org/netbeans/api/java/source/SourceUtils.java:1.22.4.6 --- java/source/src/org/netbeans/api/java/source/SourceUtils.java:1.33 Thu May 17 07:47:18 2007 +++ java/source/src/org/netbeans/api/java/source/SourceUtils.java Wed Jun 13 12:54:57 2007 @@ -27,6 +27,7 @@ import java.util.*; import javax.lang.model.element.*; +import javax.lang.model.type.*; import javax.lang.model.element.VariableElement; import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; @@ -57,8 +58,11 @@ import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.net.URLEncoder; +import java.util.logging.Level; +import java.util.logging.Logger; import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.api.java.lexer.JavaTokenId; import org.netbeans.api.java.classpath.GlobalPathRegistry; import org.netbeans.api.java.queries.JavadocForBinaryQuery; import org.netbeans.api.java.queries.SourceForBinaryQuery; @@ -66,6 +70,9 @@ import org.netbeans.api.java.source.ClasspathInfo.PathKind; import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.api.java.source.WorkingCopy; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenId; +import org.netbeans.api.lexer.TokenSequence; import org.netbeans.modules.java.JavaDataLoader; import org.netbeans.modules.java.source.parsing.FileObjects; import org.netbeans.modules.java.source.usages.ClasspathInfoAccessor; @@ -75,8 +82,10 @@ import org.openide.filesystems.FileObject; import org.openide.filesystems.FileStateInvalidException; +import org.openide.filesystems.FileUtil; import org.openide.filesystems.URLMapper; import org.openide.util.Exceptions; +import org.openide.util.Parameters; import org.openide.util.RequestProcessor; /** @@ -120,6 +129,21 @@ return ((MethodSymbol)method).implementation((TypeSymbol)origin, com.sun.tools.javac.code.Types.instance(c), true); } + public static TokenSequence getJavaTokenSequence(final TokenHierarchy hierarchy, final int offset) { + if (hierarchy != null) { + TokenSequence ts = hierarchy.tokenSequence(); + while(ts != null && (ts.moveNext() || offset == 0)) { + ts.move(offset); + if (!ts.moveNext()) + return null; + if (ts.language() == JavaTokenId.language()) + return (TokenSequence)ts; + ts = ts.embedded(); + } + } + return null; + } + public static boolean checkTypesAssignable(CompilationInfo info, TypeMirror from, TypeMirror to) { Context c = ((JavacTaskImpl) info.getJavacTask()).getContext(); if (from.getKind() == TypeKind.DECLARED) { Index: java/source/src/org/netbeans/api/java/source/support/CaretAwareJavaSourceTaskFactory.java diff -u java/source/src/org/netbeans/api/java/source/support/CaretAwareJavaSourceTaskFactory.java:1.3 java/source/src/org/netbeans/api/java/source/support/CaretAwareJavaSourceTaskFactory.java:1.3.12.4 --- java/source/src/org/netbeans/api/java/source/support/CaretAwareJavaSourceTaskFactory.java:1.3 Thu Nov 2 02:13:40 2006 +++ java/source/src/org/netbeans/api/java/source/support/CaretAwareJavaSourceTaskFactory.java Thu Jun 14 01:43:21 2007 @@ -19,6 +19,7 @@ package org.netbeans.api.java.source.support; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,6 +32,7 @@ import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.api.java.source.JavaSource.Priority; import org.netbeans.api.java.source.JavaSourceTaskFactory; +import org.netbeans.api.java.source.SourceUtils; import org.openide.filesystems.FileObject; import org.openide.util.RequestProcessor; @@ -39,6 +41,9 @@ * opened and visible JTextComponents and reschedules the tasks as necessary. * * The tasks may access current caret position using {@link #getLastPosition} method. + * + * The files returned from the {@link #getFileObjects} method will be filtered using + * {@link org.netbeans.api.java.source.SourceUtils#filterSupportedMIMETypes}. * * @author Jan Lahoda */ @@ -48,6 +53,7 @@ private static final RequestProcessor WORKER = new RequestProcessor("CaretAwareJavaSourceTaskFactory worker"); private int timeout; + private String[] supportedMimeTypes; /**Construct the CaretAwareJavaSourceTaskFactory with given {@link Phase} and {@link Priority}. * @@ -55,21 +61,32 @@ * @param priority priority to use for tasks created by {@link #createTask} */ public CaretAwareJavaSourceTaskFactory(Phase phase, Priority priority) { + this(phase, priority, (String[]) null); + } + + /**Construct the CaretAwareJavaSourceTaskFactory with given {@link Phase} and {@link Priority}. + * + * @param phase phase to use for tasks created by {@link #createTask} + * @param priority priority to use for tasks created by {@link #createTask} + * @param supportedMimeTypes a list of mime types on which the tasks created by this factory should be run + */ + public CaretAwareJavaSourceTaskFactory(Phase phase, Priority priority, String... supportedMimeTypes) { super(phase, priority); //XXX: weak, or something like this: OpenedEditors.getDefault().addChangeListener(new ChangeListenerImpl()); this.timeout = DEFAULT_RESCHEDULE_TIMEOUT; + this.supportedMimeTypes = supportedMimeTypes != null ? supportedMimeTypes.clone() : null; } /**@inheritDoc*/ public List getFileObjects() { - List files = new ArrayList(OpenedEditors.getDefault().getVisibleEditorsFiles()); + List files = OpenedEditors.filterSupportedMIMETypes(OpenedEditors.getDefault().getVisibleEditorsFiles(), supportedMimeTypes); return files; } - private Map component2Listener = new HashMap(); - private static Map file2LastPosition = new WeakHashMap(); + private Map component2Listener = new HashMap(); + private static Map file2LastPosition = new WeakHashMap(); /**Returns current caret position in current {@link JTextComponent} for a given file. * Index: java/source/src/org/netbeans/api/java/source/support/EditorAwareJavaSourceTaskFactory.java diff -u java/source/src/org/netbeans/api/java/source/support/EditorAwareJavaSourceTaskFactory.java:1.3 java/source/src/org/netbeans/api/java/source/support/EditorAwareJavaSourceTaskFactory.java:1.3.12.4 --- java/source/src/org/netbeans/api/java/source/support/EditorAwareJavaSourceTaskFactory.java:1.3 Thu Nov 2 02:13:41 2006 +++ java/source/src/org/netbeans/api/java/source/support/EditorAwareJavaSourceTaskFactory.java Thu Jun 14 01:43:21 2007 @@ -18,39 +18,52 @@ */ package org.netbeans.api.java.source.support; -import java.util.ArrayList; import java.util.List; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import javax.swing.text.Document; -import javax.swing.text.JTextComponent; import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.api.java.source.JavaSource.Priority; import org.netbeans.api.java.source.JavaSourceTaskFactory; +import org.netbeans.api.java.source.SourceUtils; import org.openide.filesystems.FileObject; -import org.openide.loaders.DataObject; /**A {@link JavaSourceTaskFactorySupport} that registers tasks to all files that are * opened in the editor and are visible. * + * The files returned from the {@link #getFileObjects} method will be filtered using + * {@link org.netbeans.api.java.source.SourceUtils#filterSupportedMIMETypes}. + * * @author Jan Lahoda */ public abstract class EditorAwareJavaSourceTaskFactory extends JavaSourceTaskFactory { + private String[] supportedMimeTypes; + /**Construct the EditorAwareJavaSourceTaskFactory with given {@link Phase} and {@link Priority}. * * @param phase phase to use for tasks created by {@link #createTask} * @param priority priority to use for tasks created by {@link #createTask} */ protected EditorAwareJavaSourceTaskFactory(Phase phase, Priority priority) { + this(phase, priority, (String[]) null); + } + + /**Construct the EditorAwareJavaSourceTaskFactory with given {@link Phase} and {@link Priority}. + * + * @param phase phase to use for tasks created by {@link #createTask} + * @param priority priority to use for tasks created by {@link #createTask} + * @param supportedMimeTypes a list of mime types on which the tasks created by this factory should be run + */ + protected EditorAwareJavaSourceTaskFactory(Phase phase, Priority priority, String... supportedMimeTypes) { super(phase, priority); //XXX: weak, or something like this: OpenedEditors.getDefault().addChangeListener(new ChangeListenerImpl()); + this.supportedMimeTypes = supportedMimeTypes != null ? supportedMimeTypes.clone() : null; } /**@inheritDoc*/ public List getFileObjects() { - List files = new ArrayList(OpenedEditors.getDefault().getVisibleEditorsFiles()); + List files = OpenedEditors.filterSupportedMIMETypes(OpenedEditors.getDefault().getVisibleEditorsFiles(), supportedMimeTypes); return files; } Index: java/source/src/org/netbeans/api/java/source/support/LookupBasedJavaSourceTaskFactory.java diff -u java/source/src/org/netbeans/api/java/source/support/LookupBasedJavaSourceTaskFactory.java:1.3 java/source/src/org/netbeans/api/java/source/support/LookupBasedJavaSourceTaskFactory.java:1.3.12.4 --- java/source/src/org/netbeans/api/java/source/support/LookupBasedJavaSourceTaskFactory.java:1.3 Thu Nov 2 02:13:40 2006 +++ java/source/src/org/netbeans/api/java/source/support/LookupBasedJavaSourceTaskFactory.java Thu Jun 14 01:43:21 2007 @@ -21,12 +21,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.swing.event.ChangeEvent; import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.api.java.source.JavaSource.Priority; import org.netbeans.api.java.source.JavaSourceTaskFactory; +import org.netbeans.api.java.source.SourceUtils; import org.openide.filesystems.FileObject; import org.openide.loaders.DataObject; import org.openide.nodes.Node; @@ -42,6 +44,9 @@ * in the lookup. If {@link Node}(s) are found, its/their lookup is searched for * {@link FileObject} and {@link DataObject}. * + * The files returned from the {@link #getFileObjects} method will be filtered using + * {@link org.netbeans.api.java.source.SourceUtils#filterSupportedMIMETypes}. + * * @author Jan Lahoda */ public abstract class LookupBasedJavaSourceTaskFactory extends JavaSourceTaskFactory { @@ -52,6 +57,8 @@ private List currentFiles; private LookupListener listener; + + private String[] supportedMimeTypes; /**Construct the LookupBasedJavaSourceTaskFactory with given {@link Phase} and {@link Priority}. * @@ -59,9 +66,19 @@ * @param priority priority to use for tasks created by {@link #createTask} */ public LookupBasedJavaSourceTaskFactory(Phase phase, Priority priority) { + this(phase, priority, (String[]) null); + } + + /**Construct the LookupBasedJavaSourceTaskFactory with given {@link Phase} and {@link Priority}. + * + * @param phase phase to use for tasks created by {@link #createTask} + * @param priority priority to use for tasks created by {@link #createTask} + */ + public LookupBasedJavaSourceTaskFactory(Phase phase, Priority priority, String... supportedMimeTypes) { super(phase, priority); currentFiles = Collections.emptyList(); listener = new LookupListenerImpl(); + this.supportedMimeTypes = supportedMimeTypes != null ? supportedMimeTypes.clone() : null; } /**Sets a new {@link Lookup} to search. @@ -91,7 +108,7 @@ } private synchronized void updateCurrentFiles() { - Set newCurrentFiles = new HashSet(); + Set newCurrentFiles = new HashSet(); newCurrentFiles.addAll(fileObjectResult.allInstances()); @@ -107,7 +124,7 @@ } } - currentFiles = new ArrayList(newCurrentFiles); + currentFiles = OpenedEditors.filterSupportedMIMETypes(new LinkedList(newCurrentFiles), supportedMimeTypes); lookupContentChanged(); } Index: java/source/src/org/netbeans/api/java/source/support/OpenedEditors.java diff -u java/source/src/org/netbeans/api/java/source/support/OpenedEditors.java:1.3 java/source/src/org/netbeans/api/java/source/support/OpenedEditors.java:1.3.12.2 --- java/source/src/org/netbeans/api/java/source/support/OpenedEditors.java:1.3 Thu Nov 2 02:13:41 2006 +++ java/source/src/org/netbeans/api/java/source/support/OpenedEditors.java Wed Jun 13 12:54:55 2007 @@ -21,19 +21,26 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.JEditorPane; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.text.Document; import javax.swing.text.JTextComponent; +import org.netbeans.api.java.source.JavaSource; import org.netbeans.editor.Registry; import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; +import org.openide.util.Parameters; /** * @@ -98,7 +105,8 @@ JTextComponent editor = Registry.getMostActiveComponent(); - if (editor instanceof JEditorPane && "text/x-java".equals(((JEditorPane) editor).getContentType())) { + FileObject fo = getFileObject(editor); + if (editor instanceof JEditorPane && fo != null && JavaSource.forFileObject(fo) != null) { visibleEditors.add(editor); } @@ -131,4 +139,103 @@ return null; } + /**Checks if the given file is supported. See {@link #filterSupportedMIMETypes} + * for more details. + * + * @param file to check + * @param type the type to check for the {@link SupportedMimeTypes} annotation + * @return true if and only if the given file is supported (see {@link #filterSupportedMIMETypes}) + * @throws NullPointerException if file == null or type == null + */ + public static boolean isSupported(FileObject file, String... mimeTypes) throws NullPointerException { + Parameters.notNull("files", file); + + return !filterSupportedMIMETypes(Collections.singletonList(file), mimeTypes).isEmpty(); + } + + /**Filter unsupported files from the files parameter. A supported file + * f is defined as follows: + *
    + *
  • JavaSource.forFileObject(f) != null
  • + *
  • If the type is annotated with the {@link SupportedMimeTypes} annotation, + * the file is supported if type.getAnnotation(SupportedMimeTypes.class).value() + * contains FileUtil.getMIMEType(f). + *
  • + *
  • If the type is not annotated with the {@link SupportedMimeTypes} annotation, + * the file is supported if FileUtil.getMIMEType(f) == "text/x-java". + *
+ * + * @param files the list of files to filter + * @param type the type to check for the {@link SupportedMimeTypes} annotation + * @return list of files that are supported (see above). + * @throws NullPointerException if files == null or type == null + */ + public static List filterSupportedMIMETypes(Collection files, String... mimeTypes) throws NullPointerException { + Parameters.notNull("files", files); + + boolean allowJavaExtension = false; + + if (mimeTypes == null) { + mimeTypes = new String[] {"text/x-java"}; + allowJavaExtension = true; + } + + List mimeTypesList = Arrays.asList(mimeTypes); + boolean allowAll = mimeTypesList.contains("*"); + List result = new LinkedList(); + + Logger.getLogger(OpenedEditors.class.getName()).log(Level.FINER, "mimeTypesList={0}", mimeTypesList); + + for (FileObject f : files) { + Logger.getLogger(OpenedEditors.class.getName()).log(Level.FINER, "analyzing={0}", f); + + if (JavaSource.forFileObject(f) == null) + continue; + + if (allowAll) { + result.add(f); + continue; + } + + if (allowJavaExtension && "java".equals(f.getExt())) { + result.add(f); + continue; + } + + String fileMimeType = FileUtil.getMIMEType(f); + + Logger.getLogger(OpenedEditors.class.getName()).log(Level.FINER, "fileMimeType={0}", fileMimeType); + + if (mimeTypesList.contains(fileMimeType)) { + result.add(f); + continue; + } + + String shorterMimeType = fileMimeType; + + while (true) { + int slash = shorterMimeType.indexOf('/'); + + if (slash == (-1)) + break; + + int plus = shorterMimeType.indexOf('+', slash); + + if (plus == (-1)) + break; + + shorterMimeType = shorterMimeType.substring(0, slash + 1) + shorterMimeType.substring(plus + 1); + + if (mimeTypesList.contains(shorterMimeType)) { + result.add(f); + break; + } + } + } + + Logger.getLogger(OpenedEditors.class.getName()).log(Level.FINE, "filter({0}, {1})={2}", new Object[] {files, mimeTypesList, result}); + + return result; + } + } Index: java/source/src/org/netbeans/modules/java/source/parsing/SourceFileObject.java diff -u java/source/src/org/netbeans/modules/java/source/parsing/SourceFileObject.java:1.12 java/source/src/org/netbeans/modules/java/source/parsing/SourceFileObject.java:1.5.2.3 --- java/source/src/org/netbeans/modules/java/source/parsing/SourceFileObject.java:1.12 Tue Jun 5 06:08:55 2007 +++ java/source/src/org/netbeans/modules/java/source/parsing/SourceFileObject.java Thu Jun 14 01:43:25 2007 @@ -366,9 +366,13 @@ doc.render(new Runnable() { public void run () { try { - int len = doc.getLength(); + CharSequence text = doc.getText(0, doc.getLength()); + if (filter != null) { + text = filter.filterCharSequence(text); + } + int len = text.length(); result[0] = new char[len+1]; - doc.getText(0,len).getChars(0,len,result[0],0); + text.toString().getChars(0,len,result[0],0); length[0] = len; } catch (BadLocationException e) { ErrorManager.getDefault().notify(e); Index: java/source/test/unit/src/org/netbeans/api/java/source/JavaSourceTest.java diff -u java/source/test/unit/src/org/netbeans/api/java/source/JavaSourceTest.java:1.13 java/source/test/unit/src/org/netbeans/api/java/source/JavaSourceTest.java:1.7.8.4 --- java/source/test/unit/src/org/netbeans/api/java/source/JavaSourceTest.java:1.13 Mon May 21 01:35:56 2007 +++ java/source/test/unit/src/org/netbeans/api/java/source/JavaSourceTest.java Thu Jun 14 01:43:35 2007 @@ -1109,7 +1109,7 @@ js.runUserActionTask(new CancellableTask() { public void run(CompilationController cc) throws IOException { - files.add(cc.getFileObject()); + files.add(cc.getConversionInfo().getFileObject()); cc.toPhase(Phase.RESOLVED); } public void cancel() {} @@ -1121,7 +1121,7 @@ js.runModificationTask(new CancellableTask() { public void run(WorkingCopy cc) throws IOException { - files.add(cc.getFileObject()); + files.add(cc.getConversionInfo().getFileObject()); cc.toPhase(Phase.RESOLVED); } public void cancel() {}