diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java index 033835abbf96..7af1a7c359db 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java @@ -34,6 +34,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.HashMap; import org.apache.oro.text.regex.*; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -229,14 +230,12 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements } } - if (ApplicationManagerEx.getApplicationEx().isInternal()) { - try { - CompilerAPICompiler inprocessJavaCompiler = new CompilerAPICompiler(myProject); - myRegisteredCompilers.add(inprocessJavaCompiler); - } - catch (NoClassDefFoundError e) { - // wrong JDK - } + try { + CompilerAPICompiler inprocessJavaCompiler = new CompilerAPICompiler(myProject); + myRegisteredCompilers.add(inprocessJavaCompiler); + } + catch (NoClassDefFoundError e) { + // wrong JDK } } @@ -534,7 +533,7 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements myObtainProcessorsFromClasspath = Boolean.valueOf(annotationProcessingSettings.getAttributeValue("useClasspath", "true")); final StringBuilder pathBuilder = new StringBuilder(); - for (Element pathElement : ((Collection)annotationProcessingSettings.getChildren("processorPath"))) { + for (Element pathElement : (Collection)annotationProcessingSettings.getChildren("processorPath")) { final String path = pathElement.getAttributeValue("value"); if (path != null) { if (pathBuilder.length() > 0) { @@ -546,7 +545,7 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements myProcessorPath = pathBuilder.toString(); myProcessorsMap.clear(); - for (Element processorChild : ((Collection)annotationProcessingSettings.getChildren("processor"))) { + for (Element processorChild : (Collection)annotationProcessingSettings.getChildren("processor")) { final String name = processorChild.getAttributeValue("name"); final String options = processorChild.getAttributeValue("options", ""); myProcessorsMap.put(name, options); @@ -555,8 +554,8 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements myModuleNames.clear(); final Collection processed = (Collection)annotationProcessingSettings.getChildren("processModule"); - if (processed.size() > 0) { - final Map moduleMap = new com.intellij.util.containers.HashMap(); + if (!processed.isEmpty()) { + final Map moduleMap = new HashMap(); for (Module module : myModuleManager.getModules()) { moduleMap.put(module.getName(), module); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 30816ea69299..ba4ee0acb31e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -298,6 +298,7 @@ public class CompileDriver { } catch (IOException e) { context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.exception", e.getMessage()), null, -1, -1); + LOG.info(e); } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java index 3cc3def8a9ad..3aefed8225c9 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java @@ -47,6 +47,7 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -62,7 +63,6 @@ import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.*; import java.util.concurrent.ArrayBlockingQueue; @@ -85,7 +85,7 @@ public class BackendCompilerWrapper { private final Map myModuleToTempDirMap = new THashMap(); private final ProjectFileIndex myProjectFileIndex; @NonNls private static final String PACKAGE_ANNOTATION_FILE_NAME = "package-info.java"; - private static final FileObject myStopThreadToken = new FileObject(null,null); + private static final FileObject myStopThreadToken = new FileObject(new File(""), new byte[0]); private long myCompilationDuration = 0L; public final Map> myFileNameToSourceMap= new THashMap>(); @@ -180,7 +180,7 @@ public class BackendCompilerWrapper { myFilesToRecompile.addAll(allDependent); } final List outputs = processPackageInfoFiles(); - if (myFilesToRecompile.size() > 0 || outputs.size() > 0) { + if (!myFilesToRecompile.isEmpty() || !outputs.isEmpty()) { mySink.add(null, outputs, VfsUtil.toVirtualFileArray(myFilesToRecompile)); } } @@ -458,7 +458,7 @@ public class BackendCompilerWrapper { exitValue = process.exitValue(); } finally { - myCompilationDuration += (System.currentTimeMillis() - compilationStart); + myCompilationDuration += System.currentTimeMillis() - compilationStart; if (errorParsingThread != null) { errorParsingThread.setProcessTerminated(true); } @@ -880,7 +880,7 @@ public class BackendCompilerWrapper { myAddNotNullAssertions = CompilerWorkspaceConfiguration.getInstance(myProject).ASSERT_NOT_NULL; } - volatile boolean processing; + private volatile boolean processing; public void run() { processing = true; try { @@ -897,7 +897,9 @@ public class BackendCompilerWrapper { catch (CacheCorruptedException e) { myError = e; } - processing = false; + finally { + processing = false; + } } public void addPath(FileObject path) throws CacheCorruptedException { @@ -927,7 +929,6 @@ public class BackendCompilerWrapper { putName(sourceFileName, newClassQName, relativePathToSource, path); boolean haveToInstrument = myAddNotNullAssertions && hasNotNullAnnotations(newClassesCache, dependencyCache.getSymbolTable(), newClassQName); - boolean fileContentChanged = false; if (haveToInstrument) { try { ClassReader reader = new ClassReader(fileContent, 0, fileContent.length); @@ -936,8 +937,7 @@ public class BackendCompilerWrapper { final NotNullVerifyingInstrumenter instrumenter = new NotNullVerifyingInstrumenter(writer); reader.accept(instrumenter, 0); if (instrumenter.isModification()) { - fileContent = writer.toByteArray(); - fileContentChanged = true; + fileObject = new FileObject(file, writer.toByteArray()); } } catch (Exception ignored) { @@ -945,9 +945,7 @@ public class BackendCompilerWrapper { } } - if (fileContentChanged || !fileObject.isSaved()) { - writeFile(file, fileContent); - } + fileObject.save(); } else { final String _path = FileUtil.toSystemIndependentName(path); @@ -960,34 +958,20 @@ public class BackendCompilerWrapper { } } catch (ClsFormatException e) { - String message; final String m = e.getMessage(); - if (m == null || "".equals(m)) { - message = CompilerBundle.message("error.bad.class.file.format", path); - } - else { - message = CompilerBundle.message("error.bad.class.file.format", m + "\n" + path); - } + String message = CompilerBundle.message("error.bad.class.file.format", StringUtil.isEmpty(m) ? path : m + "\n" + path); myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1); + LOG.info(e); } catch (IOException e) { myCompileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + LOG.info(e); } finally { myClassesCount++; updateStatistics(); } } - - private void writeFile(File file, byte[] fileContent) throws IOException { - try { - FileUtil.writeToFile(file, fileContent); - } - catch (FileNotFoundException e) { - FileUtil.createParentDirs(file); - FileUtil.writeToFile(file, fileContent); - } - } } private static boolean hasNotNullAnnotations(final Cache cache, final SymbolTable symbolTable, final int className) throws CacheCorruptedException { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java index 100fbbe643cc..2c1fba6db054 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -81,8 +81,10 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { myError = e; LOG.info(e); } - killProcess(); - processing = false; + finally { + killProcess(); + processing = false; + } } private void killProcess() { @@ -115,6 +117,9 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { } public final void fileGenerated(FileObject path) { + // javac first logs file generated, then starts to write the file to disk, + // so this thread sometimes can stumble on not yet existing file, + // hence this complex logic FileObject previousPath = myClassFileToProcess; myClassFileToProcess = path; if (previousPath != null) { @@ -123,6 +128,7 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { } catch (CacheCorruptedException e) { myError = e; + LOG.info(e); killProcess(); } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/FileObject.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/FileObject.java index e04e473da226..e9483bcaa98d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/FileObject.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/FileObject.java @@ -16,48 +16,57 @@ package com.intellij.compiler.impl.javaCompiler; import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; /** * @author cdr */ public class FileObject { - private final static byte[] NOT_LOADED = new byte[0]; + private static final byte[] NOT_LOADED = new byte[0]; private final File myFile; - private byte[] myContent; - private final boolean mySaved; + private final byte[] myContent; - public FileObject(File file, byte[] content) { + public FileObject(@NotNull File file, @NotNull byte[] content) { myFile = file; myContent = content; - mySaved = false; } public FileObject(File file) { myFile = file; myContent = NOT_LOADED; - mySaved = true; } public File getFile() { return myFile; } - public byte[] getContent() { + public byte[] getContent() throws IOException { if (myContent == NOT_LOADED) { - try{ - return FileUtil.loadFileBytes(myFile); - } - catch(IOException ignored){ - } + return FileUtil.loadFileBytes(myFile); } return myContent; } - public boolean isSaved() { - return mySaved; + public void save() throws IOException { + if (myContent == NOT_LOADED) { + return; // already on disk + } + try { + FileUtil.writeToFile(myFile, myContent); + } + catch (FileNotFoundException e) { + FileUtil.createParentDirs(myFile); + FileUtil.writeToFile(myFile, myContent); + } + } + + @Override + public String toString() { + return getFile().toString(); } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java index 60043afb6524..20601f3abc23 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java @@ -64,6 +64,7 @@ public class JavaCompiler implements TranslatingCompiler { } catch (CompilerException e) { context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + LOG.info(e); } catch (CacheCorruptedException e) { LOG.info(e); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompAPIDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompAPIDriver.java index 4273e8174fbb..be4f6f170320 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompAPIDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompAPIDriver.java @@ -16,15 +16,14 @@ package com.intellij.compiler.impl.javaCompiler.api; import com.intellij.compiler.OutputParser; -import com.sun.source.util.JavacTask; -import com.sun.source.util.TaskEvent; -import com.sun.source.util.TaskListener; +import com.sun.source.util.*; import com.sun.tools.javac.api.JavacTool; import org.jetbrains.annotations.NotNull; import javax.tools.*; import java.io.File; import java.io.PrintWriter; +import java.net.URI; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -50,13 +49,16 @@ public class CompAPIDriver { private volatile boolean compiling; private static final PrintWriter COMPILER_ERRORS = new PrintWriter(System.err); + public CompAPIDriver() { + } + public void compile(List commandLine, List paths, final String outputDir) { myOutputDir = outputDir; compiling = true; assert myCompilationResults.isEmpty(); JavaCompiler compiler = JavacTool.create(); //use current classloader - StandardJavaFileManager manager = new MyFileManager(this, outputDir); + MyFileManager manager = new MyFileManager(this, outputDir); Iterable input = manager.getJavaFileObjectsFromFiles(paths); @@ -109,7 +111,7 @@ public class CompAPIDriver { } private volatile boolean processing; - public boolean processAll(@NotNull OutputParser.Callback callback) { + public void processAll(@NotNull OutputParser.Callback callback) { try { processing = true; while (true) { @@ -120,8 +122,9 @@ public class CompAPIDriver { } catch (InterruptedException ignored) { } - processing = false; - return false; + finally { + processing = false; + } } public void finish() { @@ -131,9 +134,11 @@ public class CompAPIDriver { myCompilationResults.clear(); } - public void offer(CompilationEvent compilationEvent) { - myCompilationResults.offer(compilationEvent); + public void offerClassFile(URI uri, byte[] bytes) { + CompilationEvent event = CompilationEvent.generateClass(uri, bytes); + myCompilationResults.offer(event); } + } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilationEvent.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilationEvent.java index 848d58cc1ae9..38c1726c76e0 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilationEvent.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilationEvent.java @@ -17,15 +17,15 @@ package com.intellij.compiler.impl.javaCompiler.api; import com.intellij.compiler.OutputParser; import com.intellij.compiler.impl.javaCompiler.FileObject; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtil; +import org.jetbrains.annotations.NonNls; -import javax.tools.JavaFileObject; -import javax.tools.Diagnostic; -import java.net.URI; +import javax.tools.*; import java.io.File; +import java.net.URI; /** * @author cdr @@ -40,6 +40,7 @@ abstract class CompilationEvent { showProgressFor(title, fileObject.toUri(), callback); } + @NonNls @Override public String toString() { return "Progress: "+title+" "+fileObject.toUri(); @@ -59,6 +60,7 @@ abstract class CompilationEvent { File file = new File(uri.getPath()); callback.fileGenerated(new FileObject(file,bytes)); } + @NonNls @Override public String toString() { return "Write: "+uri; @@ -93,6 +95,7 @@ abstract class CompilationEvent { : CompilerMessageCategory.INFORMATION; callback.message(category, message, url, (int)diagnostic.getLineNumber(), (int)diagnostic.getColumnNumber()); } + @NonNls @Override public String toString() { return "Diagnostic: "+diagnostic; @@ -106,6 +109,7 @@ abstract class CompilationEvent { protected void process(OutputParser.Callback callback) { callback.fileProcessed(null); } + @NonNls @Override public String toString() { return "Processed"; diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java index 5aeb2cbd4553..8e87a8c8da11 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java @@ -27,6 +27,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; @@ -51,6 +52,7 @@ import java.util.*; public class CompilerAPICompiler implements BackendCompiler { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.api.CompilerAPICompiler"); private final Project myProject; private static final Set COMPILABLE_TYPES = Collections.singleton(StdFileTypes.JAVA); @@ -94,7 +96,7 @@ public class CompilerAPICompiler implements BackendCompiler { @NotNull public String getPresentableName() { - return "Javac in-process (Java6 only)"; + return "Javac in-process (Java6+ only)"; } @NotNull @@ -111,7 +113,8 @@ public class CompilerAPICompiler implements BackendCompiler { public OutputParser createErrorParser(@NotNull final String outputDir, final Process process) { return new OutputParser() { public boolean processMessageLine(Callback callback) { - return ((MyProcess)process).myCompAPIDriver.processAll(callback); + ((MyProcess)process).myCompAPIDriver.processAll(callback); + return false; } }; } @@ -200,6 +203,7 @@ public class CompilerAPICompiler implements BackendCompiler { } catch (Exception e) { myCompileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + LOG.info(e); myExitCode = -1; return -1; } @@ -214,4 +218,4 @@ public class CompilerAPICompiler implements BackendCompiler { return myChunk.toString(); } } -} \ No newline at end of file +} diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/FileVirtualObject.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/FileVirtualObject.java index 1ed2ca17410f..0537997cc911 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/FileVirtualObject.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/FileVirtualObject.java @@ -18,8 +18,7 @@ package com.intellij.compiler.impl.javaCompiler.api; import com.intellij.openapi.fileEditor.impl.LoadTextUtil; import com.intellij.openapi.vfs.VirtualFile; -import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; +import javax.tools.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -28,6 +27,7 @@ import java.net.URI; /** * @author cdr */ +@SuppressWarnings({"Since15"}) public abstract class FileVirtualObject extends SimpleJavaFileObject { public FileVirtualObject(URI uri, Kind kind) { super(uri, kind); @@ -64,5 +64,4 @@ public abstract class FileVirtualObject extends SimpleJavaFileObject { public boolean equals(Object obj) { return obj instanceof JavaFileObject && toUri().equals(((JavaFileObject)obj).toUri()); } - } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java new file mode 100644 index 000000000000..bbb48baf0497 --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.compiler.impl.javaCompiler.api; + +import com.intellij.openapi.util.io.FileUtil; + +import javax.tools.*; +import java.io.*; + +/** +* User: cdr +*/ +@SuppressWarnings({"Since15"}) +class JavaIoFile extends SimpleJavaFileObject { + private final File myFile; + + JavaIoFile(File file, Kind kind) { + super(file.toURI(), kind); + myFile = file; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return new String(FileUtil.loadFileText(myFile)); + } + + @Override + public InputStream openInputStream() throws IOException { + return new BufferedInputStream(new FileInputStream(myFile)); + } + + @Override + public OutputStream openOutputStream() throws IOException { + return new BufferedOutputStream(new FileOutputStream(myFile)); + } + + @Override + public String toString() { + return toUri().toString(); + } + + @Override + public int hashCode() { + return toUri().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof JavaFileObject && toUri().equals(((JavaFileObject)obj).toUri()); + } +} diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualByIoFile.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualByIoFile.java new file mode 100644 index 000000000000..6fd106528aab --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualByIoFile.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.compiler.impl.javaCompiler.api; + +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; + +/** + * User: cdr + */ +@SuppressWarnings({"Since15"}) +class JavaVirtualByIoFile extends FileVirtualObject { + private final File myFile; + + protected JavaVirtualByIoFile(File file, Kind kind) { + super(file.toURI(), kind); + myFile = file; + } + + protected VirtualFile getVirtualFile() { + return LocalFileSystem.getInstance().findFileByIoFile(myFile); + } +} \ No newline at end of file diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualFile.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualFile.java new file mode 100644 index 000000000000..abe8f24cda58 --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualFile.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.compiler.impl.javaCompiler.api; + +import com.intellij.openapi.vfs.VirtualFile; + +/** +* User: cdr +*/ +@SuppressWarnings({"Since15"}) +class JavaVirtualFile extends FileVirtualObject { + private final VirtualFile myFile; + + JavaVirtualFile(VirtualFile file, Kind kind) { + super(MyFileManager.createUri(file.getUrl()), kind); + myFile = file; + } + + protected VirtualFile getVirtualFile() { + return myFile; + } +} diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java index 528244274ba5..166145e53965 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java @@ -15,6 +15,7 @@ */ package com.intellij.compiler.impl.javaCompiler.api; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; @@ -23,11 +24,10 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.SmartList; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.DefaultFileManager; +import gnu.trove.THashSet; +import gnu.trove.TObjectHashingStrategy; -import javax.tools.FileObject; -import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; -import java.io.ByteArrayOutputStream; +import javax.tools.*; import java.io.File; import java.io.IOException; import java.net.URI; @@ -36,7 +36,10 @@ import java.util.*; /** * @author cdr */ +@SuppressWarnings({"Since15"}) class MyFileManager extends DefaultFileManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.api.MyFileManager"); + private final String myOutputDir; private final CompAPIDriver myCompAPIDriver; @@ -48,100 +51,34 @@ class MyFileManager extends DefaultFileManager { @Override public Iterable getJavaFileObjectsFromFiles(Iterable files) { - //return super.getJavaFileObjectsFromFiles(files); int size = ((Collection)files).size(); List result = new ArrayList(size); for (File file : files) { - result.add(getSource(file)); + JavaFileObject fileObject = new JavaVirtualByIoFile(file, JavaFileObject.Kind.SOURCE); + result.add(fileObject); } return result; } - private JavaFileObject getSource(File file) { - JavaFileObject fileObject = new JavaIoFile(file); - return fileObject; - } - private JavaFileObject getOutput(URI uri) { - JavaFileObject fileObject = new Output(uri) { - protected void offerClassFile(URI uri, byte[] bytes) { - myCompAPIDriver.offer(CompilationEvent.generateClass(uri, bytes)); - } - }; - return fileObject; - } - @Override public JavaFileObject getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject fileObject) { - return getOutput(toURI(myOutputDir,name)); + URI uri = toURI(myOutputDir, name); + return new Output(uri, myCompAPIDriver); } - private static class JavaIoFile extends FileVirtualObject { - private final File myFile; - - protected JavaIoFile(File file) { - super(file.toURI(), Kind.SOURCE); - myFile = file; - } - - protected VirtualFile getVirtualFile() { - return LocalFileSystem.getInstance().findFileByIoFile(myFile); - } - } - - private static URI createUri(String url) { + static URI createUri(String url) { return URI.create(url.replaceAll(" ","%20")); } - private static class JavaVirtualFile extends FileVirtualObject { - private final VirtualFile myFile; - - protected JavaVirtualFile(VirtualFile file, Kind source) { - super(createUri(file.getUrl()), source); - myFile = file; - } - - protected VirtualFile getVirtualFile() { - return myFile; - } - } - - private abstract static class Output extends SimpleJavaFileObject { - private Output(URI uri) { - super(uri, Kind.CLASS); - } - - @Override - public ByteArrayOutputStream openOutputStream() { - return new ByteArrayOutputStream() { - @Override - public void close() throws IOException { - super.close(); - offerClassFile(toUri(), toByteArray()); - } - }; - } - @Override - public int hashCode() { - return toUri().hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof JavaFileObject && toUri().equals(((JavaFileObject)obj).toUri()); - } - - protected abstract void offerClassFile(URI uri, byte[] bytes); - } - private static URI toURI(String outputDir, String name) { return createUri("file:///" + outputDir.replace('\\','/') + "/" + name.replace('.', '/') + JavaFileObject.Kind.CLASS.extension); } @Override public Iterable list(Location location, String packageName, Set kinds, boolean recurse) throws IOException { - if (/*location != StandardLocation.SOURCE_PATH || */recurse) { + if (recurse) { return super.list(location, packageName, kinds, recurse); } Iterable path = getLocation(location); @@ -166,33 +103,42 @@ class MyFileManager extends DefaultFileManager { if (kinds.contains(kind)) { if (results == null) results = new SmartList(); if (kind == JavaFileObject.Kind.SOURCE && child.getFileSystem() instanceof JarFileSystem) continue; //for some reasdon javac looks for java files inside jar - results.add(new JavaVirtualFile(child, kind)); + + // do not use VFS to read .class content + JavaFileObject fileObject = + kind == JavaFileObject.Kind.CLASS && child.getFileSystem() == LocalFileSystem.getInstance() ? + new JavaIoFile(new File(child.getPath()), kind) : new JavaVirtualFile(child, kind); + results.add(fileObject); } } } - //if (this!=null) return c; List ret = results == null ? Collections.emptyList() : results; - //Collection c = (Collection)super.list(location, packageName, kinds, recurse); - //Collection sup = new HashSet(c); - //assert sup.size() == c.size(); - //assert new HashSet(c).equals(sup); - // - //THashSet s = new THashSet(new TObjectHashingStrategy() { - // public int computeHashCode(JavaFileObject object) { - // return object.getName().hashCode(); - // } - // - // public boolean equals(JavaFileObject o1, JavaFileObject o2) { - // return o1.getKind() == o2.getKind() && o1.toUri().equals(o2.toUri()); - // } - //}); - //s.addAll(ret); - // - //s.removeAll(sup); - //if (ret.size() != sup.size()) { - // int i = 0; - //} + + if (LOG.isDebugEnabled()) { + // for testing consistency + Collection c = (Collection)super.list(location, packageName, kinds, recurse); + Collection sup = new HashSet(c); + assert sup.size() == c.size(); + assert new HashSet(c).equals(sup); + + THashSet s = new THashSet(new TObjectHashingStrategy() { + public int computeHashCode(JavaFileObject object) { + return object.getName().hashCode(); + } + + public boolean equals(JavaFileObject o1, JavaFileObject o2) { + return o1.getKind() == o2.getKind() && o1.toUri().equals(o2.toUri()); + } + }); + s.addAll(ret); + + s.removeAll(sup); + if (ret.size() != sup.size()) { + assert false : "our implementation differs from javac'"; + } + } + return ret; } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/Output.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/Output.java new file mode 100644 index 000000000000..716bd781f539 --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/Output.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.compiler.impl.javaCompiler.api; + +import javax.tools.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URI; + +/** +* User: cdr +*/ +@SuppressWarnings({"ALL"}) +class Output extends SimpleJavaFileObject { + private final CompAPIDriver myCompAPIDriver; + + Output(URI uri, CompAPIDriver compAPIDriver) { + super(uri, Kind.CLASS); + myCompAPIDriver = compAPIDriver; + } + + @Override + public ByteArrayOutputStream openOutputStream() { + return new ByteArrayOutputStream() { + @Override + public void close() throws IOException { + super.close(); + myCompAPIDriver.offerClassFile(toUri(), toByteArray()); + } + }; + } + @Override + public int hashCode() { + return toUri().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof JavaFileObject && toUri().equals(((JavaFileObject)obj).toUri()); + } +} diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java index 5c8689063124..29febbecc1ea 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java @@ -25,6 +25,7 @@ import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompilerBundle; import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.options.Configurable; @@ -43,6 +44,8 @@ import java.util.Set; public class EclipseEmbeddedCompiler implements BackendCompiler { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.eclipse.EclipseEmbeddedCompiler"); + private final Project myProject; private final EclipseCompiler myEclipseExternalCompiler; private int myExitCode; @@ -148,6 +151,7 @@ public class EclipseEmbeddedCompiler implements BackendCompiler { } catch (Exception e) { compileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + LOG.info(e); myExitCode = -1; return -1; } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java index 62a934c1354e..8df7503e89fc 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java @@ -118,6 +118,7 @@ public class RmicCompiler implements ClassPostProcessingCompiler{ } catch (CacheCorruptedException e) { context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + LOG.info(e); } } }); @@ -183,6 +184,7 @@ public class RmicCompiler implements ClassPostProcessingCompiler{ } catch (IOException e) { context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + LOG.info(e); } } // update state so that the latest timestamps are recorded by make diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java index 43d967f299d4..a0e2f33a9e0e 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalArtifactsCompiler.java @@ -137,6 +137,7 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler { catch (IOException e) { context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); result.setResult(ProcessingItem.EMPTY_ARRAY); + LOG.info(e); return; }