do not use VFS to read .class file content,

javac inprocess compiler is available for not only internal mode,
cleanup
This commit is contained in:
Alexey Kudravtsev
2010-01-18 12:28:17 +03:00
parent ad3432c6bd
commit 59cbc1cc85
18 changed files with 332 additions and 176 deletions
@@ -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<Element>)annotationProcessingSettings.getChildren("processorPath"))) {
for (Element pathElement : (Collection<Element>)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<Element>)annotationProcessingSettings.getChildren("processor"))) {
for (Element processorChild : (Collection<Element>)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<Element> processed = (Collection<Element>)annotationProcessingSettings.getChildren("processModule");
if (processed.size() > 0) {
final Map<String, Module> moduleMap = new com.intellij.util.containers.HashMap<String, Module>();
if (!processed.isEmpty()) {
final Map<String, Module> moduleMap = new HashMap<String, Module>();
for (Module module : myModuleManager.getModules()) {
moduleMap.put(module.getName(), module);
}
@@ -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);
}
}
@@ -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<Module, VirtualFile> myModuleToTempDirMap = new THashMap<Module, VirtualFile>();
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<String, Set<CompiledClass>> myFileNameToSourceMap= new THashMap<String, Set<CompiledClass>>();
@@ -180,7 +180,7 @@ public class BackendCompilerWrapper {
myFilesToRecompile.addAll(allDependent);
}
final List<TranslatingCompiler.OutputItem> 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 {
@@ -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();
}
}
@@ -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();
}
}
@@ -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);
@@ -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<String> commandLine, List<File> 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<? extends JavaFileObject> 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);
}
}
@@ -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";
@@ -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<FileType> COMPILABLE_TYPES = Collections.<FileType>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();
}
}
}
}
@@ -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());
}
}
@@ -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());
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
//return super.getJavaFileObjectsFromFiles(files);
int size = ((Collection)files).size();
List<JavaFileObject> result = new ArrayList<JavaFileObject>(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<JavaFileObject> list(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) throws IOException {
if (/*location != StandardLocation.SOURCE_PATH || */recurse) {
if (recurse) {
return super.list(location, packageName, kinds, recurse);
}
Iterable<? extends File> path = getLocation(location);
@@ -166,33 +103,42 @@ class MyFileManager extends DefaultFileManager {
if (kinds.contains(kind)) {
if (results == null) results = new SmartList<JavaFileObject>();
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<JavaFileObject> ret = results == null ? Collections.<JavaFileObject>emptyList() : results;
//Collection c = (Collection)super.list(location, packageName, kinds, recurse);
//Collection<JavaFileObject> sup = new HashSet(c);
//assert sup.size() == c.size();
//assert new HashSet(c).equals(sup);
//
//THashSet<JavaFileObject> s = new THashSet<JavaFileObject>(new TObjectHashingStrategy<JavaFileObject>() {
// 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<JavaFileObject> sup = new HashSet(c);
assert sup.size() == c.size();
assert new HashSet(c).equals(sup);
THashSet<JavaFileObject> s = new THashSet<JavaFileObject>(new TObjectHashingStrategy<JavaFileObject>() {
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;
}
@@ -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());
}
}
@@ -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;
}
@@ -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
@@ -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;
}