mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
deleting old make implementation
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
@@ -23,17 +22,11 @@ package com.intellij.compiler;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ProjectTopics;
|
||||
import com.intellij.compiler.impl.TranslatingCompilerFilesMonitor;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.api.CompilerAPICompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.eclipse.EclipseCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.eclipse.EclipseEmbeddedCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler;
|
||||
import com.intellij.compiler.options.ExternalBuildOptionListener;
|
||||
import com.intellij.compiler.server.BuildManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.compiler.CompilerManager;
|
||||
import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
|
||||
@@ -80,7 +73,6 @@ import java.util.*;
|
||||
public class CompilerConfigurationImpl extends CompilerConfiguration implements PersistentStateComponent<Element>, ProjectComponent {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.CompilerConfiguration");
|
||||
@NonNls public static final String TESTS_EXTERNAL_COMPILER_HOME_PROPERTY_NAME = "tests.external.compiler.home";
|
||||
public static final int DEPENDENCY_FORMAT_VERSION = 55;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess"}) public String DEFAULT_COMPILER;
|
||||
@NotNull private BackendCompiler myDefaultJavaCompiler;
|
||||
@@ -128,33 +120,6 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements
|
||||
myProcessorsProfilesMap = null; // clear cache
|
||||
}
|
||||
});
|
||||
|
||||
connection.subscribe(ExternalBuildOptionListener.TOPIC, new ExternalBuildOptionListener() {
|
||||
@Override
|
||||
public void externalBuildOptionChanged(boolean externalBuildEnabled) {
|
||||
// this will schedule for compilation all files that might become compilable after resource patterns' changing
|
||||
final TranslatingCompilerFilesMonitor monitor = TranslatingCompilerFilesMonitor.getInstance();
|
||||
if (externalBuildEnabled) {
|
||||
monitor.suspendProject(myProject);
|
||||
}
|
||||
else {
|
||||
monitor.watchProject(myProject);
|
||||
monitor.scanSourcesForCompilableFiles(myProject);
|
||||
if (!myProject.isDefault()) {
|
||||
final File buildSystem = BuildManager.getInstance().getBuildSystemDirectory();
|
||||
final File[] subdirs = buildSystem.listFiles();
|
||||
if (subdirs != null) {
|
||||
final String prefix = myProject.getName().toLowerCase(Locale.US) + "_";
|
||||
for (File subdir : subdirs) {
|
||||
if (subdir.getName().startsWith(prefix)) {
|
||||
FileUtil.asyncDelete(subdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Element getState() {
|
||||
@@ -290,35 +255,14 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements
|
||||
myRegisteredCompilers.add(JAVAC_EXTERNAL_BACKEND);
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
//final BackendCompiler JIKES_BACKEND = new JikesCompiler(myProject);
|
||||
//myRegisteredCompilers.add(JIKES_BACKEND);
|
||||
|
||||
if (EclipseCompiler.isInitialized()) {
|
||||
final EclipseCompiler eclipse = new EclipseCompiler(myProject);
|
||||
myRegisteredCompilers.add(eclipse);
|
||||
}
|
||||
|
||||
if (ApplicationManagerEx.getApplicationEx().isInternal()) {
|
||||
try {
|
||||
final EclipseEmbeddedCompiler eclipseEmbedded = new EclipseEmbeddedCompiler(myProject);
|
||||
myRegisteredCompilers.add(eclipseEmbedded);
|
||||
}
|
||||
catch (NoClassDefFoundError e) {
|
||||
// eclipse jar must be not in the classpath
|
||||
}
|
||||
try {
|
||||
CompilerAPICompiler inProcessJavaCompiler = new CompilerAPICompiler(myProject);
|
||||
myRegisteredCompilers.add(inProcessJavaCompiler);
|
||||
}
|
||||
catch (NoClassDefFoundError e) {
|
||||
// wrong JDK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final BackendCompiler[] compilers = Extensions.getExtensions(BackendCompiler.EP_NAME, myProject);
|
||||
final Set<FileType> types = new HashSet<FileType>();
|
||||
for (BackendCompiler compiler : compilers) {
|
||||
for (BackendCompiler compiler : Extensions.getExtensions(BackendCompiler.EP_NAME, myProject)) {
|
||||
myRegisteredCompilers.add(compiler);
|
||||
types.addAll(compiler.getCompilableFileTypes());
|
||||
}
|
||||
@@ -327,7 +271,7 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements
|
||||
for (FileType type : types) {
|
||||
compilerManager.addCompilableFileType(type);
|
||||
}
|
||||
|
||||
|
||||
myDefaultJavaCompiler = JAVAC_EXTERNAL_BACKEND;
|
||||
for (BackendCompiler compiler : myRegisteredCompilers) {
|
||||
if (compiler.getId().equals(DEFAULT_COMPILER)) {
|
||||
@@ -338,11 +282,6 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements
|
||||
DEFAULT_COMPILER = myDefaultJavaCompiler.getId();
|
||||
}
|
||||
|
||||
public Collection<BackendCompiler> getRegisteredJavaCompilers() {
|
||||
createCompilers();
|
||||
return myRegisteredCompilers;
|
||||
}
|
||||
|
||||
public String[] getResourceFilePatterns() {
|
||||
return getWildcardPatterns();
|
||||
}
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
package com.intellij.compiler;
|
||||
|
||||
import com.intellij.compiler.impl.*;
|
||||
import com.intellij.compiler.impl.javaCompiler.AnnotationProcessingCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.JavaCompiler;
|
||||
import com.intellij.compiler.impl.resourceCompiler.ResourceCompiler;
|
||||
import com.intellij.compiler.impl.rmiCompiler.RmicCompiler;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
@@ -35,11 +31,6 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Chunk;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.graph.CachingSemiGraph;
|
||||
import com.intellij.util.graph.Graph;
|
||||
import com.intellij.util.graph.GraphGenerator;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -54,28 +45,20 @@ public class CompilerManagerImpl extends CompilerManager {
|
||||
private final Project myProject;
|
||||
|
||||
private final List<Compiler> myCompilers = new ArrayList<Compiler>();
|
||||
private final List<TranslatingCompiler> myTranslators = new ArrayList<TranslatingCompiler>();
|
||||
|
||||
private final List<CompileTask> myBeforeTasks = new ArrayList<CompileTask>();
|
||||
private final List<CompileTask> myAfterTasks = new ArrayList<CompileTask>();
|
||||
private final Set<FileType> myCompilableTypes = new HashSet<FileType>();
|
||||
private final CompilationStatusListener myEventPublisher;
|
||||
private final Semaphore myCompilationSemaphore = new Semaphore(1, true);
|
||||
private final Map<Compiler, Set<FileType>> myCompilerToInputTypes = new HashMap<Compiler, Set<FileType>>();
|
||||
private final Map<Compiler, Set<FileType>> myCompilerToOutputTypes = new HashMap<Compiler, Set<FileType>>();
|
||||
private final Set<ModuleType> myValidationDisabledModuleTypes = new HashSet<ModuleType>();
|
||||
private final Set<LocalFileSystem.WatchRequest> myWatchRoots;
|
||||
|
||||
public CompilerManagerImpl(final Project project, CompilerConfigurationImpl compilerConfiguration, MessageBus messageBus) {
|
||||
public CompilerManagerImpl(final Project project, MessageBus messageBus) {
|
||||
myProject = project;
|
||||
myEventPublisher = messageBus.syncPublisher(CompilerTopics.COMPILATION_STATUS);
|
||||
|
||||
// predefined compilers
|
||||
addTranslatingCompiler(new AnnotationProcessingCompiler(project), new HashSet<FileType>(Arrays.asList(StdFileTypes.JAVA)), new HashSet<FileType>(Arrays.asList(StdFileTypes.JAVA, StdFileTypes.CLASS)));
|
||||
addTranslatingCompiler(new JavaCompiler(project), new HashSet<FileType>(Arrays.asList(StdFileTypes.JAVA)), new HashSet<FileType>(Arrays.asList(StdFileTypes.CLASS)));
|
||||
addCompiler(new ResourceCompiler(project, compilerConfiguration));
|
||||
addCompiler(new RmicCompiler());
|
||||
|
||||
for(Compiler compiler: Extensions.getExtensions(Compiler.EP_NAME, myProject)) {
|
||||
addCompiler(compiler);
|
||||
}
|
||||
@@ -87,7 +70,7 @@ public class CompilerManagerImpl extends CompilerManager {
|
||||
}
|
||||
|
||||
addCompilableFileType(StdFileTypes.JAVA);
|
||||
|
||||
|
||||
final File projectGeneratedSrcRoot = CompilerPaths.getGeneratedDataDirectory(project);
|
||||
projectGeneratedSrcRoot.mkdirs();
|
||||
final LocalFileSystem lfs = LocalFileSystem.getInstance();
|
||||
@@ -100,28 +83,6 @@ public class CompilerManagerImpl extends CompilerManager {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
//addCompiler(new DummyTransformingCompiler()); // this one is for testing purposes only
|
||||
//addCompiler(new DummySourceGeneratingCompiler(myProject)); // this one is for testing purposes only
|
||||
/*
|
||||
// for testing only
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
FileTypeManager.getInstance().registerFileType(DummyTranslatingCompiler.INPUT_FILE_TYPE, DummyTranslatingCompiler.FILETYPE_EXTENSION);
|
||||
addTranslatingCompiler(
|
||||
new DummyTranslatingCompiler(),
|
||||
new HashSet<FileType>(Arrays.asList(DummyTranslatingCompiler.INPUT_FILE_TYPE)),
|
||||
new HashSet<FileType>(Arrays.asList( StdFileTypes.JAVA))
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
public Semaphore getCompilationSemaphore() {
|
||||
@@ -132,68 +93,32 @@ public class CompilerManagerImpl extends CompilerManager {
|
||||
return myCompilationSemaphore.availablePermits() == 0;
|
||||
}
|
||||
|
||||
public void addTranslatingCompiler(@NotNull final TranslatingCompiler compiler, final Set<FileType> inputTypes, final Set<FileType> outputTypes) {
|
||||
myTranslators.add(compiler);
|
||||
myCompilerToInputTypes.put(compiler, inputTypes);
|
||||
myCompilerToOutputTypes.put(compiler, outputTypes);
|
||||
|
||||
final List<Chunk<Compiler>> chunks = ModuleCompilerUtil.getSortedChunks(createCompilerGraph((List<Compiler>)(List)myTranslators));
|
||||
|
||||
myTranslators.clear();
|
||||
for (Chunk<Compiler> chunk : chunks) {
|
||||
for (Compiler chunkCompiler : chunk.getNodes()) {
|
||||
myTranslators.add((TranslatingCompiler)chunkCompiler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<FileType> getRegisteredInputTypes(@NotNull final TranslatingCompiler compiler) {
|
||||
final Set<FileType> inputs = myCompilerToInputTypes.get(compiler);
|
||||
return inputs != null? Collections.unmodifiableSet(inputs) : Collections.<FileType>emptySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<FileType> getRegisteredOutputTypes(@NotNull final TranslatingCompiler compiler) {
|
||||
final Set<FileType> outs = myCompilerToOutputTypes.get(compiler);
|
||||
return outs != null? Collections.unmodifiableSet(outs) : Collections.<FileType>emptySet();
|
||||
}
|
||||
|
||||
public final void addCompiler(@NotNull Compiler compiler) {
|
||||
if (compiler instanceof TranslatingCompiler) {
|
||||
myTranslators.add((TranslatingCompiler)compiler);
|
||||
myCompilers.add(compiler);
|
||||
// supporting file instrumenting compilers and validators for external build
|
||||
// Since these compilers are IDE-specific and use PSI, it is ok to run them before and after the build in the IDE
|
||||
if (compiler instanceof SourceInstrumentingCompiler) {
|
||||
addBeforeTask(new FileProcessingCompilerAdapterTask((FileProcessingCompiler)compiler));
|
||||
}
|
||||
else {
|
||||
myCompilers.add(compiler);
|
||||
// supporting file instrumenting compilers and validators for external build
|
||||
// Since these compilers are IDE-specific and use PSI, it is ok to run them before and after the build in the IDE
|
||||
if (compiler instanceof SourceInstrumentingCompiler) {
|
||||
addBeforeTask(new FileProcessingCompilerAdapterTask((FileProcessingCompiler)compiler));
|
||||
}
|
||||
else if (compiler instanceof Validator) {
|
||||
addAfterTask(new FileProcessingCompilerAdapterTask((FileProcessingCompiler)compiler));
|
||||
}
|
||||
else if (compiler instanceof Validator) {
|
||||
addAfterTask(new FileProcessingCompilerAdapterTask((FileProcessingCompiler)compiler));
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void addTranslatingCompiler(@NotNull TranslatingCompiler compiler, Set<FileType> inputTypes, Set<FileType> outputTypes) {
|
||||
// empty
|
||||
}
|
||||
|
||||
public final void removeCompiler(@NotNull Compiler compiler) {
|
||||
if (compiler instanceof TranslatingCompiler) {
|
||||
myTranslators.remove(compiler);
|
||||
}
|
||||
else {
|
||||
if (myCompilers.remove(compiler)) {
|
||||
for (List<CompileTask> tasks : Arrays.asList(myBeforeTasks, myAfterTasks)) {
|
||||
for (Iterator<CompileTask> iterator = tasks.iterator(); iterator.hasNext(); ) {
|
||||
CompileTask task = iterator.next();
|
||||
if (task instanceof FileProcessingCompilerAdapterTask && ((FileProcessingCompilerAdapterTask)task).getCompiler() == compiler) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
for (List<CompileTask> tasks : Arrays.asList(myBeforeTasks, myAfterTasks)) {
|
||||
for (Iterator<CompileTask> iterator = tasks.iterator(); iterator.hasNext(); ) {
|
||||
CompileTask task = iterator.next();
|
||||
if (task instanceof FileProcessingCompilerAdapterTask && ((FileProcessingCompilerAdapterTask)task).getCompiler() == compiler) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
myCompilerToInputTypes.remove(compiler);
|
||||
myCompilerToOutputTypes.remove(compiler);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -209,11 +134,6 @@ public class CompilerManagerImpl extends CompilerManager {
|
||||
compilers.add((T)item);
|
||||
}
|
||||
}
|
||||
for (final Compiler item : myTranslators) {
|
||||
if (compilerClass.isAssignableFrom(item.getClass()) && filter.acceptCompiler(item)) {
|
||||
compilers.add((T)item);
|
||||
}
|
||||
}
|
||||
final T[] array = (T[])Array.newInstance(compilerClass, compilers.size());
|
||||
return compilers.toArray(array);
|
||||
}
|
||||
@@ -263,11 +183,11 @@ public class CompilerManagerImpl extends CompilerManager {
|
||||
}
|
||||
|
||||
public void compile(@NotNull Module module, CompileStatusNotification callback) {
|
||||
new CompileDriver(myProject).compile(createModuleCompileScope(module, false), new ListenerNotificator(callback), true);
|
||||
new CompileDriver(myProject).compile(createModuleCompileScope(module, false), new ListenerNotificator(callback));
|
||||
}
|
||||
|
||||
public void compile(@NotNull CompileScope scope, CompileStatusNotification callback) {
|
||||
new CompileDriver(myProject).compile(scope, new ListenerNotificator(callback), false);
|
||||
new CompileDriver(myProject).compile(scope, new ListenerNotificator(callback));
|
||||
}
|
||||
|
||||
public void make(CompileStatusNotification callback) {
|
||||
@@ -372,20 +292,6 @@ public class CompilerManagerImpl extends CompilerManager {
|
||||
return CompilerConfiguration.getInstance(myProject).isExcludedFromCompilation(file);
|
||||
}
|
||||
|
||||
private static final OutputToSourceMapping OUTPUT_TO_SOURCE_MAPPING = new OutputToSourceMapping() {
|
||||
public String getSourcePath(final String outputPath) {
|
||||
final LocalFileSystem lfs = LocalFileSystem.getInstance();
|
||||
final VirtualFile outputFile = lfs.findFileByPath(outputPath);
|
||||
|
||||
final VirtualFile sourceFile = outputFile != null ? TranslatingCompilerFilesMonitor.getSourceFileByOutput(outputFile) : null;
|
||||
return sourceFile != null? sourceFile.getPath() : null;
|
||||
}
|
||||
};
|
||||
@NotNull
|
||||
public OutputToSourceMapping getJavaCompilerOutputMapping() {
|
||||
return OUTPUT_TO_SOURCE_MAPPING;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompileScope createFilesCompileScope(@NotNull final VirtualFile[] files) {
|
||||
CompileScope[] scopes = new CompileScope[files.length];
|
||||
@@ -438,32 +344,6 @@ public class CompilerManagerImpl extends CompilerManager {
|
||||
return !myValidationDisabledModuleTypes.contains(ModuleType.get(module));
|
||||
}
|
||||
|
||||
private Graph<Compiler> createCompilerGraph(final List<Compiler> compilers) {
|
||||
return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<Compiler>() {
|
||||
public Collection<Compiler> getNodes() {
|
||||
return compilers;
|
||||
}
|
||||
|
||||
public Iterator<Compiler> getIn(Compiler compiler) {
|
||||
final Set<FileType> compilerInput = myCompilerToInputTypes.get(compiler);
|
||||
if (compilerInput == null || compilerInput.isEmpty()) {
|
||||
return Collections.<Compiler>emptySet().iterator();
|
||||
}
|
||||
|
||||
final Set<Compiler> inCompilers = new HashSet<Compiler>();
|
||||
|
||||
for (Map.Entry<Compiler, Set<FileType>> entry : myCompilerToOutputTypes.entrySet()) {
|
||||
final Set<FileType> outputs = entry.getValue();
|
||||
Compiler comp = entry.getKey();
|
||||
if (outputs != null && ContainerUtil.intersects(compilerInput, outputs)) {
|
||||
inCompilers.add(comp);
|
||||
}
|
||||
}
|
||||
return inCompilers.iterator();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private class ListenerNotificator implements CompileStatusNotification {
|
||||
private final @Nullable CompileStatusNotification myDelegate;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -38,12 +37,8 @@ public class CompilerSettingsUsageCollector extends UsagesCollector{
|
||||
@Override
|
||||
public Set<UsageDescriptor> getUsages(@Nullable Project project) throws CollectUsagesException {
|
||||
final CompilerWorkspaceConfiguration wsConfig = CompilerWorkspaceConfiguration.getInstance(project);
|
||||
if (!wsConfig.useOutOfProcessBuild()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
final Set<UsageDescriptor> result = new HashSet<UsageDescriptor>();
|
||||
result.add(new UsageDescriptor("external_build", 1));
|
||||
if (wsConfig.MAKE_PROJECT_ON_SAVE) {
|
||||
result.add(new UsageDescriptor("auto_make", 1));
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.compiler.make.CachingSearcher;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Aug 19, 2008
|
||||
*/
|
||||
public interface DependencyProcessor {
|
||||
ExtensionPointName<DependencyProcessor> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.makeDependencyProcessor");
|
||||
|
||||
void processDependencies(CompileContext context, int classQualifiedName, CachingSearcher searcher) throws CacheCorruptedException;
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.compiler;
|
||||
|
||||
import com.intellij.compiler.impl.javaCompiler.FileObject;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -27,12 +26,12 @@ public abstract class OutputParser {
|
||||
protected final List<ParserAction> myParserActions = new ArrayList<ParserAction>(10);
|
||||
|
||||
public interface Callback {
|
||||
@NonNls String getNextLine();
|
||||
@NonNls String getCurrentLine();
|
||||
String getNextLine();
|
||||
String getCurrentLine();
|
||||
void pushBack(String line);
|
||||
void setProgressText(String text);
|
||||
void fileProcessed(@NonNls String path);
|
||||
void fileGenerated(@NonNls FileObject path);
|
||||
void fileProcessed(String path);
|
||||
void fileGenerated(String path);
|
||||
void message(CompilerMessageCategory category, String message, @NonNls String url, int lineNum, int columnNum);
|
||||
}
|
||||
|
||||
@@ -65,8 +64,4 @@ public abstract class OutputParser {
|
||||
protected static void addMessage(Callback callback, CompilerMessageCategory type, String text, String url, int line, int column){
|
||||
callback.message(type, text, url, line, column);
|
||||
}
|
||||
|
||||
public boolean isTrimLines() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author: Eugene Zhuravlev
|
||||
* Date: Mar 3, 2003
|
||||
* Time: 12:34:44 PM
|
||||
*/
|
||||
package com.intellij.compiler;
|
||||
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.containers.SLRUCache;
|
||||
import com.intellij.util.io.PersistentEnumerator;
|
||||
import com.intellij.util.io.PersistentStringEnumerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class SymbolTable {
|
||||
private final PersistentStringEnumerator myTrie;
|
||||
|
||||
// both caches should have equal size
|
||||
private static final int STRING_CACHE_SIZE = 1024;
|
||||
|
||||
private final SLRUCache<Integer, String> myIndexStringCache = new SLRUCache<Integer, String>(STRING_CACHE_SIZE * 2, STRING_CACHE_SIZE) {
|
||||
@NotNull
|
||||
public String createValue(Integer key) {
|
||||
try {
|
||||
return myTrie.valueOf(key.intValue());
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final SLRUCache<String, Integer> myStringIndexCache = new SLRUCache<String, Integer>(STRING_CACHE_SIZE * 2, STRING_CACHE_SIZE) {
|
||||
@NotNull
|
||||
public Integer createValue(String key) {
|
||||
try {
|
||||
return myTrie.enumerate(key);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public SymbolTable(File file) throws CacheCorruptedException {
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
FileUtil.createIfDoesntExist(file);
|
||||
}
|
||||
myTrie = new PersistentStringEnumerator(file);
|
||||
}
|
||||
catch (PersistentEnumerator.CorruptedException e) {
|
||||
throw new CacheCorruptedException(CompilerBundle.message("error.compiler.caches.corrupted"), e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized int getId(@NotNull String symbol) throws CacheCorruptedException {
|
||||
if (symbol.length() == 0) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
return myStringIndexCache.get(symbol);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
throw new CacheCorruptedException(e.getCause());
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized String getSymbol(int id) throws CacheCorruptedException {
|
||||
if (id == -1) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
return myIndexStringCache.get(id);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
throw new CacheCorruptedException(e.getCause());
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void dispose() throws CacheCorruptedException {
|
||||
try {
|
||||
myIndexStringCache.clear();
|
||||
myStringIndexCache.clear();
|
||||
myTrie.close(); // will call "flush()" if needed
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.compiler.actions;
|
||||
|
||||
import com.intellij.compiler.CompilerWorkspaceConfiguration;
|
||||
import com.intellij.notification.NotificationGroup;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
@@ -126,13 +125,8 @@ public class BuildArtifactAction extends DumbAwareAction {
|
||||
final CompileScope scope = ArtifactCompileScope.createArtifactsScope(project, artifacts, rebuild);
|
||||
|
||||
ArtifactsWorkspaceSettings.getInstance(project).setArtifactsToBuild(artifacts);
|
||||
if (!rebuild || CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
|
||||
//in external build we can set 'rebuild' flag per target type
|
||||
CompilerManager.getInstance(project).make(scope, null);
|
||||
}
|
||||
else {
|
||||
CompilerManager.getInstance(project).compile(scope, null);
|
||||
}
|
||||
//in external build we can set 'rebuild' flag per target type
|
||||
CompilerManager.getInstance(project).make(scope, null);
|
||||
}
|
||||
|
||||
private static Set<Artifact> getArtifacts(final List<ArtifactPopupItem> items, final Project project) {
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.actions;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerWorkspaceConfiguration;
|
||||
import com.intellij.compiler.impl.FileSetCompileScope;
|
||||
import com.intellij.compiler.impl.ModuleCompileScope;
|
||||
import com.intellij.compiler.impl.javaCompiler.AnnotationProcessingCompiler;
|
||||
import com.intellij.compiler.impl.resourceCompiler.ResourceCompiler;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.compiler.CompilerFilter;
|
||||
import com.intellij.openapi.compiler.CompilerManager;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ProcessAnnotationsAction extends CompileActionBase {
|
||||
|
||||
protected void doAction(DataContext dataContext, Project project) {
|
||||
final Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
|
||||
final CompilerFilter filter = new CompilerFilter() {
|
||||
public boolean acceptCompiler(com.intellij.openapi.compiler.Compiler compiler) {
|
||||
// EclipseLink CanonicalModelProcessor reads input from output hence adding ResourcesCompiler
|
||||
return compiler instanceof AnnotationProcessingCompiler || compiler instanceof ResourceCompiler;
|
||||
}
|
||||
};
|
||||
if (module != null) {
|
||||
CompilerManager.getInstance(project).make(new ModuleCompileScope(module, false), filter, null);
|
||||
}
|
||||
else {
|
||||
final FileSetCompileScope scope = getCompilableFiles(project, CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext));
|
||||
if (scope != null) {
|
||||
CompilerManager.getInstance(project).make(scope, filter, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void update(AnActionEvent event) {
|
||||
super.update(event);
|
||||
Presentation presentation = event.getPresentation();
|
||||
if (!presentation.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
DataContext dataContext = event.getDataContext();
|
||||
presentation.setVisible(false);
|
||||
|
||||
Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
if (project == null) {
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project);
|
||||
|
||||
final Module module = LangDataKeys.MODULE.getData(dataContext);
|
||||
final Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
|
||||
|
||||
if (module == null) {
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
final AnnotationProcessingConfiguration profile = compilerConfiguration.getAnnotationProcessingConfiguration(module);
|
||||
if (!profile.isEnabled() || (!profile.isObtainProcessorsFromClasspath() && profile.getProcessors().isEmpty())) {
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
presentation.setVisible(true);
|
||||
presentation.setText(createPresentationText(""), true);
|
||||
final FileSetCompileScope scope = getCompilableFiles(project, CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext));
|
||||
if (moduleContext == null && scope == null) {
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
String elementDescription = null;
|
||||
if (moduleContext != null) {
|
||||
elementDescription = CompilerBundle.message("action.compile.description.module", moduleContext.getName());
|
||||
}
|
||||
else {
|
||||
PsiPackage aPackage = null;
|
||||
final Collection<VirtualFile> files = scope.getRootFiles();
|
||||
if (files.size() == 1) {
|
||||
final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(files.iterator().next());
|
||||
if (directory != null) {
|
||||
aPackage = JavaDirectoryService.getInstance().getPackage(directory);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
|
||||
if (element instanceof PsiPackage) {
|
||||
aPackage = (PsiPackage)element;
|
||||
}
|
||||
}
|
||||
|
||||
if (aPackage != null) {
|
||||
String name = aPackage.getQualifiedName();
|
||||
if (name.length() == 0) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
name = "<default>";
|
||||
}
|
||||
elementDescription = "'" + name + "'";
|
||||
}
|
||||
else if (files.size() == 1) {
|
||||
final VirtualFile file = files.iterator().next();
|
||||
FileType fileType = file.getFileType();
|
||||
if (CompilerManager.getInstance(project).isCompilableFileType(fileType)) {
|
||||
elementDescription = "'" + file.getName() + "'";
|
||||
}
|
||||
else {
|
||||
if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) {
|
||||
// the action should be invisible in popups for non-java files
|
||||
presentation.setEnabled(false);
|
||||
presentation.setVisible(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
elementDescription = CompilerBundle.message("action.compile.description.selected.files");
|
||||
}
|
||||
}
|
||||
|
||||
if (elementDescription == null) {
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
presentation.setText(createPresentationText(elementDescription), true);
|
||||
presentation.setEnabled(true);
|
||||
}
|
||||
|
||||
private static String createPresentationText(final String elementDescription) {
|
||||
int length = elementDescription.length();
|
||||
String target = length > 23 ? (StringUtil.startsWithChar(elementDescription, '\'') ? "'..." : "...") + elementDescription.substring(length - 20, length) : elementDescription;
|
||||
return MessageFormat.format(ActionsBundle.actionText(StringUtil.isEmpty(target)? "RunAPT" : "RunAPT.1"), target);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static FileSetCompileScope getCompilableFiles(Project project, VirtualFile[] files) {
|
||||
if (files == null || files.length == 0) {
|
||||
return null;
|
||||
}
|
||||
final PsiManager psiManager = PsiManager.getInstance(project);
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
final CompilerManager compilerManager = CompilerManager.getInstance(project);
|
||||
final List<VirtualFile> filesToCompile = new ArrayList<VirtualFile>();
|
||||
final List<Module> affectedModules = new ArrayList<Module>();
|
||||
for (final VirtualFile file : files) {
|
||||
if (!fileIndex.isInSourceContent(file)) {
|
||||
continue;
|
||||
}
|
||||
if (!file.isInLocalFileSystem()) {
|
||||
continue;
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
final PsiDirectory directory = psiManager.findDirectory(file);
|
||||
if (directory == null || JavaDirectoryService.getInstance().getPackage(directory) == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
FileType fileType = file.getFileType();
|
||||
if (!(compilerManager.isCompilableFileType(fileType))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
filesToCompile.add(file);
|
||||
ContainerUtil.addIfNotNull(fileIndex.getModuleForFile(file), affectedModules);
|
||||
}
|
||||
if (filesToCompile.isEmpty()) return null;
|
||||
return new FileSetCompileScope(filesToCompile, affectedModules.toArray(new Module[affectedModules.size()]));
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Apr 2, 2004
|
||||
*/
|
||||
public class AnnotationConstantValue extends ConstantValue {
|
||||
public static final AnnotationConstantValue[] EMPTY_ARRAY = new AnnotationConstantValue[0];
|
||||
public static final AnnotationConstantValue[][] EMPTY_ARRAY_ARRAY = new AnnotationConstantValue[0][];
|
||||
public final int myQName;
|
||||
public final AnnotationNameValuePair[] myMemberValues;
|
||||
|
||||
public AnnotationConstantValue(int qName, AnnotationNameValuePair[] memberValues) {
|
||||
myQName = qName;
|
||||
myMemberValues = memberValues;
|
||||
}
|
||||
|
||||
public int getAnnotationQName() {
|
||||
return myQName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an array of Integer -> ConstantValue pairs
|
||||
*/
|
||||
public AnnotationNameValuePair[] getMemberValues() {
|
||||
return myMemberValues;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue(DataInput in) throws IOException {
|
||||
myQName = in.readInt();
|
||||
final int size = in.readInt();
|
||||
myMemberValues = new AnnotationNameValuePair[size];
|
||||
for (int idx = 0; idx < myMemberValues.length; idx++) {
|
||||
final int name = in.readInt();
|
||||
final ConstantValue constantValue = MemberInfoExternalizer.loadConstantValue(in);
|
||||
myMemberValues[idx] = new AnnotationNameValuePair(name, constantValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeInt(myQName);
|
||||
out.writeInt(myMemberValues.length);
|
||||
for (int idx = 0; idx < myMemberValues.length; idx++) {
|
||||
final AnnotationNameValuePair nameValuePair = myMemberValues[idx];
|
||||
out.writeInt(nameValuePair.getName());
|
||||
MemberInfoExternalizer.saveConstantValue(out, nameValuePair.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AnnotationConstantValue)) return false;
|
||||
|
||||
final AnnotationConstantValue annotationConstantValue = (AnnotationConstantValue)o;
|
||||
|
||||
if (myQName != annotationConstantValue.myQName) return false;
|
||||
if (!Arrays.equals(myMemberValues, annotationConstantValue.myMemberValues)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myQName;
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Apr 8, 2004
|
||||
*/
|
||||
public class AnnotationNameValuePair {
|
||||
private final int myName;
|
||||
private final ConstantValue myValue;
|
||||
|
||||
public AnnotationNameValuePair(int name, ConstantValue value) {
|
||||
myName = name;
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public int getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public ConstantValue getValue() {
|
||||
return myValue;
|
||||
}
|
||||
}
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Apr 2, 2004
|
||||
*/
|
||||
public class AnnotationPrimitiveConstantValue extends ConstantValue{
|
||||
private final char myValueTag;
|
||||
private final ConstantValue myValue;
|
||||
|
||||
public AnnotationPrimitiveConstantValue(char valueTag, ConstantValue value) {
|
||||
myValueTag = valueTag;
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public AnnotationPrimitiveConstantValue(DataInput in) throws IOException {
|
||||
myValueTag = in.readChar();
|
||||
myValue = MemberInfoExternalizer.loadConstantValue(in);
|
||||
}
|
||||
|
||||
public char getValueTag() {
|
||||
return myValueTag;
|
||||
}
|
||||
|
||||
public ConstantValue getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeChar(myValueTag);
|
||||
MemberInfoExternalizer.saveConstantValue(out, myValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AnnotationPrimitiveConstantValue)) return false;
|
||||
|
||||
final AnnotationPrimitiveConstantValue memberValue = (AnnotationPrimitiveConstantValue)o;
|
||||
|
||||
if (myValueTag != memberValue.myValueTag) return false;
|
||||
if (!myValue.equals(memberValue.myValue)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = (int)myValueTag;
|
||||
result = 29 * result + myValue.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,770 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Jan 2, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import com.intellij.compiler.SymbolTable;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.cls.BytePointer;
|
||||
import com.intellij.util.cls.ClsFormatException;
|
||||
import com.intellij.util.cls.ClsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ClassFileReader {
|
||||
private final File myFile;
|
||||
private byte[] myData;
|
||||
private int[] myConstantPoolOffsets = null; // the last offset points to the constant pool end
|
||||
|
||||
private String myQualifiedName;
|
||||
private String myGenericSignature;
|
||||
private List<ReferenceInfo> myReferences;
|
||||
private List<FieldInfo> myFields;
|
||||
private List<MethodInfo> myMethods;
|
||||
private String mySourceFileName;
|
||||
private String mySuperClassName;
|
||||
private String[] mySuperInterfaces;
|
||||
private final SymbolTable mySymbolTable;
|
||||
private AnnotationConstantValue[] myRuntimeVisibleAnnotations;
|
||||
private AnnotationConstantValue[] myRuntimeInvisibleAnnotations;
|
||||
private static final String CONSTRUCTOR_NAME = "<init>";
|
||||
private boolean myParsingDone;
|
||||
|
||||
public ClassFileReader(@NotNull File file, SymbolTable symbolTable, @Nullable final byte[] fileContent) {
|
||||
mySymbolTable = symbolTable;
|
||||
myFile = file;
|
||||
myData = fileContent;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return myFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
public Collection<ReferenceInfo> getReferences() throws ClsFormatException {
|
||||
parseConstantPool();
|
||||
return myReferences;
|
||||
}
|
||||
|
||||
public MethodInfo[] getMethods() throws ClsFormatException{
|
||||
parseMembers();
|
||||
return myMethods.toArray(new MethodInfo[myMethods.size()]);
|
||||
}
|
||||
|
||||
public FieldInfo[] getFields() throws ClsFormatException{
|
||||
parseMembers();
|
||||
return myFields.toArray(new FieldInfo[myFields.size()]);
|
||||
}
|
||||
|
||||
private void parseMembers() throws ClsFormatException {
|
||||
if (myParsingDone) {
|
||||
return;
|
||||
}
|
||||
initConstantPool();
|
||||
myMethods = new ArrayList<MethodInfo>();
|
||||
myFields = new ArrayList<FieldInfo>();
|
||||
BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd());
|
||||
ptr.offset += 2; // access flags
|
||||
ptr.offset += 2; // this class
|
||||
ptr.offset += 2; // super class
|
||||
int count = ClsUtil.readU2(ptr); // interface count
|
||||
ptr.offset += 2 * count; // skip interface infos
|
||||
count = ClsUtil.readU2(ptr); // field count
|
||||
while (count-- > 0) {
|
||||
FieldInfo field = (FieldInfo)readMemberStructure(ptr, true);
|
||||
String name = getSymbol(field.getName());
|
||||
if (name.indexOf('$') < 0 && name.indexOf('<') < 0){ // skip synthetic fields
|
||||
myFields.add(field);
|
||||
}
|
||||
}
|
||||
count = ClsUtil.readU2(ptr); // method count
|
||||
while (count-- > 0) {
|
||||
MethodInfo method = (MethodInfo)readMemberStructure(ptr, false);
|
||||
String name = getSymbol(method.getName());
|
||||
if (name.indexOf('$') < 0 && name.indexOf('<') < 0) { // skip synthetic methods
|
||||
myMethods.add(method);
|
||||
}
|
||||
else
|
||||
if (CONSTRUCTOR_NAME.equals(name)) { // store constructors
|
||||
myMethods.add(method);
|
||||
}
|
||||
}
|
||||
|
||||
final ClsAttributeTable attributeTable = readAttributes(ptr);
|
||||
mySourceFileName = attributeTable.sourceFile;
|
||||
myGenericSignature = attributeTable.genericSignature;
|
||||
myRuntimeVisibleAnnotations = attributeTable.runtimeVisibleAnnotations;
|
||||
myRuntimeInvisibleAnnotations = attributeTable.runtimeInvisibleAnnotations;
|
||||
myParsingDone = true;
|
||||
}
|
||||
|
||||
private String getSymbol(final int id) throws ClsFormatException {
|
||||
try {
|
||||
return mySymbolTable.getSymbol(id);
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
throw new ClsFormatException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private MemberInfo readMemberStructure(BytePointer ptr, boolean isField) throws ClsFormatException {
|
||||
int flags = ClsUtil.readU2(ptr);
|
||||
int nameIndex = ClsUtil.readU2(ptr);
|
||||
int descriptorIndex = ClsUtil.readU2(ptr);
|
||||
|
||||
BytePointer p = new BytePointer(getData(), getOffsetInConstantPool(nameIndex));
|
||||
String name = ClsUtil.readUtf8Info(p);
|
||||
p.offset = getOffsetInConstantPool(descriptorIndex);
|
||||
String descriptor = ClsUtil.readUtf8Info(p);
|
||||
|
||||
if (isField) {
|
||||
final ClsAttributeTable attributeTable = readAttributes(ptr);
|
||||
return new FieldInfo(
|
||||
getSymbolId(name),
|
||||
getSymbolId(descriptor),
|
||||
attributeTable.genericSignature != null? getSymbolId(attributeTable.genericSignature) : -1,
|
||||
flags,
|
||||
attributeTable.constantValue,
|
||||
attributeTable.runtimeVisibleAnnotations,
|
||||
attributeTable.runtimeInvisibleAnnotations
|
||||
);
|
||||
}
|
||||
else {
|
||||
final ClsAttributeTable attributeTable = readAttributes(ptr);
|
||||
int[] intExceptions = null;
|
||||
if (attributeTable.exceptions != null) {
|
||||
intExceptions = ArrayUtil.newIntArray(attributeTable.exceptions.length);
|
||||
for (int idx = 0; idx < intExceptions.length; idx++) {
|
||||
intExceptions[idx] = getSymbolId(attributeTable.exceptions[idx]);
|
||||
}
|
||||
}
|
||||
return new MethodInfo(
|
||||
getSymbolId(name),
|
||||
getSymbolId(descriptor),
|
||||
attributeTable.genericSignature != null? getSymbolId(attributeTable.genericSignature) : -1,
|
||||
flags,
|
||||
intExceptions,
|
||||
CONSTRUCTOR_NAME.equals(name),
|
||||
attributeTable.runtimeVisibleAnnotations,
|
||||
attributeTable.runtimeInvisibleAnnotations,
|
||||
attributeTable.runtimeVisibleParameterAnnotations,
|
||||
attributeTable.runtimeInvisibleParameterAnnotations,
|
||||
attributeTable.annotationDefault
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private int getSymbolId(final String symbol) throws ClsFormatException{
|
||||
try {
|
||||
return mySymbolTable.getId(symbol);
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
throw new ClsFormatException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String getQualifiedName() throws ClsFormatException {
|
||||
if (myQualifiedName == null) {
|
||||
BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 2);
|
||||
ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
|
||||
int tag = ClsUtil.readU1(ptr);
|
||||
if (tag != ClsUtil.CONSTANT_Class){
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
|
||||
myQualifiedName = ClsUtil.readUtf8Info(ptr, '/', '.'); // keep '$' in the names
|
||||
}
|
||||
return myQualifiedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return fully qualified name of the class' superclass. In case there is no super return ""
|
||||
*/
|
||||
public String getSuperClass() throws ClsFormatException {
|
||||
if (mySuperClassName == null) {
|
||||
BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 4);
|
||||
int index = ClsUtil.readU2(ptr);
|
||||
if (index == 0) {
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(getQualifiedName())) {
|
||||
mySuperClassName = "";
|
||||
}
|
||||
else {
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptr.offset = getOffsetInConstantPool(index);
|
||||
mySuperClassName = readClassInfo(ptr); // keep '$' in the name for anonymous classes
|
||||
if (isInterface()) {
|
||||
if (!CommonClassNames.JAVA_LANG_OBJECT.equals(mySuperClassName)) {
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
}
|
||||
/*
|
||||
else {
|
||||
if (!MakeUtil.isAnonymous(mySuperClassName)) {
|
||||
mySuperClassName = mySuperClassName.replace('$', '.');
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
return mySuperClassName;
|
||||
}
|
||||
|
||||
public String[] getSuperInterfaces() throws ClsFormatException {
|
||||
if (mySuperInterfaces == null) {
|
||||
BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 6);
|
||||
int count = ClsUtil.readU2(ptr);
|
||||
mySuperInterfaces = ArrayUtil.newStringArray(count);
|
||||
BytePointer auxPtr = new BytePointer(ptr.bytes, 0);
|
||||
for (int idx = 0; idx < mySuperInterfaces.length; idx++) {
|
||||
auxPtr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
|
||||
mySuperInterfaces[idx] = readClassInfo(auxPtr);
|
||||
}
|
||||
}
|
||||
return mySuperInterfaces;
|
||||
}
|
||||
|
||||
|
||||
public String getSourceFileName() throws ClsFormatException {
|
||||
parseMembers();
|
||||
final String fName = mySourceFileName;
|
||||
return fName != null? fName : "";
|
||||
}
|
||||
|
||||
public String getGenericSignature() throws ClsFormatException {
|
||||
parseMembers();
|
||||
final String genericSignature = myGenericSignature;
|
||||
return genericSignature != null && !genericSignature.isEmpty() ? genericSignature : null;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeVisibleAnnotations() throws ClsFormatException {
|
||||
parseMembers();
|
||||
final AnnotationConstantValue[] annotations = myRuntimeVisibleAnnotations;
|
||||
return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() throws ClsFormatException {
|
||||
parseMembers();
|
||||
final AnnotationConstantValue[] annotations = myRuntimeInvisibleAnnotations;
|
||||
return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
private boolean isInterface(){
|
||||
return (getAccessFlags() & ClsUtil.ACC_INTERFACE) != 0;
|
||||
}
|
||||
|
||||
// helper methods
|
||||
private void parseConstantPool() throws ClsFormatException {
|
||||
if (myReferences != null) {
|
||||
return;
|
||||
}
|
||||
myReferences = new ArrayList<ReferenceInfo>();
|
||||
initConstantPool();
|
||||
final BytePointer ptr = new BytePointer(getData(), 0);
|
||||
ConstantPoolIterator iterator = new ConstantPoolIterator(ptr);
|
||||
while (iterator.hasMoreEntries()) {
|
||||
final int tag = ClsUtil.readU1(ptr);
|
||||
if (tag == ClsUtil.CONSTANT_Fieldref || tag == ClsUtil.CONSTANT_Methodref || tag == ClsUtil.CONSTANT_InterfaceMethodref) {
|
||||
//ptr.offset -= 1; // position to the beginning of the structure
|
||||
MemberReferenceInfo refInfo = readRefStructure(tag, ptr);
|
||||
if (refInfo != null) {
|
||||
myReferences.add(refInfo);
|
||||
}
|
||||
/*
|
||||
String name = mySymbolTable.getSymbol(refInfo.getMemberInfo().getName());
|
||||
if (name.indexOf('$') < 0 && name.indexOf('<') < 0) { // skip refs to synthetic members
|
||||
myReferences.add(refInfo);
|
||||
}
|
||||
else if ("<init>".equals(name)) { // add instance initializers (constructors)
|
||||
myReferences.add(refInfo);
|
||||
}
|
||||
else {
|
||||
System.out.println("ReferenceInfo thrown out: " + mySymbolTable.getSymbol(refInfo.getClassName()) + "." + mySymbolTable.getSymbol(refInfo.getMemberInfo().getName()));
|
||||
ourWasteReferenceObjectsCounter += 1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (tag == ClsUtil.CONSTANT_Class) {
|
||||
ptr.offset -= 1; // position to the beginning of the structure
|
||||
String className = readClassInfo(ptr);
|
||||
myReferences.add(new ReferenceInfo(getSymbolId(className)));
|
||||
}
|
||||
iterator.next();
|
||||
}
|
||||
//System.out.println("ourWasteReferenceObjectsCounter = " + ourWasteReferenceObjectsCounter);
|
||||
}
|
||||
|
||||
private MemberReferenceInfo readRefStructure(int tag, BytePointer ptr) throws ClsFormatException {
|
||||
/*
|
||||
if (tag != ClsUtil.CONSTANT_Fieldref && tag != ClsUtil.CONSTANT_Methodref && tag != ClsUtil.CONSTANT_InterfaceMethodref) {
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
*/
|
||||
int classInfoIndex = ClsUtil.readU2(ptr);
|
||||
int nameTypeInfoIndex = ClsUtil.readU2(ptr);
|
||||
|
||||
ptr.offset = getOffsetInConstantPool(classInfoIndex);
|
||||
if (ClsUtil.CONSTANT_Class != ClsUtil.readU1(ptr)) {
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
|
||||
String className = ClsUtil.readUtf8Info(ptr, '/', '.'); // keep '$' in names
|
||||
|
||||
ptr.offset = getOffsetInConstantPool(nameTypeInfoIndex);
|
||||
if (ClsUtil.CONSTANT_NameAndType != ClsUtil.readU1(ptr)) {
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
int memberNameIndex = ClsUtil.readU2(ptr);
|
||||
int descriptorIndex = ClsUtil.readU2(ptr);
|
||||
|
||||
ptr.offset = getOffsetInConstantPool(memberNameIndex);
|
||||
String memberName = ClsUtil.readUtf8Info(ptr);
|
||||
|
||||
if ((memberName.indexOf('$') >= 0 || memberName.indexOf('<') >= 0) && !CONSTRUCTOR_NAME.equals(memberName)) { // skip refs to synthetic members
|
||||
return null;
|
||||
}
|
||||
|
||||
ptr.offset = getOffsetInConstantPool(descriptorIndex);
|
||||
String descriptor = ClsUtil.readUtf8Info(ptr);
|
||||
|
||||
MemberInfo info = ClsUtil.CONSTANT_Fieldref == tag? new FieldInfo(getSymbolId(memberName), getSymbolId(descriptor)) : new MethodInfo(getSymbolId(memberName), getSymbolId(descriptor), CONSTRUCTOR_NAME.equals(memberName));
|
||||
return new MemberReferenceInfo(getSymbolId(className), info);
|
||||
}
|
||||
|
||||
public int getAccessFlags(){
|
||||
try{
|
||||
int offset = getConstantPoolEnd();
|
||||
byte[] data = getData();
|
||||
if (offset + 2 > data.length){
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
int b1 = data[offset++] & 0xFF;
|
||||
int b2 = data[offset++] & 0xFF;
|
||||
return (b1 << 8) + b2;
|
||||
}
|
||||
catch(ClsFormatException e){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getData(){
|
||||
if (myData == null) {
|
||||
try{
|
||||
myData = FileUtil.loadFileBytes(myFile);
|
||||
}
|
||||
catch(IOException e){
|
||||
myData = ArrayUtil.EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
}
|
||||
return myData;
|
||||
}
|
||||
|
||||
private int getOffsetInConstantPool(int index) throws ClsFormatException {
|
||||
initConstantPool();
|
||||
if (index < 1 || index >= myConstantPoolOffsets.length){
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
return myConstantPoolOffsets[index - 1];
|
||||
}
|
||||
|
||||
private int getConstantPoolEnd() throws ClsFormatException {
|
||||
initConstantPool();
|
||||
return myConstantPoolOffsets[myConstantPoolOffsets.length - 1];
|
||||
}
|
||||
|
||||
private void initConstantPool() throws ClsFormatException {
|
||||
if (myConstantPoolOffsets == null){
|
||||
BytePointer ptr = new BytePointer(getData(), 0);
|
||||
ConstantPoolIterator iterator = new ConstantPoolIterator(ptr);
|
||||
myConstantPoolOffsets = new int[iterator.getEntryCount()];
|
||||
myConstantPoolOffsets[0] = iterator.getCurrentOffset();
|
||||
int index = 1;
|
||||
while (iterator.hasMoreEntries()) {
|
||||
int tag = ClsUtil.readU1(ptr);
|
||||
if (tag == ClsUtil.CONSTANT_Long || tag == ClsUtil.CONSTANT_Double) {
|
||||
myConstantPoolOffsets[index++] = ptr.offset + 8; // takes 2 entries!
|
||||
}
|
||||
iterator.next();
|
||||
myConstantPoolOffsets[index++] = iterator.getCurrentOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String readClassInfo(BytePointer ptr) throws ClsFormatException{
|
||||
final int tag = ClsUtil.readU1(ptr);
|
||||
if (tag != ClsUtil.CONSTANT_Class){
|
||||
throw new ClsFormatException(CompilerBundle.message("class.parsing.error.wrong.record.tag.expected.another", tag, ClsUtil.CONSTANT_Class));
|
||||
}
|
||||
int index = ClsUtil.readU2(ptr);
|
||||
return ClsUtil.readUtf8Info(new BytePointer(ptr.bytes, getOffsetInConstantPool(index)), '/', '.');
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private ClsAttributeTable readAttributes(BytePointer ptr) throws ClsFormatException {
|
||||
int count = ClsUtil.readU2(ptr); // attributeCount
|
||||
final ClsAttributeTable attributes = new ClsAttributeTable();
|
||||
while (count-- > 0) {
|
||||
final String attrName = readAttributeName(ptr);
|
||||
if ("Exceptions".equals(attrName)) {
|
||||
attributes.exceptions = readExceptions(ptr);
|
||||
}
|
||||
else if ("Signature".equals(attrName)) {
|
||||
attributes.genericSignature = readSignatureAttribute(ptr);
|
||||
}
|
||||
else if ("SourceFile".equals(attrName)) {
|
||||
attributes.sourceFile = readSourceFileAttribute(ptr);
|
||||
}
|
||||
else if ("ConstantValue".equals(attrName)){
|
||||
attributes.constantValue = readFieldConstantValue(ptr);
|
||||
}
|
||||
else if ("RuntimeVisibleAnnotations".equals(attrName)) {
|
||||
attributes.runtimeVisibleAnnotations = readAnnotations(ptr);
|
||||
}
|
||||
else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
|
||||
attributes.runtimeInvisibleAnnotations = readAnnotations(ptr);
|
||||
}
|
||||
else if ("RuntimeVisibleParameterAnnotations".equals(attrName)) {
|
||||
attributes.runtimeVisibleParameterAnnotations = readParameterAnnotations(ptr);
|
||||
}
|
||||
else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) {
|
||||
attributes.runtimeInvisibleParameterAnnotations = readParameterAnnotations(ptr);
|
||||
}
|
||||
else if ("AnnotationDefault".equals(attrName)) {
|
||||
attributes.annotationDefault = readAnnotationMemberValue(new BytePointer(ptr.bytes, ptr.offset + 6));
|
||||
}
|
||||
gotoNextAttribute(ptr);
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private String readAttributeName(BytePointer p) throws ClsFormatException {
|
||||
final BytePointer ptr = new BytePointer(p.bytes, p.offset);
|
||||
final int nameIndex = ClsUtil.readU2(ptr);
|
||||
ptr.offset = getOffsetInConstantPool(nameIndex);
|
||||
return ClsUtil.readUtf8Info(ptr);
|
||||
}
|
||||
|
||||
private static void gotoNextAttribute(BytePointer ptr) throws ClsFormatException {
|
||||
ptr.offset += 2; // skip name index
|
||||
final int length = ClsUtil.readU4(ptr); // important! Do not inline since ptr.offset is also changed inside ClsUtil.readU4() method
|
||||
ptr.offset += length;
|
||||
}
|
||||
|
||||
/**
|
||||
Signature_attribute {
|
||||
u2 attribute_name_index; (must be equal to "Signature")
|
||||
u4 attribute_length; (must be equal to 2)
|
||||
u2 signature_index;
|
||||
}
|
||||
*/
|
||||
private String readSignatureAttribute(BytePointer p) throws ClsFormatException {
|
||||
final BytePointer ptr = new BytePointer(p.bytes, p.offset + 2); // position to the length
|
||||
if (ClsUtil.readU4(ptr) != 2) {
|
||||
return null;
|
||||
}
|
||||
ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
|
||||
return ClsUtil.readUtf8Info(ptr);
|
||||
}
|
||||
|
||||
private String[] readExceptions(BytePointer p) throws ClsFormatException{
|
||||
final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6); // position to the count of exceptions
|
||||
int count = ClsUtil.readU2(ptr);
|
||||
final ArrayList<String> array = new ArrayList<String>(count);
|
||||
while (count-- > 0) {
|
||||
int idx = ClsUtil.readU2(ptr);
|
||||
if (idx != 0) {
|
||||
final String exceptionClass = readClassInfo(new BytePointer(ptr.bytes, getOffsetInConstantPool(idx)));
|
||||
array.add(exceptionClass);
|
||||
}
|
||||
}
|
||||
return ArrayUtil.toStringArray(array);
|
||||
}
|
||||
|
||||
private String readSourceFileAttribute(BytePointer p) throws ClsFormatException {
|
||||
BytePointer ptr = new BytePointer(p.bytes, p.offset + 2); // position to the length
|
||||
if (ClsUtil.readU4(ptr) != 2) {
|
||||
return null;
|
||||
}
|
||||
ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
|
||||
String path = ClsUtil.readUtf8Info(ptr);
|
||||
// jdk version 1.3.0 puts full path to the source, but later versions store only short name
|
||||
final int slashIndex = path.lastIndexOf('/');
|
||||
if (slashIndex >= 0) {
|
||||
path = path.substring(slashIndex + 1, path.length());
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
private ConstantValue readFieldConstantValue(BytePointer p) throws ClsFormatException{
|
||||
final BytePointer ptr = new BytePointer(p.bytes, p.offset + 2);
|
||||
if (ClsUtil.readU4(ptr) != 2) {
|
||||
throw new ClsFormatException(); // attribute length must be 2
|
||||
}
|
||||
int valueIndex = ClsUtil.readU2(ptr);
|
||||
ptr.offset = getOffsetInConstantPool(valueIndex);
|
||||
return readConstant(ptr);
|
||||
}
|
||||
|
||||
private ConstantValue readConstant(final BytePointer ptr) throws ClsFormatException {
|
||||
final int tag = ClsUtil.readU1(ptr);
|
||||
switch (tag) {
|
||||
case ClsUtil.CONSTANT_Integer :
|
||||
int value = ClsUtil.readU4(ptr);
|
||||
return new IntegerConstantValue(value);
|
||||
case ClsUtil.CONSTANT_Float:
|
||||
float floatValue = ClsUtil.readFloat(ptr);
|
||||
return new FloatConstantValue(floatValue);
|
||||
case ClsUtil.CONSTANT_Long :
|
||||
int high = ClsUtil.readU4(ptr);
|
||||
int low = ClsUtil.readU4(ptr);
|
||||
long v = ((long)high << 32) | (low & 0xFFFFFFFFL);
|
||||
return new LongConstantValue(v);
|
||||
case ClsUtil.CONSTANT_Double :
|
||||
double doubleValue = ClsUtil.readDouble(ptr);
|
||||
return new DoubleConstantValue(doubleValue);
|
||||
case ClsUtil.CONSTANT_String :
|
||||
int stringIndex = ClsUtil.readU2(ptr);
|
||||
ptr.offset = getOffsetInConstantPool(stringIndex);
|
||||
return new StringConstantValue(ClsUtil.readUtf8Info(ptr));
|
||||
default : throw new ClsFormatException();
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationConstantValue[] readAnnotations(BytePointer p) throws ClsFormatException {
|
||||
final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6);
|
||||
return readAnnotationsArray(ptr);
|
||||
}
|
||||
|
||||
private AnnotationConstantValue[][] readParameterAnnotations(BytePointer p) throws ClsFormatException {
|
||||
final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6); // position to the number of parameters
|
||||
final int numberOfParams = ClsUtil.readU1(ptr);
|
||||
if (numberOfParams == 0) {
|
||||
return null;
|
||||
}
|
||||
final AnnotationConstantValue[][] annotations = new AnnotationConstantValue[numberOfParams][];
|
||||
for (int parameterIndex = 0; parameterIndex < numberOfParams; parameterIndex++) {
|
||||
annotations[parameterIndex] = readAnnotationsArray(ptr);
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
private AnnotationConstantValue[] readAnnotationsArray(BytePointer ptr) throws ClsFormatException {
|
||||
final int numberOfAnnotations = ClsUtil.readU2(ptr);
|
||||
if (numberOfAnnotations == 0) {
|
||||
return AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
AnnotationConstantValue[] annotations = new AnnotationConstantValue[numberOfAnnotations];
|
||||
for (int attributeIndex = 0; attributeIndex < numberOfAnnotations; attributeIndex++) {
|
||||
annotations[attributeIndex] = readAnnotation(ptr);
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
private AnnotationConstantValue readAnnotation(BytePointer ptr) throws ClsFormatException {
|
||||
final int classInfoIndex = ClsUtil.readU2(ptr);
|
||||
final String qName = readAnnotationClassName(new BytePointer(ptr.bytes, getOffsetInConstantPool(classInfoIndex)));
|
||||
final List<AnnotationNameValuePair> memberValues = new ArrayList<AnnotationNameValuePair>();
|
||||
final int numberOfPairs = ClsUtil.readU2(ptr);
|
||||
for (int idx = 0; idx < numberOfPairs; idx++) {
|
||||
final int memberNameIndex = ClsUtil.readU2(ptr);
|
||||
final String memberName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(memberNameIndex));
|
||||
final ConstantValue memberValue = readAnnotationMemberValue(ptr);
|
||||
memberValues.add(new AnnotationNameValuePair(getSymbolId(memberName), memberValue));
|
||||
}
|
||||
return new AnnotationConstantValue(getSymbolId(qName), memberValues.toArray(new AnnotationNameValuePair[memberValues.size()]));
|
||||
}
|
||||
|
||||
private String readAnnotationClassName(BytePointer ptr) throws ClsFormatException {
|
||||
// TODO: need this method because because of incomplete class format spec at the moment of writing
|
||||
// it is not clear what structure is expected: CONSTANT_Utf8 or CONSTANT_Class
|
||||
final int tag = ClsUtil.readU1(ptr);
|
||||
if (tag == ClsUtil.CONSTANT_Utf8) {
|
||||
return ClsUtil.getTypeText(ptr.bytes, ptr.offset + 2); //skip length
|
||||
}
|
||||
if (tag == ClsUtil.CONSTANT_Class){
|
||||
ptr.offset -= 1; // rollback
|
||||
return readClassInfo(ptr);
|
||||
}
|
||||
//noinspection HardCodedStringLiteral
|
||||
throw new ClsFormatException(CompilerBundle.message("class.parsing.error.wrong.record.tag.expected.another", tag, "CONSTANT_Utf8(" + ClsUtil.CONSTANT_Utf8 + ") / CONSTANT_Class(" + ClsUtil.CONSTANT_Class + ")"));
|
||||
}
|
||||
|
||||
private ConstantValue readAnnotationMemberValue(BytePointer ptr) throws ClsFormatException {
|
||||
final char tag = (char)ClsUtil.readU1(ptr);
|
||||
switch (tag) {
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'F':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'S':
|
||||
case 'Z': {
|
||||
final int valueIndex = ClsUtil.readU2(ptr);
|
||||
return new AnnotationPrimitiveConstantValue(tag, readConstant(new BytePointer(ptr.bytes, getOffsetInConstantPool(valueIndex))));
|
||||
}
|
||||
case 's': {
|
||||
final int valueIndex = ClsUtil.readU2(ptr);
|
||||
return new StringConstantValue(ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(valueIndex)));
|
||||
}
|
||||
case 'e': {
|
||||
final int typeNameIndex = ClsUtil.readU2(ptr);
|
||||
final int constantNameIndex = ClsUtil.readU2(ptr);
|
||||
final String typeName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(typeNameIndex));
|
||||
final String constantName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(constantNameIndex));
|
||||
return new EnumConstantValue(getSymbolId(typeName), getSymbolId(constantName));
|
||||
}
|
||||
case 'c' : {
|
||||
final int classInfoIndex = ClsUtil.readU2(ptr);
|
||||
BytePointer p = new BytePointer(ptr.bytes, getOffsetInConstantPool(classInfoIndex));
|
||||
final int recordTag = ClsUtil.readU1(p);
|
||||
if (recordTag != ClsUtil.CONSTANT_Utf8) {
|
||||
throw new ClsFormatException(CompilerBundle.message("class.parsing.error.wrong.record.tag.expected.another", recordTag, ClsUtil.CONSTANT_Utf8));
|
||||
}
|
||||
p.offset += 2; //Skip length
|
||||
final String className = ClsUtil.getTypeText(p.bytes, p.offset);
|
||||
return new ClassInfoConstantValue(getSymbolId(className));
|
||||
}
|
||||
case '@' : {
|
||||
return readAnnotation(ptr);
|
||||
}
|
||||
case '[' : {
|
||||
final int numberOfValues = ClsUtil.readU2(ptr);
|
||||
final ConstantValue[] values = new ConstantValue[numberOfValues];
|
||||
for (int idx = 0; idx < numberOfValues; idx++) {
|
||||
values[idx] = readAnnotationMemberValue(ptr);
|
||||
}
|
||||
return new ConstantValueArray(values);
|
||||
}
|
||||
default : throw new ClsFormatException(CompilerBundle.message("class.parsing.error.wrong.tag.annotation.member.value", tag));
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClsAttributeTable {
|
||||
public String[] exceptions;
|
||||
public String genericSignature;
|
||||
public String sourceFile;
|
||||
public ConstantValue constantValue;
|
||||
public AnnotationConstantValue[] runtimeVisibleAnnotations;
|
||||
public AnnotationConstantValue[] runtimeInvisibleAnnotations;
|
||||
public AnnotationConstantValue[][] runtimeVisibleParameterAnnotations;
|
||||
public AnnotationConstantValue[][] runtimeInvisibleParameterAnnotations;
|
||||
public ConstantValue annotationDefault;
|
||||
}
|
||||
|
||||
private static class ConstantPoolIterator {
|
||||
private final BytePointer myPtr;
|
||||
private final int myEntryCount;
|
||||
private int myCurrentEntryIndex;
|
||||
private int myCurrentOffset;
|
||||
|
||||
public ConstantPoolIterator(BytePointer ptr) throws ClsFormatException {
|
||||
myPtr = ptr;
|
||||
myPtr.offset = 0;
|
||||
int magic = ClsUtil.readU4(myPtr);
|
||||
if (magic != ClsUtil.MAGIC){
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
myPtr.offset += 2; // minor version
|
||||
myPtr.offset += 2; // major version
|
||||
myEntryCount = ClsUtil.readU2(myPtr);
|
||||
if (myEntryCount < 1){
|
||||
throw new ClsFormatException();
|
||||
}
|
||||
myCurrentEntryIndex = 1; // Entry at index 0 is included in the count but is not present in the constant pool
|
||||
myCurrentOffset = myPtr.offset;
|
||||
}
|
||||
|
||||
public int getEntryCount() {
|
||||
return myEntryCount;
|
||||
}
|
||||
|
||||
public int getCurrentOffset() {
|
||||
return myCurrentOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* tests if there are unread entries
|
||||
*/
|
||||
public boolean hasMoreEntries() {
|
||||
return myCurrentEntryIndex < myEntryCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Positions the pointer to the next entry
|
||||
*/
|
||||
public void next() throws ClsFormatException {
|
||||
myPtr.offset = myCurrentOffset;
|
||||
int tag = ClsUtil.readU1(myPtr);
|
||||
switch(tag){
|
||||
default:
|
||||
throw new ClsFormatException();
|
||||
|
||||
case ClsUtil.CONSTANT_Class:
|
||||
case ClsUtil.CONSTANT_String:
|
||||
myPtr.offset += 2;
|
||||
break;
|
||||
|
||||
case ClsUtil.CONSTANT_Fieldref:
|
||||
case ClsUtil.CONSTANT_Methodref:
|
||||
case ClsUtil.CONSTANT_InterfaceMethodref:
|
||||
case ClsUtil.CONSTANT_Integer:
|
||||
case ClsUtil.CONSTANT_Float:
|
||||
case ClsUtil.CONSTANT_NameAndType:
|
||||
myPtr.offset += 4;
|
||||
break;
|
||||
|
||||
case ClsUtil.CONSTANT_Long:
|
||||
case ClsUtil.CONSTANT_Double:
|
||||
myPtr.offset += 8;
|
||||
myCurrentEntryIndex++; // takes 2 entries
|
||||
break;
|
||||
|
||||
case ClsUtil.CONSTANT_Utf8:
|
||||
int length = ClsUtil.readU2(myPtr);
|
||||
myPtr.offset += length;
|
||||
break;
|
||||
|
||||
case ClsUtil.CONSTANT_MethodHandle:
|
||||
myPtr.offset += 3;
|
||||
break;
|
||||
case ClsUtil.CONSTANT_MethodType:
|
||||
myPtr.offset += 2;
|
||||
break;
|
||||
case ClsUtil.CONSTANT_InvokeDynamic:
|
||||
myPtr.offset += 4;
|
||||
break;
|
||||
}
|
||||
myCurrentEntryIndex++;
|
||||
myCurrentOffset = myPtr.offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
import com.intellij.compiler.SymbolTable;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.cls.ClsFormatException;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@author Eugene Zhuravlev
|
||||
*/
|
||||
public final class ClassInfo implements Cloneable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.classParsing.ClassInfo");
|
||||
|
||||
private static final ReferenceInfo[] EMPTY_REF_ARRAY = new ReferenceInfo[0];
|
||||
|
||||
private final int myQualifiedName;
|
||||
private final int myGenericSignature;
|
||||
private final int mySuperQualifiedName;
|
||||
private final int myFlags;
|
||||
private String myPath;
|
||||
private final String mySourceFileName;
|
||||
private final int[] mySuperInterfaces;
|
||||
private final FieldInfo[] myFields;
|
||||
private final MethodInfo[] myMethods;
|
||||
private ReferenceInfo[] myReferences;
|
||||
private final AnnotationConstantValue[] myRuntimeVisibleAnnotations;
|
||||
private final AnnotationConstantValue[] myRuntimeInvisibleAnnotations;
|
||||
private boolean myIsDirty = false;
|
||||
|
||||
public ClassInfo(ClassFileReader reader, SymbolTable symbolTable) throws CacheCorruptedException {
|
||||
try {
|
||||
final int qName = symbolTable.getId(reader.getQualifiedName());
|
||||
myQualifiedName = qName;
|
||||
|
||||
final String genericSignature = reader.getGenericSignature();
|
||||
myGenericSignature = genericSignature != null? symbolTable.getId(genericSignature) : -1;
|
||||
|
||||
myPath = reader.getPath();
|
||||
|
||||
final String superClass = reader.getSuperClass();
|
||||
final int superQName = "".equals(superClass)? -1 : symbolTable.getId(superClass);
|
||||
mySuperQualifiedName = superQName;
|
||||
|
||||
LOG.assertTrue(superQName != qName);
|
||||
|
||||
final String[] superInterfaces = reader.getSuperInterfaces();
|
||||
mySuperInterfaces = ArrayUtil.newIntArray(superInterfaces.length);
|
||||
for (int idx = 0; idx < superInterfaces.length; idx++) {
|
||||
mySuperInterfaces[idx] = symbolTable.getId(superInterfaces[idx]);
|
||||
}
|
||||
|
||||
final String sourceFileName = reader.getSourceFileName();
|
||||
mySourceFileName = sourceFileName != null? sourceFileName : "";
|
||||
|
||||
myFlags = reader.getAccessFlags();
|
||||
|
||||
myRuntimeVisibleAnnotations = reader.getRuntimeVisibleAnnotations();
|
||||
myRuntimeInvisibleAnnotations = reader.getRuntimeInvisibleAnnotations();
|
||||
|
||||
final Collection<ReferenceInfo> refs = reader.getReferences();
|
||||
myReferences = refs.toArray(new ReferenceInfo[refs.size()]);
|
||||
|
||||
myFields = reader.getFields();
|
||||
myMethods = reader.getMethods();
|
||||
}
|
||||
catch (ClsFormatException e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassInfo(DataInput in) throws IOException {
|
||||
myQualifiedName = in.readInt();
|
||||
mySuperQualifiedName = in.readInt();
|
||||
myGenericSignature = in.readInt();
|
||||
myFlags = in.readInt();
|
||||
myPath = in.readUTF();
|
||||
mySourceFileName = in.readUTF();
|
||||
|
||||
final int ifaceCount = in.readInt();
|
||||
mySuperInterfaces = new int[ifaceCount];
|
||||
for (int idx = 0; idx < ifaceCount; idx++) {
|
||||
mySuperInterfaces[idx] = in.readInt();
|
||||
}
|
||||
|
||||
final int fieldCount = in.readInt();
|
||||
myFields = new FieldInfo[fieldCount];
|
||||
for (int idx = 0; idx < fieldCount; idx++) {
|
||||
myFields[idx] = new FieldInfo(in);
|
||||
}
|
||||
|
||||
final int methodCount = in.readInt();
|
||||
myMethods = new MethodInfo[methodCount];
|
||||
for (int idx = 0; idx < methodCount; idx++) {
|
||||
myMethods[idx] = new MethodInfo(in);
|
||||
}
|
||||
|
||||
final int refCount = in.readInt();
|
||||
myReferences = refCount > 0? new ReferenceInfo[refCount] : EMPTY_REF_ARRAY;
|
||||
for (int idx = 0; idx < refCount; idx++) {
|
||||
myReferences[idx] = MemberInfoExternalizer.loadReferenceInfo(in);
|
||||
}
|
||||
|
||||
myRuntimeVisibleAnnotations = MemberInfoExternalizer.readAnnotationConstantValueArray1(in);
|
||||
myRuntimeInvisibleAnnotations = MemberInfoExternalizer.readAnnotationConstantValueArray1(in);
|
||||
}
|
||||
|
||||
public ClassInfo clone() {
|
||||
try {
|
||||
return (ClassInfo)super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeInt(myQualifiedName);
|
||||
out.writeInt(mySuperQualifiedName);
|
||||
out.writeInt(myGenericSignature);
|
||||
out.writeInt(myFlags);
|
||||
out.writeUTF(myPath);
|
||||
out.writeUTF(mySourceFileName);
|
||||
out.writeInt(mySuperInterfaces.length);
|
||||
for (int ifaceQName : mySuperInterfaces) {
|
||||
out.writeInt(ifaceQName);
|
||||
}
|
||||
|
||||
out.writeInt(myFields.length);
|
||||
for (FieldInfo field : myFields) {
|
||||
field.save(out);
|
||||
}
|
||||
|
||||
out.writeInt(myMethods.length);
|
||||
for (MethodInfo method : myMethods) {
|
||||
method.save(out);
|
||||
}
|
||||
|
||||
out.writeInt(myReferences.length);
|
||||
for (ReferenceInfo info : myReferences) {
|
||||
MemberInfoExternalizer.saveReferenceInfo(out, info);
|
||||
}
|
||||
|
||||
MemberInfoExternalizer.writeConstantValueArray1(out, myRuntimeVisibleAnnotations);
|
||||
MemberInfoExternalizer.writeConstantValueArray1(out, myRuntimeInvisibleAnnotations);
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return myIsDirty;
|
||||
}
|
||||
|
||||
public int getQualifiedName() throws IOException {
|
||||
return myQualifiedName;
|
||||
}
|
||||
|
||||
public int getGenericSignature() throws IOException {
|
||||
return myGenericSignature;
|
||||
}
|
||||
|
||||
public int getSuperQualifiedName() throws IOException {
|
||||
return mySuperQualifiedName;
|
||||
}
|
||||
|
||||
public int[] getSuperInterfaces() throws IOException {
|
||||
return mySuperInterfaces;
|
||||
}
|
||||
|
||||
public int getFlags() throws IOException {
|
||||
return myFlags;
|
||||
}
|
||||
|
||||
public String getPath() throws IOException {
|
||||
return myPath;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
myIsDirty |= !Comparing.equal(myPath, path);
|
||||
myPath = path;
|
||||
}
|
||||
|
||||
public String getSourceFileName() throws IOException {
|
||||
return mySourceFileName;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeVisibleAnnotations() throws IOException {
|
||||
return myRuntimeVisibleAnnotations;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() throws IOException {
|
||||
return myRuntimeInvisibleAnnotations;
|
||||
}
|
||||
|
||||
public ReferenceInfo[] getReferences() {
|
||||
return myReferences;
|
||||
}
|
||||
|
||||
public void clearReferences() {
|
||||
myReferences = EMPTY_REF_ARRAY;
|
||||
}
|
||||
|
||||
public FieldInfo[] getFields() {
|
||||
return myFields;
|
||||
}
|
||||
|
||||
public MethodInfo[] getMethods() {
|
||||
return myMethods;
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClassInfoConstantValue extends ConstantValue{
|
||||
private final int myValue;
|
||||
|
||||
public ClassInfoConstantValue(int value) {
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public ClassInfoConstantValue(DataInput in) throws IOException{
|
||||
myValue = in.readInt();
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
out.writeInt(myValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ClassInfoConstantValue)) return false;
|
||||
|
||||
final ClassInfoConstantValue classInfoConstantValue = (ClassInfoConstantValue)o;
|
||||
|
||||
if (myValue != classInfoConstantValue.myValue) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myValue;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Feb 24, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ConstantValue {
|
||||
public static final ConstantValue EMPTY_CONSTANT_VALUE = new ConstantValue();
|
||||
|
||||
protected ConstantValue() {
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Apr 2, 2004
|
||||
*/
|
||||
public class ConstantValueArray extends ConstantValue{
|
||||
private final ConstantValue[] myValue;
|
||||
|
||||
public ConstantValueArray(ConstantValue[] value) {
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public ConstantValueArray(DataInput in) throws IOException {
|
||||
final int size = in.readInt();
|
||||
myValue = new ConstantValue[size];
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
myValue[idx] = MemberInfoExternalizer.loadConstantValue(in);
|
||||
}
|
||||
}
|
||||
|
||||
public ConstantValue[] getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeInt(myValue.length);
|
||||
for (int idx = 0; idx < myValue.length; idx++) {
|
||||
MemberInfoExternalizer.saveConstantValue(out, myValue[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ConstantValueArray)) return false;
|
||||
|
||||
final ConstantValueArray constantValueArray = (ConstantValueArray)o;
|
||||
|
||||
if (!Arrays.equals(myValue, constantValueArray.myValue)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Feb 24, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DoubleConstantValue extends ConstantValue{
|
||||
private final double myValue;
|
||||
|
||||
public DoubleConstantValue(double value) {
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public DoubleConstantValue(DataInput in) throws IOException{
|
||||
myValue = in.readDouble();
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
out.writeDouble(myValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof DoubleConstantValue) && (((DoubleConstantValue)obj).myValue == myValue);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Feb 24, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EnumConstantValue extends ConstantValue{
|
||||
private final int myTypeName;
|
||||
private final int myConstantName;
|
||||
|
||||
public EnumConstantValue(int typeName, int constantName) {
|
||||
myTypeName = typeName;
|
||||
myConstantName = constantName;
|
||||
}
|
||||
|
||||
public EnumConstantValue(DataInput in) throws IOException{
|
||||
myTypeName = in.readInt();
|
||||
myConstantName = in.readInt();
|
||||
}
|
||||
|
||||
public int getTypeName() {
|
||||
return myTypeName;
|
||||
}
|
||||
|
||||
public int getConstantName() {
|
||||
return myConstantName;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
out.writeInt(myTypeName);
|
||||
out.writeInt(myConstantName);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof EnumConstantValue)) return false;
|
||||
|
||||
final EnumConstantValue enumConstantValue = (EnumConstantValue)o;
|
||||
|
||||
if (myConstantName != enumConstantValue.myConstantName) return false;
|
||||
if (myTypeName != enumConstantValue.myTypeName) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = myTypeName;
|
||||
result = 29 * result + myConstantName;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Jan 10, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FieldInfo extends MemberInfo {
|
||||
public static final FieldInfo[] EMPTY_ARRAY = new FieldInfo[0];
|
||||
private final ConstantValue myConstantValue;
|
||||
|
||||
public FieldInfo(int name, int descriptor) {
|
||||
super(name, descriptor);
|
||||
myConstantValue = ConstantValue.EMPTY_CONSTANT_VALUE;
|
||||
}
|
||||
|
||||
public FieldInfo(int name, int descriptor, final int genericSignature, int flags, ConstantValue value, final AnnotationConstantValue[] runtimeVisibleAnnotations, final AnnotationConstantValue[] runtimeInvisibleAnnotations) {
|
||||
super(name, descriptor, genericSignature, flags, runtimeVisibleAnnotations, runtimeInvisibleAnnotations);
|
||||
myConstantValue = value == null ? ConstantValue.EMPTY_CONSTANT_VALUE : value;
|
||||
}
|
||||
|
||||
public FieldInfo(DataInput in) throws IOException {
|
||||
super(in);
|
||||
myConstantValue = MemberInfoExternalizer.loadConstantValue(in);
|
||||
}
|
||||
|
||||
public ConstantValue getConstantValue() {
|
||||
return myConstantValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
MemberInfoExternalizer.saveConstantValue(out, myConstantValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Feb 24, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FloatConstantValue extends ConstantValue{
|
||||
private final float myValue;
|
||||
|
||||
public FloatConstantValue(float value) {
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public FloatConstantValue(DataInput in) throws IOException{
|
||||
myValue = in.readFloat();
|
||||
}
|
||||
|
||||
public float getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
out.writeFloat(myValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof FloatConstantValue) && (((FloatConstantValue)obj).myValue == myValue);
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Mar 4, 2004
|
||||
*/
|
||||
public class GenericMethodSignature {
|
||||
private final String myFormalTypeParams;
|
||||
private final String[] myParamSignatures;
|
||||
private final String myReturnTypeSignature;
|
||||
private final String myThrowsSignature;
|
||||
|
||||
private GenericMethodSignature(String formalTypeParams, String[] paramSignatures, String returnTypeSignature, String throwsSignature) {
|
||||
myFormalTypeParams = formalTypeParams;
|
||||
myParamSignatures = paramSignatures;
|
||||
myReturnTypeSignature = returnTypeSignature;
|
||||
myThrowsSignature = throwsSignature;
|
||||
}
|
||||
|
||||
public String getFormalTypeParams() {
|
||||
return myFormalTypeParams;
|
||||
}
|
||||
|
||||
public String[] getParamSignatures() {
|
||||
return myParamSignatures;
|
||||
}
|
||||
|
||||
public String getReturnTypeSignature() {
|
||||
return myReturnTypeSignature;
|
||||
}
|
||||
|
||||
public String getThrowsSignature() {
|
||||
return myThrowsSignature;
|
||||
}
|
||||
|
||||
public static GenericMethodSignature parse(String methodSignature) throws SignatureParsingException {
|
||||
final StringCharacterIterator it = new StringCharacterIterator(methodSignature);
|
||||
|
||||
final StringBuilder formals = new StringBuilder();
|
||||
if (it.current() == '<') {
|
||||
SignatureParser.INSTANCE.parseFormalTypeParameters(it, formals);
|
||||
}
|
||||
|
||||
if (it.current() != '(') {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "(", formals.toString()));
|
||||
}
|
||||
|
||||
it.next(); // skip '('
|
||||
|
||||
final String[] paramSignatures;
|
||||
if (it.current() != ')') {
|
||||
final List<String> params = new ArrayList<String>();
|
||||
while (it.current() != ')') {
|
||||
final StringBuilder typeSignature = new StringBuilder();
|
||||
SignatureParser.INSTANCE.parseTypeSignature(it, typeSignature);
|
||||
params.add(typeSignature.toString());
|
||||
}
|
||||
paramSignatures = ArrayUtil.toStringArray(params);
|
||||
}
|
||||
else {
|
||||
paramSignatures = ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
it.next(); // skip ')'
|
||||
|
||||
final StringBuilder returnTypeSignature = new StringBuilder();
|
||||
SignatureParser.INSTANCE.parseReturnType(it, returnTypeSignature);
|
||||
|
||||
final StringBuilder throwsSignature = new StringBuilder();
|
||||
if (it.current() != CharacterIterator.DONE) {
|
||||
SignatureParser.INSTANCE.parseThrowsSignature(it, throwsSignature);
|
||||
}
|
||||
|
||||
return new GenericMethodSignature(formals.toString(), paramSignatures, returnTypeSignature.toString(), throwsSignature.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Feb 24, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class IntegerConstantValue extends ConstantValue{
|
||||
private final int myValue;
|
||||
|
||||
public IntegerConstantValue(int value) {
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public IntegerConstantValue(DataInput in) throws IOException{
|
||||
myValue = in.readInt();
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
out.writeInt(myValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof IntegerConstantValue) && (((IntegerConstantValue)obj).myValue == myValue);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Feb 24, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LongConstantValue extends ConstantValue{
|
||||
private final long myValue;
|
||||
|
||||
public LongConstantValue(long value) {
|
||||
myValue = value;
|
||||
}
|
||||
public LongConstantValue(DataInput in) throws IOException{
|
||||
myValue = in.readLong();
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
out.writeLong(myValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof LongConstantValue) && (((LongConstantValue)obj).myValue == myValue);
|
||||
}
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Jan 8, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import com.intellij.util.cls.ClsUtil;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class MemberInfo {
|
||||
public static final MemberInfo[] EMPTY_MEMBER_INFO_ARRAY = new MemberInfo[0];
|
||||
private static final int FLAG_INFO_UNAVAILABLE = 0x8000;
|
||||
private final int myName;
|
||||
private final int myDescriptor;
|
||||
private final int myGenericSignature;
|
||||
private final int myFlags;
|
||||
private final AnnotationConstantValue[] myRuntimeVisibleAnnotations;
|
||||
private final AnnotationConstantValue[] myRuntimeInvisibleAnnotations;
|
||||
|
||||
protected MemberInfo(int name, int descriptor) {
|
||||
this(name, descriptor, -1, FLAG_INFO_UNAVAILABLE, AnnotationConstantValue.EMPTY_ARRAY, AnnotationConstantValue.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
protected MemberInfo(int name, int descriptor, int genericSignature, int flags, final AnnotationConstantValue[] runtimeVisibleAnnotations, final AnnotationConstantValue[] runtimeInvisibleAnnotations) {
|
||||
myDescriptor = descriptor;
|
||||
myGenericSignature = genericSignature;
|
||||
myName = name;
|
||||
myFlags = flags;
|
||||
myRuntimeVisibleAnnotations = runtimeVisibleAnnotations != null? runtimeVisibleAnnotations : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
myRuntimeInvisibleAnnotations = runtimeInvisibleAnnotations != null? runtimeInvisibleAnnotations : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
protected MemberInfo(DataInput in) throws IOException {
|
||||
myName = in.readInt();
|
||||
myDescriptor = in.readInt();
|
||||
myGenericSignature = in.readInt();
|
||||
myFlags = in.readInt();
|
||||
myRuntimeVisibleAnnotations = loadAnnotations(in);
|
||||
myRuntimeInvisibleAnnotations = loadAnnotations(in);
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeInt(myName);
|
||||
out.writeInt(myDescriptor);
|
||||
out.writeInt(myGenericSignature);
|
||||
out.writeInt(myFlags);
|
||||
saveAnnotations(out, myRuntimeVisibleAnnotations);
|
||||
saveAnnotations(out, myRuntimeInvisibleAnnotations);
|
||||
}
|
||||
|
||||
public int getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public int getDescriptor() {
|
||||
return myDescriptor;
|
||||
}
|
||||
|
||||
public int getGenericSignature() {
|
||||
return myGenericSignature;
|
||||
}
|
||||
|
||||
public boolean isFlagInfoAvailable() {
|
||||
return myFlags != FLAG_INFO_UNAVAILABLE;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return myFlags;
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return ClsUtil.isPublic(myFlags);
|
||||
}
|
||||
|
||||
public boolean isProtected() {
|
||||
return ClsUtil.isProtected(myFlags);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return ClsUtil.isFinal(myFlags);
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return ClsUtil.isPrivate(myFlags);
|
||||
}
|
||||
|
||||
public boolean isPackageLocal() {
|
||||
return ClsUtil.isPackageLocal(myFlags);
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return ClsUtil.isStatic(myFlags);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof MemberInfo)) return false;
|
||||
MemberInfo info = (MemberInfo)obj;
|
||||
return (myName == info.myName) && (myDescriptor == info.myDescriptor);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myName + myDescriptor;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeVisibleAnnotations() {
|
||||
return myRuntimeVisibleAnnotations;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() {
|
||||
return myRuntimeInvisibleAnnotations;
|
||||
}
|
||||
|
||||
protected final void saveAnnotations(DataOutput out, final AnnotationConstantValue[] annotations) throws IOException {
|
||||
out.writeInt(annotations.length);
|
||||
for (AnnotationConstantValue annotation : annotations) {
|
||||
MemberInfoExternalizer.saveConstantValue(out, annotation);
|
||||
}
|
||||
}
|
||||
|
||||
protected final AnnotationConstantValue[] loadAnnotations(DataInput in) throws IOException {
|
||||
final int size = in.readInt();
|
||||
if (size == 0) {
|
||||
return AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
final AnnotationConstantValue[] annotations = new AnnotationConstantValue[size];
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
annotations[idx] = (AnnotationConstantValue)MemberInfoExternalizer.loadConstantValue(in);
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Jan 10, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MemberInfoExternalizer {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.classParsing.MemberInfoExternalizer");
|
||||
|
||||
public static final byte FIELD_INFO_TAG = 1;
|
||||
public static final byte METHOD_INFO_TAG = 2;
|
||||
|
||||
public static final byte DECLARATION_INFO_TAG = 9;
|
||||
|
||||
public static final byte REFERENCE_INFO_TAG = 11;
|
||||
public static final byte MEMBER_REFERENCE_INFO_TAG = 12;
|
||||
|
||||
public static final byte LONG_CONSTANT_TAG = 3;
|
||||
public static final byte FLOAT_CONSTANT_TAG = 4;
|
||||
public static final byte DOUBLE_CONSTANT_TAG = 5;
|
||||
public static final byte INTEGER_CONSTANT_TAG = 6;
|
||||
public static final byte STRING_CONSTANT_TAG = 7;
|
||||
public static final byte CONSTANT_TAG = 8;
|
||||
public static final byte ANNOTATION_CONSTANT_TAG = 13;
|
||||
public static final byte ANNOTATION_PRIMITIVE_CONSTANT_TAG = 14;
|
||||
public static final byte CONSTANT_VALUE_ARRAY_TAG = 15;
|
||||
public static final byte CLASS_CONSTANT_VALUE_TAG = 16;
|
||||
public static final byte ENUM_CONSTANT_VALUE_TAG = 17;
|
||||
|
||||
public static MemberInfo loadMemberInfo(DataInput in) throws IOException {
|
||||
byte tag = in.readByte();
|
||||
if (tag == METHOD_INFO_TAG) {
|
||||
return new MethodInfo(in);
|
||||
}
|
||||
else if (tag == FIELD_INFO_TAG) {
|
||||
return new FieldInfo(in);
|
||||
}
|
||||
LOG.error("Unknown member info");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ReferenceInfo loadReferenceInfo(DataInput in) throws IOException {
|
||||
final byte tag = in.readByte();
|
||||
if (tag == REFERENCE_INFO_TAG) {
|
||||
return new ReferenceInfo(in);
|
||||
}
|
||||
else if (tag == MEMBER_REFERENCE_INFO_TAG) {
|
||||
return new MemberReferenceInfo(in);
|
||||
}
|
||||
LOG.error("Unknown declaration info tag: " + tag);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ConstantValue loadConstantValue(DataInput in) throws IOException {
|
||||
final byte tag = in.readByte();
|
||||
if (tag == LONG_CONSTANT_TAG) {
|
||||
return new LongConstantValue(in);
|
||||
}
|
||||
else if (tag == FLOAT_CONSTANT_TAG) {
|
||||
return new FloatConstantValue(in);
|
||||
}
|
||||
else if (tag == DOUBLE_CONSTANT_TAG) {
|
||||
return new DoubleConstantValue(in);
|
||||
}
|
||||
else if (tag == INTEGER_CONSTANT_TAG) {
|
||||
return new IntegerConstantValue(in);
|
||||
}
|
||||
else if (tag == STRING_CONSTANT_TAG) {
|
||||
return new StringConstantValue(in);
|
||||
}
|
||||
else if (tag == CONSTANT_TAG) {
|
||||
return ConstantValue.EMPTY_CONSTANT_VALUE;
|
||||
}
|
||||
else if (tag == ANNOTATION_CONSTANT_TAG) {
|
||||
return new AnnotationConstantValue(in);
|
||||
}
|
||||
else if (tag == ANNOTATION_PRIMITIVE_CONSTANT_TAG) {
|
||||
return new AnnotationPrimitiveConstantValue(in);
|
||||
}
|
||||
else if (tag == CONSTANT_VALUE_ARRAY_TAG) {
|
||||
return new ConstantValueArray(in);
|
||||
}
|
||||
else if (tag == CLASS_CONSTANT_VALUE_TAG) {
|
||||
return new ClassInfoConstantValue(in);
|
||||
}
|
||||
else if (tag == ENUM_CONSTANT_VALUE_TAG) {
|
||||
return new EnumConstantValue(in);
|
||||
}
|
||||
LOG.error("Unknown constant value type " + tag);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void saveMemberInfo(DataOutput out, MemberInfo info) throws IOException {
|
||||
if (info instanceof MethodInfo) {
|
||||
out.writeByte(METHOD_INFO_TAG);
|
||||
}
|
||||
else if (info instanceof FieldInfo){
|
||||
out.writeByte(FIELD_INFO_TAG);
|
||||
}
|
||||
else {
|
||||
LOG.error("Unknown member info");
|
||||
}
|
||||
info.save(out);
|
||||
}
|
||||
|
||||
public static void saveReferenceInfo(DataOutput out, ReferenceInfo info) throws IOException {
|
||||
if (info instanceof MemberReferenceInfo) {
|
||||
out.writeByte(MEMBER_REFERENCE_INFO_TAG);
|
||||
}
|
||||
else{
|
||||
out.writeByte(REFERENCE_INFO_TAG);
|
||||
}
|
||||
info.save(out);
|
||||
}
|
||||
|
||||
public static void saveConstantValue(DataOutput out, ConstantValue value) throws IOException {
|
||||
if (value instanceof LongConstantValue) {
|
||||
out.writeByte(LONG_CONSTANT_TAG);
|
||||
}
|
||||
else if (value instanceof FloatConstantValue){
|
||||
out.writeByte(FLOAT_CONSTANT_TAG);
|
||||
}
|
||||
else if (value instanceof DoubleConstantValue){
|
||||
out.writeByte(DOUBLE_CONSTANT_TAG);
|
||||
}
|
||||
else if (value instanceof IntegerConstantValue){
|
||||
out.writeByte(INTEGER_CONSTANT_TAG);
|
||||
}
|
||||
else if (value instanceof StringConstantValue){
|
||||
out.writeByte(STRING_CONSTANT_TAG);
|
||||
}
|
||||
else if (value instanceof AnnotationConstantValue) {
|
||||
out.writeByte(ANNOTATION_CONSTANT_TAG);
|
||||
}
|
||||
else if (value instanceof AnnotationPrimitiveConstantValue) {
|
||||
out.writeByte(ANNOTATION_PRIMITIVE_CONSTANT_TAG);
|
||||
}
|
||||
else if (value instanceof ConstantValueArray) {
|
||||
out.writeByte(CONSTANT_VALUE_ARRAY_TAG);
|
||||
}
|
||||
else if (value instanceof ClassInfoConstantValue) {
|
||||
out.writeByte(CLASS_CONSTANT_VALUE_TAG);
|
||||
}
|
||||
else if (value instanceof EnumConstantValue) {
|
||||
out.writeByte(ENUM_CONSTANT_VALUE_TAG);
|
||||
}
|
||||
else {
|
||||
out.writeByte(CONSTANT_TAG);
|
||||
}
|
||||
if (value != null) {
|
||||
value.save(out);
|
||||
}
|
||||
}
|
||||
|
||||
public static AnnotationConstantValue[] readAnnotationConstantValueArray1(DataInput in) throws IOException {
|
||||
final int size = in.readInt();
|
||||
final AnnotationConstantValue[] array = size > 0? new AnnotationConstantValue[size] : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
array[idx] = (AnnotationConstantValue)loadConstantValue(in);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static AnnotationConstantValue[][] readAnnotationConstantValueArray2(DataInput in) throws IOException {
|
||||
final int size = in.readInt();
|
||||
final AnnotationConstantValue[][] array = size > 0? new AnnotationConstantValue[size][] : AnnotationConstantValue.EMPTY_ARRAY_ARRAY;
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
array[idx] = readAnnotationConstantValueArray1(in);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static void writeConstantValueArray1(DataOutput writer, final ConstantValue[] array) throws IOException {
|
||||
if (array != null && array.length > 0) {
|
||||
writer.writeInt(array.length);
|
||||
for (ConstantValue value : array) {
|
||||
saveConstantValue(writer, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
writer.writeInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeConstantValueArray2(DataOutput writer, final ConstantValue[][] array) throws IOException {
|
||||
if (array != null && array.length > 0) {
|
||||
writer.writeInt(array.length);
|
||||
for (ConstantValue[] aArray : array) {
|
||||
writeConstantValueArray1(writer, aArray);
|
||||
}
|
||||
}
|
||||
else {
|
||||
writer.writeInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Jan 8, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MemberReferenceInfo extends ReferenceInfo {
|
||||
private final MemberInfo myMemberInfo;
|
||||
|
||||
public MemberReferenceInfo(int declaringClass, MemberInfo memberInfo) {
|
||||
super(declaringClass);
|
||||
myMemberInfo = memberInfo;
|
||||
}
|
||||
|
||||
public MemberReferenceInfo(DataInput in) throws IOException {
|
||||
super(in);
|
||||
myMemberInfo = MemberInfoExternalizer.loadMemberInfo(in);
|
||||
}
|
||||
|
||||
public MemberInfo getMemberInfo() {
|
||||
return myMemberInfo;
|
||||
}
|
||||
|
||||
public boolean isFieldReference() {
|
||||
return myMemberInfo instanceof FieldInfo;
|
||||
}
|
||||
|
||||
public boolean isMethodReference() {
|
||||
return myMemberInfo instanceof MethodInfo;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
MemberInfoExternalizer.saveMemberInfo(out, myMemberInfo);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
return myMemberInfo.equals(((MemberReferenceInfo)o).myMemberInfo);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return super.hashCode() + myMemberInfo.hashCode();
|
||||
}
|
||||
|
||||
public @NonNls String toString() { // for debug purposes
|
||||
return "Member reference: [class name=" + getClassName() + ", member name = " + myMemberInfo.getName() + ", member descriptor=" + myMemberInfo.getDescriptor() + ", member signature=" + myMemberInfo.getGenericSignature() + "]";
|
||||
}
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Jan 10, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import com.intellij.compiler.SymbolTable;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.compiler.make.CacheUtils;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.cls.ClsUtil;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MethodInfo extends MemberInfo {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.classParsing.MethodInfo");
|
||||
|
||||
private static final int[] EXCEPTION_INFO_UNAVAILABLE = ArrayUtil.EMPTY_INT_ARRAY;
|
||||
public static final MethodInfo[] EMPTY_ARRAY = new MethodInfo[0];
|
||||
|
||||
private final int[] myThrownExceptions;
|
||||
// cached (lazy initialized) data
|
||||
private String mySignature = null;
|
||||
private String[] myParameterDescriptors = null;
|
||||
private String myReturnTypeSignature = null;
|
||||
private final boolean myIsConstructor;
|
||||
private final AnnotationConstantValue[][] myRuntimeVisibleParameterAnnotations;
|
||||
private final AnnotationConstantValue[][] myRuntimeInvisibleParameterAnnotations;
|
||||
private final ConstantValue myAnnotationDefault;
|
||||
|
||||
public MethodInfo(int name, int descriptor, boolean isConstructor) {
|
||||
super(name, descriptor);
|
||||
myIsConstructor = isConstructor;
|
||||
myThrownExceptions = EXCEPTION_INFO_UNAVAILABLE;
|
||||
myRuntimeVisibleParameterAnnotations = AnnotationConstantValue.EMPTY_ARRAY_ARRAY;
|
||||
myRuntimeInvisibleParameterAnnotations = AnnotationConstantValue.EMPTY_ARRAY_ARRAY;
|
||||
myAnnotationDefault = ConstantValue.EMPTY_CONSTANT_VALUE;
|
||||
}
|
||||
|
||||
public MethodInfo(int name,
|
||||
int descriptor,
|
||||
final int genericSignature,
|
||||
int flags,
|
||||
int[] exceptions,
|
||||
boolean isConstructor,
|
||||
final AnnotationConstantValue[] runtimeVisibleAnnotations,
|
||||
final AnnotationConstantValue[] runtimeInvisibleAnnotations,
|
||||
final AnnotationConstantValue[][] runtimeVisibleParameterAnnotations,
|
||||
final AnnotationConstantValue[][] runtimeInvisibleParameterAnnotations, ConstantValue annotationDefault) {
|
||||
|
||||
super(name, descriptor, genericSignature, flags, runtimeVisibleAnnotations, runtimeInvisibleAnnotations);
|
||||
myThrownExceptions = exceptions != null? exceptions : ArrayUtil.EMPTY_INT_ARRAY;
|
||||
myIsConstructor = isConstructor;
|
||||
myRuntimeVisibleParameterAnnotations = runtimeVisibleParameterAnnotations == null? AnnotationConstantValue.EMPTY_ARRAY_ARRAY : runtimeVisibleParameterAnnotations;
|
||||
myRuntimeInvisibleParameterAnnotations = runtimeInvisibleParameterAnnotations == null? AnnotationConstantValue.EMPTY_ARRAY_ARRAY : runtimeInvisibleParameterAnnotations;
|
||||
myAnnotationDefault = annotationDefault;
|
||||
}
|
||||
|
||||
public MethodInfo(DataInput in) throws IOException {
|
||||
super(in);
|
||||
myIsConstructor = in.readBoolean();
|
||||
int count = in.readInt();
|
||||
if (count == -1) {
|
||||
myThrownExceptions = EXCEPTION_INFO_UNAVAILABLE;
|
||||
}
|
||||
else {
|
||||
myThrownExceptions = ArrayUtil.newIntArray(count);
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
myThrownExceptions[idx] = in.readInt();
|
||||
}
|
||||
}
|
||||
myRuntimeVisibleParameterAnnotations = loadParameterAnnotations(in);
|
||||
myRuntimeInvisibleParameterAnnotations = loadParameterAnnotations(in);
|
||||
myAnnotationDefault = MemberInfoExternalizer.loadConstantValue(in);
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
out.writeBoolean(myIsConstructor);
|
||||
if (isExceptionInfoAvailable()) {
|
||||
out.writeInt(myThrownExceptions.length);
|
||||
}
|
||||
else {
|
||||
out.writeInt(-1);
|
||||
}
|
||||
for (int thrownException : myThrownExceptions) {
|
||||
out.writeInt(thrownException);
|
||||
}
|
||||
saveParameterAnnotations(out, myRuntimeVisibleParameterAnnotations);
|
||||
saveParameterAnnotations(out, myRuntimeInvisibleParameterAnnotations);
|
||||
MemberInfoExternalizer.saveConstantValue(out, myAnnotationDefault);
|
||||
}
|
||||
|
||||
private boolean isExceptionInfoAvailable() {
|
||||
return myThrownExceptions != EXCEPTION_INFO_UNAVAILABLE;
|
||||
}
|
||||
|
||||
public boolean areExceptionsEqual(MethodInfo info) {
|
||||
if (myThrownExceptions.length != info.myThrownExceptions.length) {
|
||||
return false;
|
||||
}
|
||||
if (myThrownExceptions.length != 0) { // optimization
|
||||
TIntHashSet exceptionsSet = new TIntHashSet();
|
||||
for (int thrownException : myThrownExceptions) {
|
||||
exceptionsSet.add(thrownException);
|
||||
}
|
||||
for (int exception : info.myThrownExceptions) {
|
||||
if (!exceptionsSet.contains(exception)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int[] getThrownExceptions() {
|
||||
return myThrownExceptions;
|
||||
}
|
||||
|
||||
public String getDescriptor(SymbolTable symbolTable) throws CacheCorruptedException {
|
||||
if (mySignature == null) {
|
||||
final String descriptor = symbolTable.getSymbol(getDescriptor());
|
||||
final String name = symbolTable.getSymbol(getName());
|
||||
mySignature = CacheUtils.getMethodSignature(name, descriptor);
|
||||
}
|
||||
return mySignature;
|
||||
}
|
||||
|
||||
public String getReturnTypeDescriptor(SymbolTable symbolTable) throws CacheCorruptedException {
|
||||
if (myReturnTypeSignature == null) {
|
||||
String descriptor = symbolTable.getSymbol(getDescriptor());
|
||||
myReturnTypeSignature = descriptor.substring(descriptor.indexOf(')') + 1, descriptor.length());
|
||||
}
|
||||
return myReturnTypeSignature;
|
||||
}
|
||||
|
||||
public String[] getParameterDescriptors(SymbolTable symbolTable) throws CacheCorruptedException {
|
||||
if (myParameterDescriptors == null) {
|
||||
String descriptor = symbolTable.getSymbol(getDescriptor());
|
||||
int endIndex = descriptor.indexOf(')');
|
||||
if (endIndex <= 0) {
|
||||
LOG.error("Corrupted method descriptor: " + descriptor);
|
||||
}
|
||||
myParameterDescriptors = parseParameterDescriptors(descriptor.substring(1, endIndex));
|
||||
}
|
||||
return myParameterDescriptors;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return ClsUtil.isAbstract(getFlags());
|
||||
}
|
||||
|
||||
public boolean isConstructor() {
|
||||
return myIsConstructor;
|
||||
}
|
||||
|
||||
private String[] parseParameterDescriptors(String signature) {
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
String paramSignature = parseFieldType(signature);
|
||||
while (paramSignature != null && !"".equals(paramSignature)) {
|
||||
list.add(paramSignature);
|
||||
signature = signature.substring(paramSignature.length());
|
||||
paramSignature = parseFieldType(signature);
|
||||
}
|
||||
return ArrayUtil.toStringArray(list);
|
||||
}
|
||||
|
||||
private @NonNls String parseFieldType(@NonNls String signature) {
|
||||
if (signature.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (signature.charAt(0) == 'B') {
|
||||
return "B";
|
||||
}
|
||||
if (signature.charAt(0) == 'C') {
|
||||
return "C";
|
||||
}
|
||||
if (signature.charAt(0) == 'D') {
|
||||
return "D";
|
||||
}
|
||||
if (signature.charAt(0) == 'F') {
|
||||
return "F";
|
||||
}
|
||||
if (signature.charAt(0) == 'I') {
|
||||
return "I";
|
||||
}
|
||||
if (signature.charAt(0) == 'J') {
|
||||
return "J";
|
||||
}
|
||||
if (signature.charAt(0) == 'S') {
|
||||
return "S";
|
||||
}
|
||||
if (signature.charAt(0) == 'Z') {
|
||||
return "Z";
|
||||
}
|
||||
if (signature.charAt(0) == 'L') {
|
||||
return signature.substring(0, signature.indexOf(";") + 1);
|
||||
}
|
||||
if (signature.charAt(0) == '[') {
|
||||
String s = parseFieldType(signature.substring(1));
|
||||
return (s != null)? ("[" + s) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[][] getRuntimeVisibleParameterAnnotations() {
|
||||
return myRuntimeVisibleParameterAnnotations;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[][] getRuntimeInvisibleParameterAnnotations() {
|
||||
return myRuntimeInvisibleParameterAnnotations;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return mySignature;
|
||||
}
|
||||
|
||||
private AnnotationConstantValue[][] loadParameterAnnotations(DataInput in) throws IOException {
|
||||
final int size = in.readInt();
|
||||
if (size == 0) {
|
||||
return AnnotationConstantValue.EMPTY_ARRAY_ARRAY;
|
||||
}
|
||||
final AnnotationConstantValue[][] paramAnnotations = new AnnotationConstantValue[size][];
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
paramAnnotations[idx] = loadAnnotations(in);
|
||||
}
|
||||
return paramAnnotations;
|
||||
}
|
||||
|
||||
private void saveParameterAnnotations(DataOutput out, AnnotationConstantValue[][] parameterAnnotations) throws IOException {
|
||||
out.writeInt(parameterAnnotations.length);
|
||||
for (AnnotationConstantValue[] parameterAnnotation : parameterAnnotations) {
|
||||
saveAnnotations(out, parameterAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
public ConstantValue getAnnotationDefault() {
|
||||
return myAnnotationDefault;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author Eugene Zhuravlev
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ReferenceInfo {
|
||||
private final int myClassName;
|
||||
|
||||
public ReferenceInfo(int declaringClassName) {
|
||||
myClassName = declaringClassName;
|
||||
}
|
||||
|
||||
public ReferenceInfo(DataInput in) throws IOException {
|
||||
this(in.readInt());
|
||||
}
|
||||
|
||||
public @NonNls String toString() { // for debug purposes
|
||||
return "Class reference[class name=" + String.valueOf(getClassName()) + "]";
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeInt(myClassName);
|
||||
}
|
||||
|
||||
public int getClassName() {
|
||||
return myClassName;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ReferenceInfo that = (ReferenceInfo)o;
|
||||
|
||||
if (myClassName != that.myClassName) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myClassName;
|
||||
}
|
||||
}
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
|
||||
import java.text.CharacterIterator;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Mar 4, 2004
|
||||
*/
|
||||
|
||||
public class SignatureParser {
|
||||
public static final SignatureParser INSTANCE = new SignatureParser();
|
||||
|
||||
public void parseIdentifier(CharacterIterator it, final StringBuilder buf) {
|
||||
while (Character.isJavaIdentifierPart(it.current())) {
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
|
||||
public void parseFormalTypeParameters(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() != '<') {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "<", buf.toString()));
|
||||
}
|
||||
|
||||
buf.append(it.current()); // skip '<'
|
||||
it.next();
|
||||
|
||||
while (it.current() != '>') {
|
||||
parseFormalTypeParameter(it, buf);
|
||||
}
|
||||
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
}
|
||||
|
||||
public void parseFormalTypeParameter(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
parseIdentifier(it, buf);
|
||||
parseClassBound(it, buf);
|
||||
while (it.current() == ':') {
|
||||
parseInterfaceBound(it, buf);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseClassBound(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() != ':') {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", ":", buf.toString()));
|
||||
}
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
|
||||
final char current = it.current();
|
||||
if (current != CharacterIterator.DONE && current != ':') {
|
||||
parseFieldTypeSignature(it, buf);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseInterfaceBound(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() != ':') {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", ":", buf.toString()));
|
||||
}
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
parseFieldTypeSignature(it, buf);
|
||||
}
|
||||
|
||||
public void parseSuperclassSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
parseClassTypeSignature(it, buf);
|
||||
}
|
||||
|
||||
public void parseSuperinterfaceSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
parseClassTypeSignature(it, buf);
|
||||
}
|
||||
|
||||
public void parseFieldTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() == 'L') {
|
||||
parseClassTypeSignature(it, buf);
|
||||
}
|
||||
else if (it.current() == '[') {
|
||||
parseArrayTypeSignature(it, buf);
|
||||
}
|
||||
else if (it.current() == 'T') {
|
||||
parseTypeVariableSignature(it, buf);
|
||||
}
|
||||
else {
|
||||
//noinspection HardCodedStringLiteral
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "'L' / '[' / 'T'", buf.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public void parseClassTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
buf.append(it.current());
|
||||
it.next(); // consume 'L'
|
||||
parseSimpleClassTypeSignature(it, buf);
|
||||
while (it.current() == '/' || it.current() == '.') { // Eclipse compiler generates '.' for inner classes
|
||||
parseClassTypeSignatureSuffix(it, buf);
|
||||
}
|
||||
if (it.current() != ';') {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", ";", buf.toString()));
|
||||
}
|
||||
buf.append(it.current());
|
||||
it.next(); // consume ';'
|
||||
}
|
||||
|
||||
public void parseSimpleClassTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
parseIdentifier(it, buf);
|
||||
if (it.current() == '<') {
|
||||
parseTypeArguments(it, buf);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseClassTypeSignatureSuffix(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
parseSimpleClassTypeSignature(it, buf);
|
||||
}
|
||||
|
||||
public void parseTypeVariableSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
buf.append(it.current());
|
||||
it.next(); // consume 'T'
|
||||
parseIdentifier(it, buf);
|
||||
if (it.current() != ';') {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", ";", buf.toString()));
|
||||
}
|
||||
buf.append(it.current());
|
||||
it.next(); // consume ';'
|
||||
}
|
||||
|
||||
public void parseTypeArguments(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
buf.append(it.current());
|
||||
it.next(); // consume '<'
|
||||
while (it.current() != '>') {
|
||||
parseTypeArgument(it, buf);
|
||||
}
|
||||
buf.append(it.current());
|
||||
it.next(); // consume '>'
|
||||
}
|
||||
|
||||
public void parseTypeArgument(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() == '*') {
|
||||
parseWildcardIndicator(it, buf);
|
||||
}
|
||||
else {
|
||||
if (it.current() == '+' || it.current() == '-') {
|
||||
parseWildcardIndicator(it, buf);
|
||||
}
|
||||
parseFieldTypeSignature(it, buf);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseWildcardIndicator(CharacterIterator it, final StringBuilder buf) {
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
}
|
||||
|
||||
public void parseArrayTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
buf.append(it.current());
|
||||
it.next(); // consume '['
|
||||
parseTypeSignature(it, buf);
|
||||
}
|
||||
|
||||
public void parseTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
char current = it.current();
|
||||
if (current == 'B' || current == 'C' || current == 'D' || current == 'F' || current == 'I' || current == 'J' || current == 'S' || current == 'Z') {
|
||||
buf.append(it.current());
|
||||
it.next(); // base type
|
||||
}
|
||||
else if (current == 'L' || current == '[' || current == 'T') {
|
||||
parseFieldTypeSignature(it, buf);
|
||||
}
|
||||
else {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.unknown.type.signature"));
|
||||
}
|
||||
}
|
||||
|
||||
public void parseReturnType(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() == 'V') {
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
}
|
||||
else {
|
||||
parseTypeSignature(it, buf);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseThrowsSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() != '^') {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "^", buf.toString()));
|
||||
}
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
if (it.current() == 'T') {
|
||||
parseTypeVariableSignature(it, buf);
|
||||
}
|
||||
else {
|
||||
parseClassTypeSignature(it, buf);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseMethodSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() == '<') {
|
||||
parseFormalTypeParameters(it, buf);
|
||||
}
|
||||
|
||||
if (it.current() != '(') {
|
||||
throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "(", buf.toString()));
|
||||
}
|
||||
|
||||
buf.append(it.current());
|
||||
it.next(); // skip '('
|
||||
|
||||
while (it.current() != ')') {
|
||||
parseTypeSignature(it, buf);
|
||||
}
|
||||
|
||||
buf.append(it.current());
|
||||
it.next(); // skip ')'
|
||||
|
||||
parseReturnType(it, buf);
|
||||
|
||||
if (it.current() != CharacterIterator.DONE) {
|
||||
parseThrowsSignature(it, buf);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseClassSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
|
||||
if (it.current() == '<') {
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
while (it.current() != '>') {
|
||||
parseFormalTypeParameter(it, buf);
|
||||
}
|
||||
buf.append(it.current());
|
||||
it.next();
|
||||
}
|
||||
|
||||
parseClassTypeSignature(it, buf);
|
||||
|
||||
while (it.current() != CharacterIterator.DONE) {
|
||||
parseClassTypeSignature(it, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.classParsing;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Mar 4, 2004
|
||||
*/
|
||||
public class SignatureParsingException extends Exception{
|
||||
public SignatureParsingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Feb 24, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.classParsing;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class StringConstantValue extends ConstantValue{
|
||||
private final String myValue;
|
||||
|
||||
public StringConstantValue(String value) {
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public StringConstantValue(DataInput in) throws IOException{
|
||||
myValue = in.readUTF();
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
super.save(out);
|
||||
out.writeUTF(myValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return
|
||||
(obj instanceof StringConstantValue) &&
|
||||
((myValue == null)? ((StringConstantValue)obj).myValue == null : myValue.equals(((StringConstantValue)obj).myValue));
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.openapi.compiler.CompilerFilter;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class AdditionalCompileScopeProvider {
|
||||
public static final ExtensionPointName<AdditionalCompileScopeProvider> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.additionalCompileScopeProvider");
|
||||
|
||||
@Nullable
|
||||
public abstract CompileScope getAdditionalScope(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project);
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.compiler.make.DependencyCache;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerMessage;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 4, 2007
|
||||
*/
|
||||
public class CompileContextExProxy implements CompileContextEx {
|
||||
private final CompileContextEx myDelegate;
|
||||
|
||||
public CompileContextExProxy(CompileContextEx delegate) {
|
||||
myDelegate = delegate;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myDelegate.getProject();
|
||||
}
|
||||
|
||||
public DependencyCache getDependencyCache() {
|
||||
return myDelegate.getDependencyCache();
|
||||
}
|
||||
|
||||
public VirtualFile getSourceFileByOutputFile(final VirtualFile outputFile) {
|
||||
return myDelegate.getSourceFileByOutputFile(outputFile);
|
||||
}
|
||||
|
||||
public void addMessage(final CompilerMessage message) {
|
||||
myDelegate.addMessage(message);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<VirtualFile> getTestOutputDirectories() {
|
||||
return myDelegate.getTestOutputDirectories();
|
||||
}
|
||||
|
||||
public boolean isInTestSourceContent(@NotNull final VirtualFile fileOrDir) {
|
||||
return myDelegate.isInTestSourceContent(fileOrDir);
|
||||
}
|
||||
|
||||
public boolean isInSourceContent(@NotNull final VirtualFile fileOrDir) {
|
||||
return myDelegate.isInSourceContent(fileOrDir);
|
||||
}
|
||||
|
||||
public void addScope(final CompileScope additionalScope) {
|
||||
myDelegate.addScope(additionalScope);
|
||||
}
|
||||
|
||||
public void addMessage(final CompilerMessageCategory category,
|
||||
final String message, @Nullable final String url, final int lineNum, final int columnNum) {
|
||||
myDelegate.addMessage(category, message, url, lineNum, columnNum);
|
||||
}
|
||||
|
||||
public void addMessage(final CompilerMessageCategory category, final String message, @Nullable final String url,
|
||||
final int lineNum,
|
||||
final int columnNum,
|
||||
final Navigatable navigatable) {
|
||||
myDelegate.addMessage(category, message, url, lineNum, columnNum, navigatable);
|
||||
}
|
||||
|
||||
public CompilerMessage[] getMessages(final CompilerMessageCategory category) {
|
||||
return myDelegate.getMessages(category);
|
||||
}
|
||||
|
||||
public int getMessageCount(final CompilerMessageCategory category) {
|
||||
return myDelegate.getMessageCount(category);
|
||||
}
|
||||
|
||||
public ProgressIndicator getProgressIndicator() {
|
||||
return myDelegate.getProgressIndicator();
|
||||
}
|
||||
|
||||
public CompileScope getCompileScope() {
|
||||
return myDelegate.getCompileScope();
|
||||
}
|
||||
|
||||
public CompileScope getProjectCompileScope() {
|
||||
return myDelegate.getProjectCompileScope();
|
||||
}
|
||||
|
||||
public void requestRebuildNextTime(final String message) {
|
||||
myDelegate.requestRebuildNextTime(message);
|
||||
}
|
||||
|
||||
public boolean isRebuildRequested() {
|
||||
return myDelegate.isRebuildRequested();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getRebuildReason() {
|
||||
return myDelegate.getRebuildReason();
|
||||
}
|
||||
|
||||
public Module getModuleByFile(final VirtualFile file) {
|
||||
return myDelegate.getModuleByFile(file);
|
||||
}
|
||||
|
||||
public VirtualFile[] getSourceRoots(final Module module) {
|
||||
return myDelegate.getSourceRoots(module);
|
||||
}
|
||||
|
||||
public VirtualFile[] getAllOutputDirectories() {
|
||||
return myDelegate.getAllOutputDirectories();
|
||||
}
|
||||
|
||||
public VirtualFile getModuleOutputDirectory(final Module module) {
|
||||
return myDelegate.getModuleOutputDirectory(module);
|
||||
}
|
||||
|
||||
public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
|
||||
return myDelegate.getModuleOutputDirectoryForTests(module);
|
||||
}
|
||||
|
||||
public boolean isMake() {
|
||||
return myDelegate.isMake();
|
||||
}
|
||||
|
||||
public boolean isAnnotationProcessorsEnabled() {
|
||||
return myDelegate.isAnnotationProcessorsEnabled();
|
||||
}
|
||||
|
||||
public boolean isRebuild() {
|
||||
return myDelegate.isRebuild();
|
||||
}
|
||||
|
||||
public <T> T getUserData(@NotNull final Key<T> key) {
|
||||
return myDelegate.getUserData(key);
|
||||
}
|
||||
|
||||
public <T> void putUserData(@NotNull final Key<T> key, final T value) {
|
||||
myDelegate.putUserData(key, value);
|
||||
}
|
||||
|
||||
public void recalculateOutputDirs() {
|
||||
myDelegate.recalculateOutputDirs();
|
||||
}
|
||||
|
||||
public void markGenerated(Collection<VirtualFile> files) {
|
||||
myDelegate.markGenerated(files);
|
||||
}
|
||||
|
||||
public boolean isGenerated(VirtualFile file) {
|
||||
return myDelegate.isGenerated(file);
|
||||
}
|
||||
|
||||
public long getStartCompilationStamp() {
|
||||
return myDelegate.getStartCompilationStamp();
|
||||
}
|
||||
|
||||
public void assignModule(@NotNull VirtualFile root, @NotNull Module module, boolean isTestSource, com.intellij.openapi.compiler.Compiler compiler) {
|
||||
myDelegate.assignModule(root, module, isTestSource, compiler);
|
||||
}
|
||||
}
|
||||
@@ -24,24 +24,21 @@ package com.intellij.compiler.impl;
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerMessageImpl;
|
||||
import com.intellij.compiler.CompilerWorkspaceConfiguration;
|
||||
import com.intellij.compiler.make.DependencyCache;
|
||||
import com.intellij.compiler.progress.CompilerTask;
|
||||
import com.intellij.execution.impl.ExecutionManagerImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.compiler.Compiler;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerMessage;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.compiler.CompilerPaths;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.CompilerModuleExtension;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
@@ -49,14 +46,9 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.OrderedSet;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
public class CompileContextImpl extends UserDataHolderBase implements CompileContextEx {
|
||||
@@ -66,7 +58,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
private final Map<CompilerMessageCategory, Collection<CompilerMessage>> myMessages = new EnumMap<CompilerMessageCategory, Collection<CompilerMessage>>(CompilerMessageCategory.class);
|
||||
private final boolean myShouldUpdateProblemsView;
|
||||
private CompileScope myCompileScope;
|
||||
private final DependencyCache myDependencyCache;
|
||||
private final boolean myMake;
|
||||
private final boolean myIsRebuild;
|
||||
private final boolean myIsAnnotationProcessorsEnabled;
|
||||
@@ -74,11 +65,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
private String myRebuildReason;
|
||||
private final Map<VirtualFile, Module> myRootToModuleMap = new HashMap<VirtualFile, Module>();
|
||||
private final Map<Module, Set<VirtualFile>> myModuleToRootsMap = new HashMap<Module, Set<VirtualFile>>();
|
||||
private final Map<VirtualFile, Pair<SourceGeneratingCompiler, Module>> myOutputRootToSourceGeneratorMap = new HashMap<VirtualFile, Pair<SourceGeneratingCompiler, Module>>();
|
||||
private final Set<VirtualFile> myGeneratedTestRoots = new java.util.HashSet<VirtualFile>();
|
||||
private VirtualFile[] myOutputDirectories;
|
||||
private Set<VirtualFile> myTestOutputDirectories;
|
||||
private final TIntHashSet myGeneratedSources = new TIntHashSet();
|
||||
private final ProjectFileIndex myProjectFileIndex; // cached for performance reasons
|
||||
private final ProjectCompileScope myProjectCompileScope;
|
||||
private final long myStartCompilationStamp;
|
||||
@@ -87,11 +74,10 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
public CompileContextImpl(final Project project,
|
||||
final CompilerTask compilerSession,
|
||||
CompileScope compileScope,
|
||||
DependencyCache dependencyCache, boolean isMake, boolean isRebuild) {
|
||||
boolean isMake, boolean isRebuild) {
|
||||
myProject = project;
|
||||
myTask = compilerSession;
|
||||
myCompileScope = compileScope;
|
||||
myDependencyCache = dependencyCache;
|
||||
myMake = isMake;
|
||||
myIsRebuild = isRebuild;
|
||||
myStartCompilationStamp = System.currentTimeMillis();
|
||||
@@ -108,110 +94,22 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
compilerSession.setSessionId(sessionId);
|
||||
}
|
||||
}
|
||||
recalculateOutputDirs();
|
||||
final CompilerWorkspaceConfiguration workspaceConfig = CompilerWorkspaceConfiguration.getInstance(myProject);
|
||||
myShouldUpdateProblemsView = workspaceConfig.useOutOfProcessBuild() && workspaceConfig.MAKE_PROJECT_ON_SAVE;
|
||||
myShouldUpdateProblemsView = workspaceConfig.MAKE_PROJECT_ON_SAVE;
|
||||
}
|
||||
|
||||
public boolean shouldUpdateProblemsView() {
|
||||
return myShouldUpdateProblemsView;
|
||||
}
|
||||
|
||||
public void recalculateOutputDirs() {
|
||||
final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
|
||||
|
||||
final Set<VirtualFile> allDirs = new OrderedSet<VirtualFile>();
|
||||
final Set<VirtualFile> testOutputDirs = new java.util.HashSet<VirtualFile>();
|
||||
final Set<VirtualFile> productionOutputDirs = new java.util.HashSet<VirtualFile>();
|
||||
|
||||
for (Module module : allModules) {
|
||||
final CompilerModuleExtension manager = CompilerModuleExtension.getInstance(module);
|
||||
final VirtualFile output = manager.getCompilerOutputPath();
|
||||
if (output != null && output.isValid()) {
|
||||
allDirs.add(output);
|
||||
productionOutputDirs.add(output);
|
||||
}
|
||||
final VirtualFile testsOutput = manager.getCompilerOutputPathForTests();
|
||||
if (testsOutput != null && testsOutput.isValid()) {
|
||||
allDirs.add(testsOutput);
|
||||
testOutputDirs.add(testsOutput);
|
||||
}
|
||||
}
|
||||
myOutputDirectories = VfsUtil.toVirtualFileArray(allDirs);
|
||||
// need this to ensure that the sent contains only _dedicated_ test output dirs
|
||||
// Directories that are configured for both test and production classes must not be added in the resulting set
|
||||
testOutputDirs.removeAll(productionOutputDirs);
|
||||
myTestOutputDirectories = Collections.unmodifiableSet(testOutputDirs);
|
||||
}
|
||||
|
||||
public void markGenerated(Collection<VirtualFile> files) {
|
||||
for (final VirtualFile file : files) {
|
||||
myGeneratedSources.add(FileBasedIndex.getFileId(file));
|
||||
}
|
||||
}
|
||||
|
||||
public long getStartCompilationStamp() {
|
||||
return myStartCompilationStamp;
|
||||
}
|
||||
|
||||
public boolean isGenerated(VirtualFile file) {
|
||||
if (myGeneratedSources.contains(FileBasedIndex.getFileId(file))) {
|
||||
return true;
|
||||
}
|
||||
if (VfsUtilCore.isUnder(file, myRootToModuleMap.keySet())) {
|
||||
return true;
|
||||
}
|
||||
final Module module = getModuleByFile(file);
|
||||
if (module != null) {
|
||||
final String procGenRoot = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
|
||||
if (procGenRoot != null && VfsUtil.isAncestor(new File(procGenRoot), new File(file.getPath()), true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
private JBZipFile lookupZip(String outputDir) {
|
||||
synchronized (myOpenZipFiles) {
|
||||
JBZipFile zip = myOpenZipFiles.get(outputDir);
|
||||
if (zip == null) {
|
||||
final File zipFile = CompilerPathsEx.getZippedOutputPath(myProject, outputDir);
|
||||
try {
|
||||
try {
|
||||
zip = new JBZipFile(zipFile);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
try {
|
||||
zipFile.createNewFile();
|
||||
zip = new JBZipFile(zipFile);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
zipFile.getParentFile().mkdirs();
|
||||
zipFile.createNewFile();
|
||||
zip = new JBZipFile(zipFile);
|
||||
}
|
||||
}
|
||||
myOpenZipFiles.put(outputDir, zip);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
addMessage(CompilerMessageCategory.ERROR, "Cannot create zip file " + zipFile.getPath() + ": " + e.getMessage(), null, -1, -1);
|
||||
}
|
||||
}
|
||||
return zip;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
public DependencyCache getDependencyCache() {
|
||||
return myDependencyCache;
|
||||
}
|
||||
|
||||
public CompilerMessage[] getMessages(CompilerMessageCategory category) {
|
||||
Collection<CompilerMessage> collection = myMessages.get(category);
|
||||
if (collection == null) {
|
||||
@@ -221,40 +119,16 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
}
|
||||
|
||||
public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) {
|
||||
CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findPresentableFileForMessage(url), lineNum, columnNum, null);
|
||||
final CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findFileByUrl(url), lineNum, columnNum, null);
|
||||
addMessage(msg);
|
||||
}
|
||||
|
||||
public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum,
|
||||
Navigatable navigatable) {
|
||||
CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findPresentableFileForMessage(url), lineNum, columnNum, navigatable);
|
||||
final CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findFileByUrl(url), lineNum, columnNum, navigatable);
|
||||
addMessage(msg);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VirtualFile findPresentableFileForMessage(@Nullable final String url) {
|
||||
final VirtualFile file = findFileByUrl(url);
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
|
||||
@Override
|
||||
public VirtualFile compute() {
|
||||
if (file.isValid()) {
|
||||
for (final Map.Entry<VirtualFile, Pair<SourceGeneratingCompiler, Module>> entry : myOutputRootToSourceGeneratorMap.entrySet()) {
|
||||
final VirtualFile root = entry.getKey();
|
||||
if (VfsUtilCore.isAncestor(root, file, false)) {
|
||||
final Pair<SourceGeneratingCompiler, Module> pair = entry.getValue();
|
||||
final VirtualFile presentableFile = pair.getFirst().getPresentableFile(CompileContextImpl.this, pair.getSecond(), root, file);
|
||||
return presentableFile != null ? presentableFile : file;
|
||||
}
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static VirtualFile findFileByUrl(@Nullable String url) {
|
||||
if (url == null) {
|
||||
@@ -312,10 +186,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
if (!myRebuildRequested) {
|
||||
myRebuildRequested = true;
|
||||
myRebuildReason = message;
|
||||
final boolean isOutOfProcessBuild = myDependencyCache == null;
|
||||
if (!isOutOfProcessBuild) {
|
||||
addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,38 +199,9 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
}
|
||||
|
||||
public ProgressIndicator getProgressIndicator() {
|
||||
//if (myProgressIndicatorProxy != null) {
|
||||
// return myProgressIndicatorProxy;
|
||||
//}
|
||||
return myTask.getIndicator();
|
||||
}
|
||||
|
||||
public void assignModule(@NotNull VirtualFile root, @NotNull Module module, final boolean isTestSource, @Nullable Compiler compiler) {
|
||||
try {
|
||||
myRootToModuleMap.put(root, module);
|
||||
Set<VirtualFile> set = myModuleToRootsMap.get(module);
|
||||
if (set == null) {
|
||||
set = new HashSet<VirtualFile>();
|
||||
myModuleToRootsMap.put(module, set);
|
||||
}
|
||||
set.add(root);
|
||||
if (isTestSource) {
|
||||
myGeneratedTestRoots.add(root);
|
||||
}
|
||||
if (compiler instanceof SourceGeneratingCompiler) {
|
||||
myOutputRootToSourceGeneratorMap.put(root, Pair.create((SourceGeneratingCompiler)compiler, module));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myModuleToRootsCache.remove(module);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VirtualFile getSourceFileByOutputFile(VirtualFile outputFile) {
|
||||
return TranslatingCompilerFilesMonitor.getSourceFileByOutput(outputFile);
|
||||
}
|
||||
|
||||
public Module getModuleByFile(VirtualFile file) {
|
||||
final Module module = myProjectFileIndex.getModuleForFile(file);
|
||||
if (module != null) {
|
||||
@@ -419,15 +260,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
return true;
|
||||
}
|
||||
|
||||
public VirtualFile[] getAllOutputDirectories() {
|
||||
return myOutputDirectories;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<VirtualFile> getTestOutputDirectories() {
|
||||
return myTestOutputDirectories;
|
||||
}
|
||||
|
||||
public VirtualFile getModuleOutputDirectory(Module module) {
|
||||
return CompilerPaths.getModuleOutputDirectory(module, false);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,8 +27,6 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -124,35 +122,6 @@ public class CompilerCacheManager implements ProjectComponent {
|
||||
return (FileProcessingCompilerStateCache)cache;
|
||||
}
|
||||
|
||||
public synchronized StateCache<ValidityState> getGeneratingCompilerCache(final GeneratingCompiler compiler) throws IOException {
|
||||
Object cache = myCompilerToCacheMap.get(compiler);
|
||||
if (cache == null) {
|
||||
final File cacheDir = getCompilerRootDir(compiler);
|
||||
final StateCache<ValidityState> stateCache = new StateCache<ValidityState>(new File(cacheDir, "timestamps")) {
|
||||
public ValidityState read(DataInput stream) throws IOException {
|
||||
return compiler.createValidityState(stream);
|
||||
}
|
||||
|
||||
public void write(ValidityState validityState, DataOutput out) throws IOException {
|
||||
validityState.save(out);
|
||||
}
|
||||
};
|
||||
myCompilerToCacheMap.put(compiler, stateCache);
|
||||
myCacheDisposables.add(new Disposable() {
|
||||
public void dispose() {
|
||||
try {
|
||||
stateCache.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
cache = stateCache;
|
||||
}
|
||||
return (StateCache<ValidityState>)cache;
|
||||
}
|
||||
|
||||
public static String getCompilerIdString(Compiler compiler) {
|
||||
@NonNls String description = compiler.getDescription();
|
||||
return description.replaceAll("\\s+", "_").replaceAll("[\\.\\?]", "_").toLowerCase();
|
||||
|
||||
-4
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.compiler.impl;
|
||||
|
||||
import com.intellij.compiler.CompilerWorkspaceConfiguration;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -53,9 +52,6 @@ public class FileProcessingCompilerAdapterTask implements CompileTask {
|
||||
@Override
|
||||
public boolean execute(CompileContext context) {
|
||||
final Project project = context.getProject();
|
||||
if (!CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
final FileProcessingCompiler.ProcessingItem[] items = myCompiler.getProcessingItems(context);
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Jun 21, 2006
|
||||
*/
|
||||
public class SourceUrlClassNamePair {
|
||||
private final String mySourceUrl;
|
||||
private final @Nullable String myClassName;
|
||||
|
||||
public SourceUrlClassNamePair(String url, @Nullable String className) {
|
||||
mySourceUrl = url;
|
||||
myClassName = className;
|
||||
}
|
||||
|
||||
public String getSourceUrl() {
|
||||
return mySourceUrl;
|
||||
}
|
||||
|
||||
public @Nullable String getClassName() {
|
||||
return myClassName;
|
||||
}
|
||||
}
|
||||
+18
-1671
File diff suppressed because it is too large
Load Diff
-151
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author: Eugene Zhuravlev
|
||||
* Date: Jan 17, 2003
|
||||
* Time: 3:22:59 PM
|
||||
*/
|
||||
package com.intellij.compiler.impl.javaCompiler;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerConfigurationImpl;
|
||||
import com.intellij.compiler.CompilerException;
|
||||
import com.intellij.compiler.impl.CompileContextExProxy;
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class AnnotationProcessingCompiler implements TranslatingCompiler{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavaCompiler");
|
||||
private final Project myProject;
|
||||
private final CompilerConfiguration myConfig;
|
||||
|
||||
public AnnotationProcessingCompiler(Project project) {
|
||||
myProject = project;
|
||||
myConfig = CompilerConfiguration.getInstance(project);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return CompilerBundle.message("annotation.processing.compiler.description");
|
||||
}
|
||||
|
||||
public boolean isCompilableFile(VirtualFile file, CompileContext context) {
|
||||
if (!context.isAnnotationProcessorsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
return file.getFileType() == StdFileTypes.JAVA && !isExcludedFromAnnotationProcessing(file, context);
|
||||
}
|
||||
|
||||
public void compile(final CompileContext context, final Chunk<Module> moduleChunk, final VirtualFile[] files, OutputSink sink) {
|
||||
if (!context.isAnnotationProcessorsEnabled()) {
|
||||
return;
|
||||
}
|
||||
final LocalFileSystem lfs = LocalFileSystem.getInstance();
|
||||
final CompileContextEx _context = new CompileContextExProxy((CompileContextEx)context) {
|
||||
public VirtualFile getModuleOutputDirectory(Module module) {
|
||||
final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
|
||||
return path != null? lfs.findFileByPath(path) : null;
|
||||
}
|
||||
|
||||
public VirtualFile getModuleOutputDirectoryForTests(Module module) {
|
||||
return getModuleOutputDirectory(module);
|
||||
}
|
||||
};
|
||||
final JavacCompiler javacCompiler = getBackEndCompiler();
|
||||
final boolean processorMode = javacCompiler.setAnnotationProcessorMode(true);
|
||||
final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(moduleChunk, myProject, Arrays.asList(files), _context, javacCompiler, sink);
|
||||
wrapper.setForceCompileTestsSeparately(true);
|
||||
try {
|
||||
wrapper.compile();
|
||||
}
|
||||
catch (CompilerException e) {
|
||||
_context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
LOG.info(e);
|
||||
_context.requestRebuildNextTime(e.getMessage());
|
||||
}
|
||||
finally {
|
||||
javacCompiler.setAnnotationProcessorMode(processorMode);
|
||||
final Set<VirtualFile> dirsToRefresh = new HashSet<VirtualFile>();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
for (Module module : moduleChunk.getNodes()) {
|
||||
final VirtualFile out = _context.getModuleOutputDirectory(module);
|
||||
if (out != null) {
|
||||
dirsToRefresh.add(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
for (VirtualFile root : dirsToRefresh) {
|
||||
root.refresh(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isExcludedFromAnnotationProcessing(VirtualFile file, CompileContext context) {
|
||||
if (!context.isAnnotationProcessorsEnabled()) {
|
||||
return true;
|
||||
}
|
||||
final Module module = context.getModuleByFile(file);
|
||||
if (module != null) {
|
||||
if (!myConfig.getAnnotationProcessingConfiguration(module).isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
|
||||
final VirtualFile generationDir = path != null? LocalFileSystem.getInstance().findFileByPath(path) : null;
|
||||
if (generationDir != null && VfsUtil.isAncestor(generationDir, file, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return myConfig.isExcludedFromCompilation(file);
|
||||
}
|
||||
|
||||
public boolean validateConfiguration(CompileScope scope) {
|
||||
final JavacCompiler compiler = getBackEndCompiler();
|
||||
final boolean previousValue = compiler.setAnnotationProcessorMode(true);
|
||||
try {
|
||||
return compiler.checkCompiler(scope);
|
||||
}
|
||||
finally {
|
||||
compiler.setAnnotationProcessorMode(previousValue);
|
||||
}
|
||||
}
|
||||
|
||||
private JavacCompiler getBackEndCompiler() {
|
||||
CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)myConfig;
|
||||
return configuration.getJavacCompiler();
|
||||
}
|
||||
|
||||
}
|
||||
+12
-22
@@ -15,36 +15,26 @@
|
||||
*/
|
||||
package com.intellij.compiler.impl.javaCompiler;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
public interface BackendCompiler {
|
||||
ExtensionPointName<BackendCompiler> EP_NAME = ExtensionPointName.create("com.intellij.java.compiler");
|
||||
|
||||
@NotNull @NonNls String getId(); // used for externalization
|
||||
@NotNull String getPresentableName();
|
||||
@NotNull Configurable createConfigurable();
|
||||
@NotNull Set<FileType> getCompilableFileTypes();
|
||||
@Nullable OutputParser createErrorParser(@NotNull String outputDir, Process process);
|
||||
@Nullable OutputParser createOutputParser(@NotNull String outputDir);
|
||||
|
||||
boolean checkCompiler(final CompileScope scope);
|
||||
|
||||
@NotNull Process launchProcess(
|
||||
@NotNull ModuleChunk chunk,
|
||||
@NotNull String outputDir,
|
||||
@NotNull CompileContext compileContext) throws IOException;
|
||||
|
||||
void compileFinished();
|
||||
|
||||
@NotNull
|
||||
String getId(); // used for externalization
|
||||
|
||||
@NotNull
|
||||
String getPresentableName();
|
||||
|
||||
@NotNull
|
||||
Configurable createConfigurable();
|
||||
|
||||
@NotNull
|
||||
Set<FileType> getCompilableFileTypes();
|
||||
|
||||
}
|
||||
|
||||
-1015
File diff suppressed because it is too large
Load Diff
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
final class CompiledClass {
|
||||
public final int qName;
|
||||
public final String relativePathToSource;
|
||||
public final String pathToClass;
|
||||
|
||||
CompiledClass(final int qName, final String relativePathToSource, final String pathToClass) {
|
||||
this.qName = qName;
|
||||
this.relativePathToSource = relativePathToSource;
|
||||
this.pathToClass = pathToClass;
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final CompiledClass that = (CompiledClass)o;
|
||||
|
||||
if (qName != that.qName) return false;
|
||||
if (!pathToClass.equals(that.pathToClass)) return false;
|
||||
if (!relativePathToSource.equals(that.relativePathToSource)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = qName;
|
||||
result = 31 * result + relativePathToSource.hashCode();
|
||||
result = 31 * result + pathToClass.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[" + pathToClass + ";" + relativePathToSource + "]";
|
||||
}
|
||||
}
|
||||
-263
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.CompileDriver;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.SpinAllocator;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Mar 30, 2004
|
||||
*/
|
||||
public class CompilerParsingThread implements Runnable, OutputParser.Callback {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavaCompilerParsingThread");
|
||||
@NonNls public static final String TERMINATION_STRING = "__terminate_read__";
|
||||
private final Reader myCompilerOutStreamReader;
|
||||
private Process myProcess;
|
||||
private final OutputParser myOutputParser;
|
||||
private final boolean myTrimLines;
|
||||
private boolean mySkipLF = false;
|
||||
private Throwable myError = null;
|
||||
private final boolean myIsUnitTestMode;
|
||||
private FileObject myClassFileToProcess = null;
|
||||
private String myLastReadLine = null;
|
||||
private String myPushBackLine = null;
|
||||
private volatile boolean myProcessExited = false;
|
||||
private final CompileContext myContext;
|
||||
|
||||
public CompilerParsingThread(Process process, OutputParser outputParser, final boolean readErrorStream, boolean trimLines, CompileContext context) {
|
||||
myProcess = process;
|
||||
myOutputParser = outputParser;
|
||||
myTrimLines = trimLines;
|
||||
InputStream stream = readErrorStream ? process.getErrorStream() : process.getInputStream();
|
||||
myCompilerOutStreamReader = stream == null ? null : new BufferedReader(new InputStreamReader(stream), 16384);
|
||||
myIsUnitTestMode = ApplicationManager.getApplication().isUnitTestMode();
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
volatile boolean processing;
|
||||
public void run() {
|
||||
processing = true;
|
||||
try {
|
||||
while (true) {
|
||||
if (!myIsUnitTestMode && myProcess == null) {
|
||||
break;
|
||||
}
|
||||
if (isCanceled()) {
|
||||
break;
|
||||
}
|
||||
if (!myOutputParser.processMessageLine(this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (myClassFileToProcess != null) {
|
||||
processCompiledClass(myClassFileToProcess);
|
||||
myClassFileToProcess = null;
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
myError = e;
|
||||
LOG.info(e);
|
||||
}
|
||||
finally {
|
||||
killProcess();
|
||||
processing = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void killProcess() {
|
||||
if (myProcess != null) {
|
||||
myProcess.destroy();
|
||||
myProcess = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Throwable getError() {
|
||||
return myError;
|
||||
}
|
||||
|
||||
public String getCurrentLine() {
|
||||
return myLastReadLine;
|
||||
}
|
||||
|
||||
public final String getNextLine() {
|
||||
final String pushBack = myPushBackLine;
|
||||
if (pushBack != null) {
|
||||
myPushBackLine = null;
|
||||
myLastReadLine = pushBack;
|
||||
return pushBack;
|
||||
}
|
||||
final String line = readLine(myCompilerOutStreamReader);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("LIne read: #" + line + "#");
|
||||
}
|
||||
if (CompileDriver.ourDebugMode) {
|
||||
System.out.println("LIne read: #" + line + "#");
|
||||
}
|
||||
if (TERMINATION_STRING.equals(line)) {
|
||||
myLastReadLine = null;
|
||||
}
|
||||
else {
|
||||
myLastReadLine = line == null ? null : myTrimLines ? line.trim() : line;
|
||||
}
|
||||
return myLastReadLine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pushBack(String line) {
|
||||
myLastReadLine = null;
|
||||
myPushBackLine = line;
|
||||
}
|
||||
|
||||
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) {
|
||||
try {
|
||||
processCompiledClass(previousPath);
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
if (CompileDriver.ourDebugMode) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
myError = e;
|
||||
LOG.info(e);
|
||||
killProcess();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isCanceled() {
|
||||
return myContext.getProgressIndicator().isCanceled();
|
||||
}
|
||||
|
||||
public void setProgressText(String text) {
|
||||
myContext.getProgressIndicator().setText(text);
|
||||
}
|
||||
|
||||
public void fileProcessed(String path) {
|
||||
}
|
||||
|
||||
public void message(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) {
|
||||
myContext.addMessage(category, message, url, lineNum, columnNum);
|
||||
}
|
||||
|
||||
protected void processCompiledClass(final FileObject classFileToProcess) throws CacheCorruptedException {
|
||||
}
|
||||
|
||||
|
||||
private String readLine(final Reader reader) {
|
||||
StringBuilder buffer;
|
||||
boolean releaseBuffer = true;
|
||||
try {
|
||||
buffer = StringBuilderSpinAllocator.alloc();
|
||||
}
|
||||
catch (SpinAllocator.AllocatorExhaustedException e) {
|
||||
if (CompileDriver.ourDebugMode) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
LOG.info(e);
|
||||
buffer = new StringBuilder();
|
||||
releaseBuffer = false;
|
||||
}
|
||||
|
||||
try {
|
||||
boolean first = true;
|
||||
while (true) {
|
||||
int c = readNextByte(reader);
|
||||
if (c == -1) break;
|
||||
first = false;
|
||||
if (c == '\n') {
|
||||
if (mySkipLF) {
|
||||
mySkipLF = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (c == '\r') {
|
||||
mySkipLF = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
mySkipLF = false;
|
||||
buffer.append((char)c);
|
||||
}
|
||||
}
|
||||
if (first) {
|
||||
return null;
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
finally {
|
||||
if (releaseBuffer) {
|
||||
StringBuilderSpinAllocator.dispose(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int readNextByte(final Reader reader) {
|
||||
try {
|
||||
while(!reader.ready()) {
|
||||
if (isProcessTerminated()) {
|
||||
if (reader.ready()) {
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1L);
|
||||
}
|
||||
catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
return reader.read();
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (CompileDriver.ourDebugMode) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1; // When process terminated Process.getInputStream()'s underlying stream becomes closed on Linux.
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (CompileDriver.ourDebugMode) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isProcessTerminated() {
|
||||
return myProcessExited;
|
||||
}
|
||||
|
||||
public void setProcessTerminated(final boolean procesExited) {
|
||||
myProcessExited = procesExited;
|
||||
}
|
||||
}
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.SourceGeneratingCompiler;
|
||||
import com.intellij.openapi.compiler.ValidityState;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Oct 9, 2004
|
||||
*/
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public class DummySourceGeneratingCompiler implements SourceGeneratingCompiler{
|
||||
public static final String MODULE_NAME = "generated";
|
||||
private final Project myProject;
|
||||
|
||||
public DummySourceGeneratingCompiler(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public GenerationItem[] getGenerationItems(CompileContext context) {
|
||||
final Module module = findMyModule();
|
||||
return new GenerationItem[] {
|
||||
new MyGenerationItem("aaa/p1.properties", module, false),
|
||||
new MyGenerationItem("bbb/p2.properties", module, false),
|
||||
new MyGenerationItem("bbb/ccc/p3.properties", module, false),
|
||||
new MyGenerationItem("aaa/p1.properties", module, true),
|
||||
new MyGenerationItem("bbb/p2-t.properties", module, true),
|
||||
new MyGenerationItem("bbb/ccc/p3.properties", module, true)
|
||||
};
|
||||
}
|
||||
|
||||
private Module findMyModule() {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
|
||||
public Module compute() {
|
||||
Module[] modules = ModuleManager.getInstance(myProject).getModules();
|
||||
for (Module module : modules) {
|
||||
if (MODULE_NAME.equals(module.getName())) {
|
||||
return module;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public GenerationItem[] generate(CompileContext context, GenerationItem[] items, final VirtualFile outputRootDirectory) {
|
||||
final String rootPath = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
public String compute() {
|
||||
return outputRootDirectory.getPath();
|
||||
}
|
||||
});
|
||||
final List<GenerationItem> success = new ArrayList<GenerationItem>();
|
||||
for (GenerationItem item1 : items) {
|
||||
GenerationItem item = item1;
|
||||
File file = new File(rootPath + File.separator + item.getPath());
|
||||
FileUtil.createIfDoesntExist(file);
|
||||
success.add(item);
|
||||
}
|
||||
return success.toArray(new GenerationItem[success.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return "Dummy Source Generator";
|
||||
}
|
||||
|
||||
public boolean validateConfiguration(CompileScope scope) {
|
||||
return findMyModule() != null;
|
||||
}
|
||||
|
||||
public ValidityState createValidityState(DataInput in) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class MyGenerationItem implements GenerationItem {
|
||||
private final String myRelPath;
|
||||
private final Module myModule;
|
||||
private final boolean myIsTestSource;
|
||||
|
||||
public MyGenerationItem(String relPath, Module module, final boolean isTestSource) {
|
||||
myRelPath = relPath;
|
||||
myModule = module;
|
||||
myIsTestSource = isTestSource;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return myRelPath;
|
||||
}
|
||||
|
||||
public ValidityState getValidityState() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Module getModule() {
|
||||
return myModule;
|
||||
}
|
||||
|
||||
public boolean isTestSource() {
|
||||
return myIsTestSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
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.compiler.JavaSourceTransformingCompiler;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Jul 10, 2004
|
||||
*/
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public class DummyTransformingCompiler implements JavaSourceTransformingCompiler{
|
||||
public boolean isTransformable(VirtualFile file) {
|
||||
return "A.java".equals(file.getName());
|
||||
}
|
||||
|
||||
public boolean transform(CompileContext context, final VirtualFile file, VirtualFile originalFile) {
|
||||
System.out.println("DummyTransformingCompiler.transform");
|
||||
final String url = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
public String compute() {
|
||||
return file.getPresentableUrl();
|
||||
}
|
||||
});
|
||||
context.getProgressIndicator().setText("Transforming file: " + url);
|
||||
try {
|
||||
OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(url)));
|
||||
DataOutput out = new DataOutputStream(os);
|
||||
out.writeBytes("package a; ");
|
||||
out.writeBytes("public class A { public static void main(String[] args) { System.out.println(\"Hello from modified class\");} }");
|
||||
os.close();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
public void run() {
|
||||
file.refresh(false, false);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
|
||||
}
|
||||
catch (IOException e) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return "a dummy compiler for testing";
|
||||
}
|
||||
|
||||
public boolean validateConfiguration(CompileScope scope) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 4, 2007
|
||||
*/
|
||||
public class DummyTranslatingCompiler implements TranslatingCompiler, IntermediateOutputCompiler{
|
||||
@NonNls private static final String DESCRIPTION = "DUMMY TRANSLATOR";
|
||||
@NonNls private static final String FILETYPE_EXTENSION = ".dummy";
|
||||
|
||||
public boolean isCompilableFile(final VirtualFile file, final CompileContext context) {
|
||||
return file.getName().endsWith(FILETYPE_EXTENSION);
|
||||
}
|
||||
|
||||
public void compile(final CompileContext context, Chunk<Module> moduleChunk, final VirtualFile[] files, OutputSink sink) {
|
||||
final List<File> filesToRefresh = new ArrayList<File>();
|
||||
final Map<String, Collection<OutputItem>> outputs = new HashMap<String, Collection<OutputItem>>();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
for (final VirtualFile file : files) {
|
||||
final Module module = context.getModuleByFile(file);
|
||||
try {
|
||||
final VirtualFile outputDir = context.getModuleOutputDirectory(module);
|
||||
if (outputDir != null) {
|
||||
final String outputDirPath = outputDir.getPath();
|
||||
final File compiledFile = doCompile(outputDir, file);
|
||||
filesToRefresh.add(compiledFile);
|
||||
Collection<OutputItem> collection = outputs.get(outputDirPath);
|
||||
if (collection == null) {
|
||||
collection = new ArrayList<OutputItem>();
|
||||
outputs.put(outputDirPath, collection);
|
||||
}
|
||||
collection.add(new OutputItemImpl(FileUtil.toSystemIndependentName(compiledFile.getPath()), file));
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
CompilerUtil.refreshIOFiles(filesToRefresh);
|
||||
for (Map.Entry<String, Collection<OutputItem>> entry : outputs.entrySet()) {
|
||||
sink.add(entry.getKey(), entry.getValue(), VirtualFile.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
private static File doCompile(VirtualFile out, VirtualFile src) throws IOException {
|
||||
final String originalName = src.getName();
|
||||
String compiledName = originalName.substring(0, originalName.length() - FILETYPE_EXTENSION.length());
|
||||
final File destFile = new File(out.getPath(), compiledName + ".java");
|
||||
FileUtil.copy(new File(src.getPath()), destFile);
|
||||
return destFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return DESCRIPTION;
|
||||
}
|
||||
|
||||
public boolean validateConfiguration(final CompileScope scope) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.EnvironmentUtil;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class ExternalCompiler implements BackendCompiler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.ExternalCompiler");
|
||||
private static final Set<FileType> COMPILABLE_TYPES = Collections.<FileType>singleton(StdFileTypes.JAVA);
|
||||
|
||||
@NotNull
|
||||
public abstract String[] createStartupCommand(ModuleChunk chunk, CompileContext context, String outputPath)
|
||||
throws IOException, IllegalArgumentException;
|
||||
|
||||
@NotNull
|
||||
public Set<FileType> getCompilableFileTypes() {
|
||||
return COMPILABLE_TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the compiler can compile the specified file.
|
||||
*
|
||||
* @param file the file to check.
|
||||
* @param context the context for the current compile operation.
|
||||
* @return true if can compile the file, false otherwise. If the method returns false, <code>file</code>
|
||||
* will not be included in the list of files passed to {@link #compile(CompileContext, com.intellij.util.Chunk < com.intellij.openapi.module.Module >,com.intellij.openapi.vfs.VirtualFile[], com.intellij.openapi.compiler.TranslatingCompiler.OutputSink)}.
|
||||
*/
|
||||
public boolean isCompilableFile(VirtualFile file, CompileContext context) {
|
||||
return getCompilableFileTypes().contains(file.getFileType());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Process launchProcess(@NotNull final ModuleChunk chunk, @NotNull final String outputDir, @NotNull final CompileContext compileContext) throws IOException {
|
||||
final String[] commands = createStartupCommand(chunk, compileContext, outputDir);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
@NonNls final StringBuilder buf = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
buf.append("\n===================================Environment:===========================\n");
|
||||
for (String pair : EnvironmentUtil.getEnvironment()) {
|
||||
buf.append("\t").append(pair).append("\n");
|
||||
}
|
||||
buf.append("=============================================================================\n");
|
||||
buf.append("Running compiler: ");
|
||||
for (final String command : commands) {
|
||||
buf.append(" ").append(command);
|
||||
}
|
||||
|
||||
LOG.debug(buf.toString());
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(buf);
|
||||
}
|
||||
}
|
||||
|
||||
return Runtime.getRuntime().exec(commands);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class FileObject {
|
||||
private static final byte[] NOT_LOADED = ArrayUtil.EMPTY_BYTE_ARRAY;
|
||||
|
||||
private final File myFile;
|
||||
private final byte[] myContent;
|
||||
|
||||
public FileObject(@NotNull File file, @NotNull byte[] content) {
|
||||
myFile = file;
|
||||
myContent = content;
|
||||
}
|
||||
|
||||
public FileObject(File file) {
|
||||
myFile = file;
|
||||
myContent = NOT_LOADED;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return myFile;
|
||||
}
|
||||
|
||||
public byte[] getContent() throws IOException {
|
||||
if (myContent == NOT_LOADED) {
|
||||
return FileUtil.loadFileBytes(myFile);
|
||||
}
|
||||
return myContent;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author: Eugene Zhuravlev
|
||||
* Date: Jan 17, 2003
|
||||
* Time: 3:22:59 PM
|
||||
*/
|
||||
package com.intellij.compiler.impl.javaCompiler;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerConfigurationImpl;
|
||||
import com.intellij.compiler.CompilerException;
|
||||
import com.intellij.compiler.impl.CompileDriver;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class JavaCompiler implements TranslatingCompiler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavaCompiler");
|
||||
private final Project myProject;
|
||||
|
||||
public JavaCompiler(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return CompilerBundle.message("java.compiler.description");
|
||||
}
|
||||
|
||||
public boolean isCompilableFile(VirtualFile file, CompileContext context) {
|
||||
final BackendCompiler backEndCompiler = getBackEndCompiler();
|
||||
if (backEndCompiler instanceof ExternalCompiler) {
|
||||
return ((ExternalCompiler)backEndCompiler).isCompilableFile(file, context);
|
||||
}
|
||||
return backEndCompiler.getCompilableFileTypes().contains(file.getFileType());
|
||||
}
|
||||
|
||||
public void compile(CompileContext context, Chunk<Module> moduleChunk, VirtualFile[] files, OutputSink sink) {
|
||||
final BackendCompiler backEndCompiler = getBackEndCompiler();
|
||||
final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(moduleChunk, myProject, Arrays.asList(files), (CompileContextEx)context, backEndCompiler, sink);
|
||||
try {
|
||||
if (CompileDriver.ourDebugMode) {
|
||||
System.out.println("Starting java compiler; with backend compiler: " + backEndCompiler.getClass().getName());
|
||||
}
|
||||
wrapper.compile();
|
||||
}
|
||||
catch (CompilerException e) {
|
||||
if (CompileDriver.ourDebugMode) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
|
||||
LOG.info(e);
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
if (CompileDriver.ourDebugMode) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
LOG.info(e);
|
||||
context.requestRebuildNextTime(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean validateConfiguration(CompileScope scope) {
|
||||
return getBackEndCompiler().checkCompiler(scope);
|
||||
}
|
||||
|
||||
private BackendCompiler getBackEndCompiler() {
|
||||
CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
|
||||
return configuration.getDefaultCompiler();
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
class OutputDir {
|
||||
private final String myPath;
|
||||
private final int myKind;
|
||||
|
||||
OutputDir(@NotNull String path, int kind) {
|
||||
myPath = path;
|
||||
myKind = kind;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getPath() {
|
||||
return myPath;
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return myKind;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof OutputDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final OutputDir outputDir = (OutputDir)o;
|
||||
|
||||
return myKind == outputDir.myKind && myPath.equals(outputDir.myPath);
|
||||
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = myPath.hashCode();
|
||||
result = 29 * result + myKind;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author: Eugene Zhuravlev
|
||||
* Date: Apr 1, 2003
|
||||
* Time: 5:58:41 PM
|
||||
*/
|
||||
package com.intellij.compiler.impl.javaCompiler;
|
||||
|
||||
import com.intellij.openapi.compiler.TranslatingCompiler;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class OutputItemImpl implements TranslatingCompiler.OutputItem{
|
||||
|
||||
private final String myOutputPath;
|
||||
private final VirtualFile mySourceFile;
|
||||
|
||||
public OutputItemImpl(VirtualFile packageInfoFile) {
|
||||
this(null, packageInfoFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param outputPath absolute path of the output file ('/' slashes used)
|
||||
* @param sourceFile corresponding source file
|
||||
*/
|
||||
public OutputItemImpl(@Nullable String outputPath, VirtualFile sourceFile) {
|
||||
myOutputPath = outputPath;
|
||||
mySourceFile = sourceFile;
|
||||
}
|
||||
|
||||
public String getOutputPath() {
|
||||
return myOutputPath;
|
||||
}
|
||||
|
||||
public VirtualFile getSourceFile() {
|
||||
return mySourceFile;
|
||||
}
|
||||
}
|
||||
-180
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.compiler.OutputParser;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.source.util.TaskEvent;
|
||||
import com.sun.source.util.TaskListener;
|
||||
import com.sun.tools.javac.api.JavacTool;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.tools.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
@SuppressWarnings({"Since15"})
|
||||
class CompAPIDriver {
|
||||
private final BlockingQueue<CompilationEvent> myCompilationResults = new LinkedBlockingQueue<CompilationEvent>();
|
||||
private static final CompilationEvent GUARD = new CompilationEvent() {
|
||||
@Override
|
||||
protected void process(OutputParser.Callback callback) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FINISH";
|
||||
}
|
||||
};
|
||||
private String myOutputDir;
|
||||
|
||||
private volatile boolean compiling;
|
||||
private static final PrintWriter COMPILER_ERRORS = new PrintWriter(System.err);
|
||||
@Nullable
|
||||
private final String mySourcesEncoding;
|
||||
|
||||
CompAPIDriver(@Nullable String sourcesEncoding) {
|
||||
mySourcesEncoding = sourcesEncoding;
|
||||
}
|
||||
|
||||
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 standardFileManager = compiler.getStandardFileManager(null, null, null);
|
||||
MyFileManager manager = new MyFileManager(this, outputDir, standardFileManager, mySourcesEncoding);
|
||||
|
||||
Iterable<? extends JavaFileObject> input = manager.getJavaFileObjectsFromFiles(paths);
|
||||
|
||||
DiagnosticListener<JavaFileObject> listener = new DiagnosticListener<JavaFileObject>() {
|
||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
CompilationEvent event = CompilationEvent.diagnostic(diagnostic);
|
||||
myCompilationResults.offer(event);
|
||||
}
|
||||
};
|
||||
try {
|
||||
JavaCompiler.CompilationTask task = compiler.getTask(COMPILER_ERRORS, manager, listener, commandLine, null, input);
|
||||
((JavacTask)task).setTaskListener(new TaskListener() {
|
||||
public void started(TaskEvent taskEvent) {
|
||||
JavaFileObject sourceFile = taskEvent.getSourceFile();
|
||||
CompilationEvent event;
|
||||
switch (taskEvent.getKind()) {
|
||||
case ANALYZE:
|
||||
event = CompilationEvent.progress("Analyzing ",sourceFile);
|
||||
break;
|
||||
case PARSE:
|
||||
event = CompilationEvent.progress("Parsing ", sourceFile);
|
||||
break;
|
||||
default:
|
||||
event = null;
|
||||
}
|
||||
if (event != null) {
|
||||
myCompilationResults.offer(event);
|
||||
}
|
||||
}
|
||||
public void finished(TaskEvent taskEvent) {
|
||||
CompilationEvent event;
|
||||
switch (taskEvent.getKind()) {
|
||||
case ENTER:
|
||||
event = CompilationEvent.fileProcessed();
|
||||
break;
|
||||
default:
|
||||
event = null;
|
||||
}
|
||||
if (event != null) {
|
||||
myCompilationResults.offer(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
task.call();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
final String message = "Javac in-process compiler error: " + e.getMessage();
|
||||
myCompilationResults.offer(new CompilationEvent() {
|
||||
@Override
|
||||
protected void process(OutputParser.Callback callback) {
|
||||
callback.message(CompilerMessageCategory.ERROR, message, null, -1, -1);
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
compiling = false;
|
||||
myCompilationResults.offer(GUARD);
|
||||
try {
|
||||
manager.close();
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private volatile boolean processing;
|
||||
public void processAll(@NotNull OutputParser.Callback callback) {
|
||||
try {
|
||||
processing = true;
|
||||
while (true) {
|
||||
CompilationEvent event = myCompilationResults.take();
|
||||
if (event == GUARD) break;
|
||||
event.process(callback);
|
||||
}
|
||||
}
|
||||
catch (InterruptedException ignored) {
|
||||
}
|
||||
finally {
|
||||
processing = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
assert !compiling : "still compiling to "+myOutputDir;
|
||||
assert !processing;
|
||||
//assert myCompilationResults.isEmpty() : myCompilationResults;
|
||||
myCompilationResults.clear();
|
||||
cleanupInternalFields();
|
||||
}
|
||||
|
||||
private static void cleanupInternalFields() {
|
||||
try {
|
||||
Field freelist = Class.forName("com.sun.tools.javac.util.SharedNameTable").getDeclaredField("freelist");
|
||||
freelist.setAccessible(true);
|
||||
freelist.set(null, com.sun.tools.javac.util.List.nil());
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void offerClassFile(URI uri, byte[] bytes) {
|
||||
CompilationEvent event = CompilationEvent.generateClass(uri, bytes);
|
||||
myCompilationResults.offer(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
-127
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.FileObject;
|
||||
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.*;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
abstract class CompilationEvent {
|
||||
protected abstract void process(OutputParser.Callback callback);
|
||||
static CompilationEvent progress(final String title, final JavaFileObject fileObject) {
|
||||
return new CompilationEvent() {
|
||||
@Override
|
||||
protected void process(OutputParser.Callback callback) {
|
||||
showProgressFor(title, fileObject.toUri(), callback);
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Progress: "+title+" "+fileObject.toUri();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void showProgressFor(String title, URI uri, OutputParser.Callback callback) {
|
||||
String normalizedPath;
|
||||
try {
|
||||
normalizedPath = new File(uri).getPath();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
normalizedPath = uri.toString();
|
||||
}
|
||||
callback.setProgressText(title + StringUtil.last(normalizedPath, 100, true));
|
||||
}
|
||||
|
||||
static CompilationEvent generateClass(final URI uri, final byte[] bytes) {
|
||||
return new CompilationEvent() {
|
||||
@Override
|
||||
protected void process(OutputParser.Callback callback) {
|
||||
showProgressFor("Writing ", uri, callback);
|
||||
File file = new File(uri);
|
||||
callback.fileGenerated(new FileObject(file,bytes));
|
||||
}
|
||||
@NonNls
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Write: "+uri;
|
||||
}
|
||||
};
|
||||
}
|
||||
static CompilationEvent diagnostic(final Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
return new CompilationEvent() {
|
||||
@Override
|
||||
protected void process(OutputParser.Callback callback) {
|
||||
JavaFileObject fileObject = diagnostic.getSource();
|
||||
String message = diagnostic.getMessage(null);
|
||||
String url;
|
||||
if (fileObject == null) {
|
||||
url = null;
|
||||
}
|
||||
else {
|
||||
URI uri = fileObject.toUri();
|
||||
if (uri.getScheme().equals("file")) {
|
||||
url = VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(uri.getPath()));
|
||||
}
|
||||
else {
|
||||
url = fileObject.toString();
|
||||
}
|
||||
}
|
||||
|
||||
CompilerMessageCategory category = diagnostic.getKind() == Diagnostic.Kind.ERROR
|
||||
? CompilerMessageCategory.ERROR
|
||||
: diagnostic.getKind() == Diagnostic.Kind.WARNING ||
|
||||
diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING
|
||||
? CompilerMessageCategory.WARNING
|
||||
: CompilerMessageCategory.INFORMATION;
|
||||
callback.message(category, message, url, (int)diagnostic.getLineNumber(), (int)diagnostic.getColumnNumber());
|
||||
}
|
||||
@NonNls
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Diagnostic: "+diagnostic;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static CompilationEvent fileProcessed() {
|
||||
return FILE_PROCESSED;
|
||||
}
|
||||
private static final CompilationEvent FILE_PROCESSED = new CompilationEvent() {
|
||||
@Override
|
||||
protected void process(OutputParser.Callback callback) {
|
||||
callback.fileProcessed(null);
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Processed";
|
||||
}
|
||||
};
|
||||
}
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacConfigurable;
|
||||
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.options.Configurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
public CompilerAPICompiler(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public boolean checkCompiler(final CompileScope scope) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getId() { // used for externalization
|
||||
return JavaCompilers.JAVAC_API_ID;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getPresentableName() {
|
||||
return "Javac in-process (Java6+ only)";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Configurable createConfigurable() {
|
||||
return new JavacConfigurable(CompilerAPIConfiguration.getOptions(myProject, CompilerAPIConfiguration.class));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<FileType> getCompilableFileTypes() {
|
||||
return COMPILABLE_TYPES;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OutputParser createErrorParser(@NotNull final String outputDir, final Process process) {
|
||||
return new OutputParser() {
|
||||
public boolean processMessageLine(Callback callback) {
|
||||
((MyProcess)process).myCompAPIDriver.processAll(callback);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OutputParser createOutputParser(@NotNull final String outputDir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void compileFinished() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Process launchProcess(@NotNull final ModuleChunk chunk, @NotNull final String outputDir, @NotNull final CompileContext compileContext) throws IOException {
|
||||
@NonNls final List<String> commandLine =
|
||||
ApplicationManager.getApplication().runReadAction(new ThrowableComputable<List<String>, IOException>() {
|
||||
@Override
|
||||
public List<String> compute() throws IOException {
|
||||
List<String> commandLine = new ArrayList<String>();
|
||||
final List<String> additionalOptions =
|
||||
JavacCompiler.addAdditionalSettings(commandLine, CompilerAPIConfiguration .getOptions(myProject, CompilerAPIConfiguration.class), false,
|
||||
JavaSdkVersion.JDK_1_6, chunk, compileContext.isAnnotationProcessorsEnabled());
|
||||
|
||||
JavacCompiler.addCommandLineOptions(chunk, commandLine, outputDir, chunk.getJdk(), false, false, null, false, false, false);
|
||||
commandLine.addAll(additionalOptions);
|
||||
return commandLine;
|
||||
}
|
||||
});
|
||||
return new MyProcess(commandLine, chunk, outputDir, compileContext);
|
||||
}
|
||||
|
||||
private static void compile(List<String> commandLine, ModuleChunk chunk, String outputDir, CompAPIDriver myCompAPIDriver) {
|
||||
List<VirtualFile> filesToCompile = chunk.getFilesToCompile();
|
||||
List<File> paths = new ArrayList<File>(filesToCompile.size());
|
||||
for (VirtualFile file : filesToCompile) {
|
||||
paths.add(new File(file.getPresentableUrl()));
|
||||
}
|
||||
myCompAPIDriver.compile(commandLine, paths, outputDir);
|
||||
}
|
||||
|
||||
private static class MyProcess extends Process {
|
||||
private final List<String> myCommandLine;
|
||||
private final ModuleChunk myChunk;
|
||||
private final String myOutputDir;
|
||||
private final CompileContext myCompileContext;
|
||||
private final CompAPIDriver myCompAPIDriver;
|
||||
|
||||
private MyProcess(List<String> commandLine, ModuleChunk chunk, String outputDir, CompileContext compileContext) {
|
||||
myCommandLine = commandLine;
|
||||
myChunk = chunk;
|
||||
myOutputDir = outputDir;
|
||||
myCompileContext = compileContext;
|
||||
myCompAPIDriver = new CompAPIDriver(findEncodingValue(commandLine));
|
||||
}
|
||||
|
||||
private static String findEncodingValue(List<String> commandLine) {
|
||||
boolean found = false;
|
||||
for (String param : commandLine) {
|
||||
if (found) {
|
||||
return param;
|
||||
}
|
||||
if ("-encoding".equalsIgnoreCase(param)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
myCompAPIDriver.finish();
|
||||
}
|
||||
|
||||
private int myExitCode;
|
||||
public int waitFor() {
|
||||
try {
|
||||
myCommandLine.remove("-verbose");
|
||||
compile(myCommandLine, myChunk, myOutputDir, myCompAPIDriver);
|
||||
myExitCode = 0;
|
||||
return myExitCode;
|
||||
}
|
||||
catch (Exception e) {
|
||||
myCompileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
|
||||
LOG.info(e);
|
||||
myExitCode = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int exitValue() {
|
||||
return myExitCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myChunk.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.compiler.impl.javaCompiler.javac.JavacConfiguration;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.components.StorageScheme;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
@State(
|
||||
name = "CompilerAPISettings",
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.PROJECT_FILE),
|
||||
@Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
|
||||
}
|
||||
)
|
||||
public class CompilerAPIConfiguration extends JavacConfiguration {
|
||||
public CompilerAPIConfiguration(Project project) {
|
||||
super(project);
|
||||
}
|
||||
}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerConfigurationImpl;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompileStatusNotification;
|
||||
import com.intellij.openapi.compiler.CompilerManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class CompilerPerfTestAction extends AnAction {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
Project project = e.getData(CommonDataKeys.PROJECT);
|
||||
e.getPresentation().setEnabled(project != null);
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final Project project = e.getData(CommonDataKeys.PROJECT);
|
||||
|
||||
final CompilerManager compilerManager = CompilerManager.getInstance(project);
|
||||
|
||||
final CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
|
||||
List<BackendCompiler> compilers = (List<BackendCompiler>)configuration.getRegisteredJavaCompilers();
|
||||
final List<BackendCompiler> allCompilers = ContainerUtil.concat(compilers, compilers, compilers, compilers, compilers, compilers, compilers);
|
||||
final int[] i = new int[1];
|
||||
|
||||
CompileStatusNotification callback = new CompileStatusNotification() {
|
||||
volatile long start;
|
||||
BackendCompiler compiler;
|
||||
|
||||
public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
|
||||
if (compiler == null) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
final long finish = System.currentTimeMillis();
|
||||
System.out.println("Compiled with '" +
|
||||
compiler.getPresentableName() + "' " +
|
||||
" in " +
|
||||
TimeUnit.MILLISECONDS.toMinutes(finish - start) + "m" +
|
||||
TimeUnit.MILLISECONDS.toSeconds((finish - start)%60000) + "s" +
|
||||
" with " +
|
||||
errors +
|
||||
" errors, " +
|
||||
warnings +
|
||||
" warnings, aborted=" +
|
||||
aborted+"; free memory="+Runtime.getRuntime().freeMemory()+" bytes");
|
||||
//ProfilingUtil.forceCaptureMemorySnapshot();
|
||||
next();
|
||||
}
|
||||
|
||||
void next() {
|
||||
if (i[0] >= allCompilers.size()) return;
|
||||
compiler = allCompilers.get(i[0]++);
|
||||
if (compiler.getId().equals("Jikes")|| compiler.getId().contains("Eclipse")) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
boolean success = compiler.checkCompiler(compilerManager.createProjectCompileScope(project));
|
||||
if (!success) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
configuration.setDefaultCompiler(compiler);
|
||||
start = System.currentTimeMillis();
|
||||
compilerManager.rebuild(this);
|
||||
}
|
||||
};
|
||||
|
||||
callback.finished(false,0,0,null);
|
||||
}
|
||||
}
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.fileEditor.impl.LoadTextUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import javax.tools.*;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
@SuppressWarnings({"Since15"})
|
||||
public abstract class FileVirtualObject extends SimpleJavaFileObject {
|
||||
public FileVirtualObject(URI uri, Kind kind) {
|
||||
super(uri, kind);
|
||||
}
|
||||
|
||||
protected abstract VirtualFile getVirtualFile();
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||
VirtualFile virtualFile = getVirtualFile();
|
||||
if (virtualFile == null) return null;
|
||||
return LoadTextUtil.loadText(virtualFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
// in-process compiler does not work well with zipped stream
|
||||
byte[] bytes = getVirtualFile().contentsToByteArray();
|
||||
return new ByteArrayInputStream(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
return getVirtualFile().getOutputStream(this);
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* 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 com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* User: cdr
|
||||
*/
|
||||
@SuppressWarnings({"Since15"})
|
||||
class JavaIoFile extends SimpleJavaFileObject {
|
||||
private final File myFile;
|
||||
@Nullable
|
||||
private final String myEncoding;
|
||||
|
||||
JavaIoFile(@NotNull File file, @NotNull Kind kind, @Nullable String encoding) {
|
||||
super(convertToURI(file.getPath()), kind);
|
||||
myFile = file;
|
||||
myEncoding = encoding;
|
||||
}
|
||||
|
||||
// File.toURI() asks for File.isDirectory which is too expensive
|
||||
@NotNull
|
||||
private static URI convertToURI(@NotNull String path) {
|
||||
if (File.separatorChar != '/') {
|
||||
path = path.replace(File.separatorChar, '/');
|
||||
}
|
||||
if (!StringUtil.startsWithChar(path, '/')) {
|
||||
path = "/" + path;
|
||||
}
|
||||
|
||||
if (path.startsWith("//")) {
|
||||
path = "//" + path;
|
||||
}
|
||||
try {
|
||||
return new URI("file", null, path, null);
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||
return FileUtil.loadFile(myFile, myEncoding);
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
-260
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
class MyFileManager implements StandardJavaFileManager {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.api.MyFileManager");
|
||||
|
||||
private final String myOutputDir;
|
||||
private final StandardJavaFileManager myStandardFileManager;
|
||||
private final String myEncoding;
|
||||
private final CompAPIDriver myCompAPIDriver;
|
||||
|
||||
MyFileManager(CompAPIDriver compAPIDriver, String outputDir, StandardJavaFileManager standardFileManager, String encoding) {
|
||||
myCompAPIDriver = compAPIDriver;
|
||||
myOutputDir = outputDir;
|
||||
myStandardFileManager = standardFileManager;
|
||||
myEncoding = encoding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
|
||||
int size = ((Collection)files).size();
|
||||
List<JavaFileObject> result = new ArrayList<JavaFileObject>(size);
|
||||
|
||||
for (File file : files) {
|
||||
JavaFileObject fileObject = new JavaIoFile(file, JavaFileObject.Kind.SOURCE, myEncoding);
|
||||
result.add(fileObject);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject fileObject) {
|
||||
URI uri = toURI(myOutputDir, name, kind);
|
||||
return new Output(uri, myCompAPIDriver, kind);
|
||||
}
|
||||
|
||||
static URI createUri(String url) {
|
||||
return URI.create(url.replaceAll(" ","%20"));
|
||||
}
|
||||
|
||||
private static URI toURI(String outputDir, String name, JavaFileObject.Kind kind) {
|
||||
return createUri("file:///" + outputDir.replace('\\','/') + "/" + name.replace('.', '/') + kind.extension);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<JavaFileObject> list(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) throws IOException {
|
||||
if (recurse) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return findInside(location, packageName, kinds, false);
|
||||
}
|
||||
|
||||
private List<JavaFileObject> findInside(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean lookForFile)
|
||||
throws IOException {
|
||||
Iterable<? extends File> path = getLocation(location);
|
||||
if (path == null) return Collections.emptyList();
|
||||
|
||||
String subdirectory = packageName.replace('.', '/');
|
||||
List<JavaFileObject> results = null;
|
||||
|
||||
for (File directory : path) {
|
||||
VirtualFile dir = LocalFileSystem.getInstance().findFileByIoFile(directory);
|
||||
if (dir == null) continue;
|
||||
if (!dir.isDirectory()) {
|
||||
dir = JarFileSystem.getInstance().getJarRootForLocalFile(dir);
|
||||
if (dir == null) continue;
|
||||
}
|
||||
VirtualFile virtualFile = StringUtil.isEmptyOrSpaces(subdirectory) ? dir : dir.findFileByRelativePath(subdirectory);
|
||||
if (virtualFile == null) continue;
|
||||
|
||||
VirtualFile[] children;
|
||||
if (lookForFile) {
|
||||
if (!virtualFile.isDirectory()) {
|
||||
children = new VirtualFile[]{virtualFile};
|
||||
}
|
||||
else continue;
|
||||
}
|
||||
else {
|
||||
children = virtualFile.getChildren();
|
||||
}
|
||||
for (VirtualFile child : children) {
|
||||
JavaFileObject.Kind kind = getKind("." + child.getExtension());
|
||||
if (kinds == null || 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
|
||||
|
||||
// use VFS to read content inside .jar
|
||||
String childPath = child.getPath();
|
||||
JavaFileObject fileObject = !childPath.contains("!/") ? new JavaIoFile(new File(childPath), kind, myEncoding) : new JavaVirtualFile(child, kind);
|
||||
results.add(fileObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<JavaFileObject> ret = results == null ? Collections.<JavaFileObject>emptyList() : results;
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
// for testing consistency
|
||||
Collection c = (Collection)myStandardFileManager.list(location, packageName, kinds, false);
|
||||
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;
|
||||
}
|
||||
|
||||
private static JavaFileObject.Kind getKind(String name) {
|
||||
if (name.endsWith(JavaFileObject.Kind.CLASS.extension))
|
||||
return JavaFileObject.Kind.CLASS;
|
||||
else if (name.endsWith(JavaFileObject.Kind.SOURCE.extension))
|
||||
return JavaFileObject.Kind.SOURCE;
|
||||
else if (name.endsWith(JavaFileObject.Kind.HTML.extension))
|
||||
return JavaFileObject.Kind.HTML;
|
||||
else
|
||||
return JavaFileObject.Kind.OTHER;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String inferBinaryName(Location location, JavaFileObject file) {
|
||||
return FileUtil.getNameWithoutExtension(new File(file.getName()).getName());
|
||||
}
|
||||
|
||||
////////// delegates
|
||||
@Override
|
||||
public int isSupportedOption(String option) {
|
||||
return myStandardFileManager.isSupportedOption(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
myStandardFileManager.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
myStandardFileManager.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleOption(String current, Iterator<String> remaining) {
|
||||
return myStandardFileManager.handleOption(current, remaining);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader(Location location) {
|
||||
return myStandardFileManager.getClassLoader(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameFile(FileObject a, FileObject b) {
|
||||
if (a instanceof FileVirtualObject && b instanceof FileVirtualObject || a instanceof Output && b instanceof Output) {
|
||||
return a.equals(b);
|
||||
}
|
||||
return myStandardFileManager.isSameFile(a, b);
|
||||
}
|
||||
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
|
||||
return getJavaFileObjectsFromFiles(Arrays.asList(files));
|
||||
}
|
||||
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
|
||||
return getJavaFileObjectsFromStrings(Arrays.asList(names));
|
||||
}
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
|
||||
ListBuffer<File> files = new ListBuffer<File>();
|
||||
for (String name : names) {
|
||||
files.append(new File(name));
|
||||
}
|
||||
return getJavaFileObjectsFromFiles(files.toList());
|
||||
}
|
||||
|
||||
public JavaFileObject getJavaFileForInput(Location location, String className, JavaFileObject.Kind kind) throws IOException {
|
||||
List<JavaFileObject> result = findInside(location, className, kind == null ? null : Collections.singleton(kind), true);
|
||||
if (!result.isEmpty()) {
|
||||
return result.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
|
||||
return getJavaFileForInput(location, packageName + "/" + relativeName, getKind(relativeName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
|
||||
return getJavaFileForOutput(location, packageName + "/" + relativeName, getKind(relativeName), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends File> getLocation(Location location) {
|
||||
return myStandardFileManager.getLocation(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(Location location, Iterable<? extends File> path) throws IOException {
|
||||
myStandardFileManager.setLocation(location, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocation(Location location) {
|
||||
return myStandardFileManager.hasLocation(location);
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* 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 org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.tools.*;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* User: cdr
|
||||
*/
|
||||
@SuppressWarnings({"ALL"})
|
||||
class Output extends SimpleJavaFileObject {
|
||||
private final CompAPIDriver myCompAPIDriver;
|
||||
@Nullable
|
||||
private volatile byte[] myFileBytes;
|
||||
|
||||
Output(URI uri, CompAPIDriver compAPIDriver, final Kind kind) {
|
||||
super(uri, kind);
|
||||
myCompAPIDriver = compAPIDriver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteArrayOutputStream openOutputStream() {
|
||||
return new ByteArrayOutputStream() {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
final byte[] bytes = toByteArray();
|
||||
myFileBytes = bytes;
|
||||
if (Kind.CLASS.equals(kind)) {
|
||||
myCompAPIDriver.offerClassFile(toUri(), bytes);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
final byte[] bytes = myFileBytes;
|
||||
if (bytes == null) {
|
||||
throw new FileNotFoundException(toUri().getPath());
|
||||
}
|
||||
return new ByteArrayInputStream(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||
final byte[] bytes = myFileBytes;
|
||||
if (bytes == null) {
|
||||
throw null;
|
||||
}
|
||||
return new String(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toUri().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof JavaFileObject && toUri().equals(((JavaFileObject)obj).toUri());
|
||||
}
|
||||
}
|
||||
+11
-155
@@ -15,43 +15,24 @@
|
||||
*/
|
||||
package com.intellij.compiler.impl.javaCompiler.eclipse;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.impl.javaCompiler.ExternalCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
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 org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.java.compiler.EclipseCompilerOptions;
|
||||
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class EclipseCompiler extends ExternalCompiler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.eclipse.EclipseCompiler");
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public class EclipseCompiler implements BackendCompiler {
|
||||
private final Project myProject;
|
||||
private final List<File> myTempFiles = new ArrayList<File>();
|
||||
private static final String COMPILER_CLASS_NAME = "org.eclipse.jdt.core.compiler.batch.BatchCompiler";
|
||||
@NonNls private static final String PATH_TO_COMPILER_JAR = findJarPah();
|
||||
|
||||
@@ -84,24 +65,6 @@ public class EclipseCompiler extends ExternalCompiler {
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
public boolean checkCompiler(final CompileScope scope) {
|
||||
if (!isInitialized()) {
|
||||
Messages.showMessageDialog(
|
||||
myProject,
|
||||
CompilerBundle.message("eclipse.compiler.error.jar.not.found", PATH_TO_COMPILER_JAR),
|
||||
CompilerBundle.message("compiler.eclipse.name"),
|
||||
Messages.getErrorIcon()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public static String getCompilerClass() {
|
||||
return "org.eclipse.jdt.internal.compiler.batch.Main";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getId() { // used for externalization
|
||||
return JavaCompilers.ECLIPSE_ID;
|
||||
@@ -117,116 +80,9 @@ public class EclipseCompiler extends ExternalCompiler {
|
||||
return new EclipseCompilerConfigurable(EclipseCompilerConfiguration.getOptions(myProject, EclipseCompilerConfiguration.class));
|
||||
}
|
||||
|
||||
public OutputParser createErrorParser(@NotNull final String outputDir, Process process) {
|
||||
return new EclipseCompilerErrorParser();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OutputParser createOutputParser(@NotNull final String outputDir) {
|
||||
return new EclipseCompilerOutputParser(outputDir);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] createStartupCommand(final ModuleChunk chunk, final CompileContext context, final String outputPath)
|
||||
throws IOException {
|
||||
|
||||
final ArrayList<String> commandLine = new ArrayList<String>();
|
||||
ApplicationManager.getApplication().runReadAction(new ThrowableComputable<Void, IOException>() {
|
||||
@Override
|
||||
public Void compute() throws IOException {
|
||||
createStartupCommand(chunk, commandLine, outputPath, true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return ArrayUtil.toStringArray(commandLine);
|
||||
}
|
||||
|
||||
private void createStartupCommand(final ModuleChunk chunk,
|
||||
@NonNls final ArrayList<String> commandLine,
|
||||
final String outputPath,
|
||||
final boolean useTempFile) throws IOException {
|
||||
final EclipseCompilerOptions options = EclipseCompilerConfiguration.getOptions(myProject, EclipseCompilerConfiguration.class);
|
||||
|
||||
final Sdk projectJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
|
||||
final String vmExePath = ((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk);
|
||||
commandLine.add(vmExePath);
|
||||
commandLine.add("-Xmx" + options.MAXIMUM_HEAP_SIZE + "m");
|
||||
|
||||
CompilerUtil.addLocaleOptions(commandLine, false);
|
||||
|
||||
commandLine.add("-classpath");
|
||||
commandLine.add(PATH_TO_COMPILER_JAR);
|
||||
commandLine.add(getCompilerClass());
|
||||
|
||||
addCommandLineOptions(commandLine, chunk, outputPath, options, useTempFile, true);
|
||||
}
|
||||
|
||||
public void addCommandLineOptions(@NotNull @NonNls final List<String> commandLine,
|
||||
@NotNull final ModuleChunk chunk,
|
||||
@NotNull final String outputPath,
|
||||
@NotNull final EclipseCompilerOptions options,
|
||||
final boolean useTempFile,
|
||||
boolean quoteBootClasspath) throws IOException {
|
||||
final Sdk jdk = chunk.getJdk();
|
||||
CompilerUtil.addSourceCommandLineSwitch(jdk, chunk.getLanguageLevel(), commandLine);
|
||||
CompilerUtil.addTargetCommandLineSwitch(chunk, commandLine);
|
||||
|
||||
final String bootCp = chunk.getCompilationBootClasspath();
|
||||
|
||||
final String classPath = chunk.getCompilationClasspath();
|
||||
|
||||
if (!StringUtil.isEmpty(bootCp)) {
|
||||
commandLine.add("-bootclasspath");
|
||||
// important: need to quote boot classpath if path to jdk contain spaces
|
||||
commandLine.add(quoteBootClasspath ? CompilerUtil.quotePath(bootCp) : bootCp);
|
||||
}
|
||||
|
||||
if (!StringUtil.isEmpty(classPath)) {
|
||||
commandLine.add("-classpath");
|
||||
commandLine.add(classPath);
|
||||
}
|
||||
|
||||
commandLine.add("-d");
|
||||
commandLine.add(outputPath.replace('/', File.separatorChar));
|
||||
|
||||
commandLine.add("-verbose");
|
||||
StringTokenizer tokenizer = new StringTokenizer(new EclipseSettingsBuilder(options).getOptionsString(chunk), " ");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
commandLine.add(tokenizer.nextToken());
|
||||
}
|
||||
|
||||
final List<VirtualFile> files = chunk.getFilesToCompile();
|
||||
|
||||
if (useTempFile) {
|
||||
File sourcesFile = FileUtil.createTempFile("javac", ".tmp");
|
||||
sourcesFile.deleteOnExit();
|
||||
myTempFiles.add(sourcesFile);
|
||||
final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(sourcesFile)));
|
||||
try {
|
||||
for (final VirtualFile file : files) {
|
||||
// Important: should use "/" slashes!
|
||||
// but not for JDK 1.5 - see SCR 36673
|
||||
final String path = file.getPath().replace('/', File.separatorChar);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Adding path for compilation " + path);
|
||||
}
|
||||
writer.println(CompilerUtil.quotePath(path));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
commandLine.add("@" + sourcesFile.getAbsolutePath());
|
||||
}
|
||||
else {
|
||||
for (VirtualFile file : files) {
|
||||
commandLine.add(file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void compileFinished() {
|
||||
FileUtil.asyncDelete(myTempFiles);
|
||||
myTempFiles.clear();
|
||||
@Override
|
||||
public Set<FileType> getCompilableFileTypes() {
|
||||
return Collections.<FileType>singleton(StdFileTypes.JAVA);
|
||||
}
|
||||
}
|
||||
|
||||
-255
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Alexey
|
||||
*/
|
||||
|
||||
package com.intellij.compiler.impl.javaCompiler.eclipse;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.FileObject;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import org.eclipse.jdt.core.compiler.IProblem;
|
||||
import org.eclipse.jdt.core.compiler.InvalidInputException;
|
||||
import org.eclipse.jdt.internal.compiler.*;
|
||||
import org.eclipse.jdt.internal.compiler.Compiler;
|
||||
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
|
||||
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
|
||||
import org.eclipse.jdt.internal.compiler.batch.Main;
|
||||
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
|
||||
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public class EclipseCompilerDriver {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.eclipse.EclipseCompilerDriver");
|
||||
|
||||
private String[] sourceFilePaths;
|
||||
private Map compilerOptions;
|
||||
private final BlockingQueue<CompilationResult> myCompilationResults = new LinkedBlockingQueue<CompilationResult>();
|
||||
private FileSystem classPath;
|
||||
|
||||
private void parseCommandLine(String[] args) throws InvalidInputException {
|
||||
StringWriter err = new StringWriter();
|
||||
Main driver = new Main(null, new PrintWriter(err), false);
|
||||
driver.configure(args);
|
||||
StringBuffer buffer = err.getBuffer();
|
||||
if (buffer.length() != 0) {
|
||||
throw new InvalidInputException(buffer.toString());
|
||||
}
|
||||
sourceFilePaths = driver.filenames;
|
||||
compilerOptions = driver.options;
|
||||
classPath = driver.getLibraryAccess();
|
||||
}
|
||||
|
||||
private CompilationUnit[] getCompilationUnits() {
|
||||
int fileCount = sourceFilePaths.length;
|
||||
CompilationUnit[] units = new CompilationUnit[fileCount];
|
||||
final String defaultEncoding = null;
|
||||
|
||||
for (int i = 0; i < fileCount; i++) {
|
||||
units[i] = new MyCompilationUnit(sourceFilePaths[i], defaultEncoding);
|
||||
}
|
||||
return units;
|
||||
}
|
||||
|
||||
private ICompilerRequestor getBatchRequestor(final CompileContext compileContext) {
|
||||
return new ICompilerRequestor() {
|
||||
public void acceptResult(CompilationResult compilationResult) {
|
||||
ProgressIndicator progress = compileContext.getProgressIndicator();
|
||||
if (progress != null) {
|
||||
progress.checkCanceled();
|
||||
}
|
||||
myCompilationResults.offer(compilationResult);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static final CompilationResult END_OF_STREAM = new CompilationResult(new char[0], 0, 0, 0);
|
||||
|
||||
private INameEnvironment getEnvironment() {
|
||||
return classPath;
|
||||
}
|
||||
|
||||
private static IProblemFactory getProblemFactory() {
|
||||
return new DefaultProblemFactory(Locale.getDefault());
|
||||
}
|
||||
|
||||
private static IErrorHandlingPolicy getHandlingPolicy() {
|
||||
return new IErrorHandlingPolicy() {
|
||||
public boolean proceedOnErrors() {
|
||||
return false; // stop if there are some errors
|
||||
}
|
||||
|
||||
public boolean stopOnFirstError() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Map getCompilerOptions() {
|
||||
return compilerOptions;
|
||||
}
|
||||
|
||||
|
||||
private void compile(final CompileContext compileContext) {
|
||||
final INameEnvironment environment = getEnvironment();
|
||||
|
||||
Compiler compiler =
|
||||
new Compiler(
|
||||
environment,
|
||||
getHandlingPolicy(),
|
||||
getCompilerOptions(),
|
||||
getBatchRequestor(compileContext),
|
||||
getProblemFactory()){
|
||||
protected void handleInternalException(Throwable internalException, CompilationUnitDeclaration unit, CompilationResult result) {
|
||||
if (internalException instanceof ProcessCanceledException) throw (ProcessCanceledException)internalException;
|
||||
super.handleInternalException(internalException, unit, result);
|
||||
}
|
||||
};
|
||||
compiler.parseThreshold = 2500;
|
||||
try {
|
||||
compiler.compile(getCompilationUnits());
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
//compileContext.addMessage(CompilerMessageCategory.ERROR, "Canceled",null,-1,-1);
|
||||
}
|
||||
catch (Exception e) {
|
||||
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (indicator == null || !indicator.isCanceled()) {
|
||||
compileContext.addMessage(CompilerMessageCategory.ERROR, "Internal Error: "+e.toString(),null,-1,-1);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myCompilationResults.offer(END_OF_STREAM);
|
||||
environment.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean processMessageLine(final OutputParser.Callback callback, final String outputDir, Project project) {
|
||||
ProgressManager.checkCanceled();
|
||||
CompilationResult result;
|
||||
try {
|
||||
result = myCompilationResults.take();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
LOG.error(e);
|
||||
return true;
|
||||
}
|
||||
if (result == END_OF_STREAM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String file = String.valueOf(result.getFileName());
|
||||
callback.setProgressText(CompilerBundle.message("eclipse.compiler.parsing", file));
|
||||
callback.fileProcessed(file);
|
||||
|
||||
ClassFile[] classFiles = result.getClassFiles();
|
||||
for (ClassFile classFile : classFiles) {
|
||||
String filePath = String.valueOf(classFile.fileName());
|
||||
String relativePath = FileUtil.toSystemDependentName(filePath + ".class");
|
||||
String path = FileUtil.toSystemDependentName(outputDir) + File.separatorChar + relativePath;
|
||||
|
||||
byte[] bytes = classFile.getBytes();
|
||||
File out = new File(path);
|
||||
|
||||
callback.fileGenerated(new FileObject(out,bytes));
|
||||
}
|
||||
IProblem[] problems = result.getProblems();
|
||||
if (problems != null) {
|
||||
for (IProblem problem : problems) {
|
||||
CompilerMessageCategory category = problem.isError() ? CompilerMessageCategory.ERROR
|
||||
: problem.isWarning() ? CompilerMessageCategory.WARNING :
|
||||
CompilerMessageCategory.INFORMATION;
|
||||
String filePath = String.valueOf(problem.getOriginatingFileName());
|
||||
String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, FileUtil.toSystemIndependentName(filePath));
|
||||
int lineNumber = problem.getSourceLineNumber();
|
||||
int sourceStart = problem.getSourceStart();
|
||||
int column = getColumn(url, lineNumber, sourceStart, project);
|
||||
callback.message(category, problem.getMessage(), url, lineNumber, column);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int getColumn(final String url, final int lineNumber, final int sourceStart, final Project project) {
|
||||
if (sourceStart == 0) return 0;
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
|
||||
public Integer compute() {
|
||||
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
|
||||
if (file == null) return 0;
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
if (document == null) return 0;
|
||||
int lineStartOffset = document.getLineStartOffset(lineNumber - 1);
|
||||
|
||||
String lineSeparator = FileDocumentManager.getInstance().getLineSeparator(file, project);
|
||||
int offsetInVirtualFile = sourceStart - (lineNumber - 1) * (lineSeparator.length() - 1);
|
||||
return offsetInVirtualFile - lineStartOffset + 1;
|
||||
}
|
||||
}).intValue();
|
||||
}
|
||||
|
||||
public void parseCommandLineAndCompile(final String[] finalCmds, final CompileContext compileContext) throws Exception {
|
||||
parseCommandLine(finalCmds);
|
||||
|
||||
compile(compileContext);
|
||||
}
|
||||
|
||||
private static class MyCompilationUnit extends CompilationUnit {
|
||||
private final String myDefaultEncoding;
|
||||
|
||||
private MyCompilationUnit(final String sourceFilePath, final String defaultEncoding) {
|
||||
super(null, sourceFilePath, defaultEncoding);
|
||||
myDefaultEncoding = defaultEncoding;
|
||||
}
|
||||
|
||||
public char[] getContents() {
|
||||
final String fileName = String.valueOf(getFileName());
|
||||
try {
|
||||
ProgressManager.checkCanceled();
|
||||
return FileUtil.loadFileText(new File(fileName), myDefaultEncoding);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.eclipse;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class EclipseCompilerErrorParser extends OutputParser {
|
||||
|
||||
private final StringBuilder problemText = new StringBuilder();
|
||||
|
||||
public boolean processMessageLine(Callback callback) {
|
||||
@NonNls String line = callback.getNextLine();
|
||||
if (line == null) {
|
||||
spitOutProblem(callback);
|
||||
return false;
|
||||
}
|
||||
if (line.trim().length() == 0) {
|
||||
return true;
|
||||
}
|
||||
if (line.equals("----------")) {
|
||||
spitOutProblem(callback);
|
||||
problemText.setLength(0);
|
||||
return true;
|
||||
}
|
||||
problemText.append(line);
|
||||
problemText.append("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
private void spitOutProblem(final Callback callback) {
|
||||
final String problem = problemText.toString();
|
||||
if (problem.trim().length() == 0) return;
|
||||
|
||||
@NonNls final String problemTemplate = "(\\d*)\\. (\\w*) in (.*)" +
|
||||
"\\s*\\(at line (\\d*)\\)\n" +
|
||||
"\\s*(.*)\n" +
|
||||
"(\\s*)\\^+\n" +
|
||||
"(.*)\\s*";
|
||||
final Pattern PATTERN = Pattern.compile(problemTemplate, Pattern.DOTALL);
|
||||
Matcher matcher = PATTERN.matcher(problem);
|
||||
if (matcher.matches()) {
|
||||
//String seqN = matcher.group(1);
|
||||
@NonNls String problemType = matcher.group(2);
|
||||
String path = matcher.group(3).trim();
|
||||
String lineNum = matcher.group(4);
|
||||
String codeSnippet = matcher.group(5);
|
||||
String indentWhiteSpace = matcher.group(6);
|
||||
String message = matcher.group(7).trim();
|
||||
|
||||
CompilerMessageCategory messageCategory;
|
||||
if ("WARNING".equals(problemType)) {
|
||||
messageCategory = CompilerMessageCategory.WARNING;
|
||||
}
|
||||
else if ("ERROR".equals(problemType)) {
|
||||
messageCategory = CompilerMessageCategory.ERROR;
|
||||
}
|
||||
else {
|
||||
messageCategory = CompilerMessageCategory.INFORMATION;
|
||||
}
|
||||
final String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, FileUtil.toSystemIndependentName(path));
|
||||
final int line = Integer.parseInt(lineNum);
|
||||
int col = indentWhiteSpace.length();
|
||||
final String offendingCode = codeSnippet.substring(col-1);
|
||||
|
||||
// try to find similar text inside source file
|
||||
int colFromFile = ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
|
||||
public Integer compute() {
|
||||
int index = -1;
|
||||
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
|
||||
Document document = file == null ? null : FileDocumentManager.getInstance().getDocument(file);
|
||||
if (document != null) {
|
||||
// line is one-based
|
||||
int docLine = line == 0 ? 0 : line-1;
|
||||
int startOffset = document.getLineStartOffset(docLine);
|
||||
int endOffset = document.getLineEndOffset(docLine);
|
||||
String lineText = document.getText().substring(startOffset, endOffset);
|
||||
index = lineText.indexOf(offendingCode);
|
||||
if (index == -1) {
|
||||
for (index = 0; index < lineText.length(); index++) {
|
||||
if (!Character.isWhitespace(lineText.charAt(index))) break;
|
||||
}
|
||||
if (index == lineText.length()) index = -1;
|
||||
}
|
||||
// to one-based
|
||||
if (index != -1) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}).intValue();
|
||||
if (colFromFile != -1) {
|
||||
col = colFromFile;
|
||||
}
|
||||
callback.message(messageCategory, message, url, line, col);
|
||||
}
|
||||
else {
|
||||
callback.message(CompilerMessageCategory.WARNING, problem, null, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTrimLines() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.eclipse;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.FileObject;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class EclipseCompilerOutputParser extends OutputParser {
|
||||
private final String myOutputDir;
|
||||
|
||||
public EclipseCompilerOutputParser(final String outputDir) {
|
||||
myOutputDir = outputDir;
|
||||
}
|
||||
|
||||
@NonNls private static final Pattern PATH_PATTERN = Pattern.compile("\\s*(.*) - #.*");
|
||||
@NonNls private static final Pattern COMPILED_PATTERN = Pattern.compile("\\[\\d* unit(s)? compiled\\]");
|
||||
@NonNls private static final Pattern GENERATED_PATTERN = Pattern.compile("\\[\\d* \\.class file(s)? generated\\]");
|
||||
public boolean processMessageLine(Callback callback) {
|
||||
@NonNls String line = callback.getNextLine();
|
||||
if (line == null) {
|
||||
return false;
|
||||
}
|
||||
if (line.trim().length() == 0) {
|
||||
return true;
|
||||
}
|
||||
if (line.startsWith("[parsing ")) {
|
||||
Matcher matcher = PATH_PATTERN.matcher(line.substring("[parsing ".length()));
|
||||
matcher.matches();
|
||||
String path = matcher.group(1);
|
||||
callback.setProgressText(CompilerBundle.message("eclipse.compiler.parsing", path));
|
||||
callback.fileProcessed(path);
|
||||
return true;
|
||||
}
|
||||
if (line.startsWith("[reading ")) {
|
||||
//StringTokenizer tokenizer = new StringTokenizer(line.substring("[reading ".length()), " ]");
|
||||
//String fqn = tokenizer.nextToken();
|
||||
callback.setProgressText(CompilerBundle.message("eclipse.compiler.reading"));
|
||||
return true;
|
||||
}
|
||||
if (line.startsWith("[analyzing ")) {
|
||||
Matcher matcher = PATH_PATTERN.matcher(line.substring("[analyzing ".length()));
|
||||
matcher.matches();
|
||||
String path = matcher.group(1);
|
||||
callback.setProgressText(CompilerBundle.message("eclipse.compiler.analyzing", path));
|
||||
return true;
|
||||
}
|
||||
if (line.startsWith("[completed ")) {
|
||||
//Matcher matcher = PATH_PATTERN.matcher(line.substring("[completed ".length()));
|
||||
//matcher.matches();
|
||||
//String path = matcher.group(1);
|
||||
//callback.setProgressText(CompilerBundle.message("eclipse.compiler.completed", path));
|
||||
return true;
|
||||
}
|
||||
if (line.startsWith("[writing ")) {
|
||||
Matcher matcher = PATH_PATTERN.matcher(line.substring("[writing ".length()));
|
||||
matcher.matches();
|
||||
String path = matcher.group(1);
|
||||
String absPath = FileUtil.toSystemDependentName(myOutputDir + '/' + path);
|
||||
//callback.setProgressText(CompilerBundle.message("eclipse.compiler.writing", absPath));
|
||||
callback.fileGenerated(new FileObject(new File(absPath)));
|
||||
return true;
|
||||
}
|
||||
if (COMPILED_PATTERN.matcher(line).matches() || GENERATED_PATTERN.matcher(line).matches()) {
|
||||
return true;
|
||||
}
|
||||
callback.message(CompilerMessageCategory.INFORMATION, line, null, -1, -1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.eclipse;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
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;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.java.compiler.EclipseCompilerOptions;
|
||||
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
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;
|
||||
private final EclipseCompilerDriver myEclipseCompilerDriver;
|
||||
private static final Set<FileType> COMPILABLE_TYPES = Collections.<FileType>singleton(StdFileTypes.JAVA);
|
||||
|
||||
public EclipseEmbeddedCompiler(Project project) {
|
||||
myProject = project;
|
||||
myEclipseExternalCompiler = new EclipseCompiler(project);
|
||||
myEclipseCompilerDriver = new EclipseCompilerDriver();
|
||||
}
|
||||
|
||||
public boolean checkCompiler(final CompileScope scope) {
|
||||
return myEclipseCompilerDriver != null && myEclipseExternalCompiler.checkCompiler(scope);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getId() { // used for externalization
|
||||
return JavaCompilers.ECLIPSE_EMBEDDED_ID;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getPresentableName() {
|
||||
return CompilerBundle.message("compiler.eclipse.embedded.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Configurable createConfigurable() {
|
||||
return new EclipseCompilerConfigurable(EclipseEmbeddedCompilerConfiguration.getOptions(myProject, EclipseEmbeddedCompilerConfiguration.class));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<FileType> getCompilableFileTypes() {
|
||||
return COMPILABLE_TYPES;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OutputParser createErrorParser(@NotNull final String outputDir, Process process) {
|
||||
return new OutputParser() {
|
||||
public boolean processMessageLine(Callback callback) {
|
||||
return myEclipseCompilerDriver.processMessageLine(callback, outputDir, myProject);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OutputParser createOutputParser(@NotNull final String outputDir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void compileFinished() {
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public Process launchProcess(@NotNull final ModuleChunk chunk, @NotNull final String outputDir, @NotNull final CompileContext compileContext) throws IOException {
|
||||
@NonNls final ArrayList<String> commandLine = new ArrayList<String>();
|
||||
ApplicationManager.getApplication().runReadAction(new ThrowableComputable<Void, IOException>() {
|
||||
@Override
|
||||
public Void compute() throws IOException {
|
||||
final EclipseCompilerOptions options =
|
||||
EclipseCompilerConfiguration.getOptions(myProject, EclipseEmbeddedCompilerConfiguration.class);
|
||||
myEclipseExternalCompiler.addCommandLineOptions(commandLine, chunk, outputDir, options, false, false);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return new Process() {
|
||||
public OutputStream getOutputStream() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public int waitFor() {
|
||||
try {
|
||||
commandLine.remove("-verbose");
|
||||
String[] finalCmds = ArrayUtil.toStringArray(commandLine);
|
||||
myEclipseCompilerDriver.parseCommandLineAndCompile(finalCmds, compileContext);
|
||||
myExitCode = 0;
|
||||
return myExitCode;
|
||||
}
|
||||
catch (Exception e) {
|
||||
compileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
|
||||
LOG.info(e);
|
||||
myExitCode = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int exitValue() {
|
||||
return myExitCode;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.eclipse;
|
||||
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.components.StorageScheme;
|
||||
|
||||
@State(
|
||||
name = "EclipseEmbeddedCompilerSettings",
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.PROJECT_FILE),
|
||||
@Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
|
||||
}
|
||||
)
|
||||
public class EclipseEmbeddedCompilerConfiguration extends EclipseCompilerConfiguration {
|
||||
}
|
||||
+1
-3
@@ -16,14 +16,12 @@
|
||||
package com.intellij.compiler.impl.javaCompiler.javac;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.FileObject;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -59,7 +57,7 @@ public class FilePathActionJavac extends JavacParserAction {
|
||||
callback.setProgressText(CompilerBundle.message("progress.parsing.file", name));
|
||||
}
|
||||
else if (StdFileTypes.CLASS.equals(fileType)) {
|
||||
callback.fileGenerated(new FileObject(new File(filePath)));
|
||||
callback.fileGenerated(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-401
@@ -15,122 +15,26 @@
|
||||
*/
|
||||
package com.intellij.compiler.impl.javaCompiler.javac;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerConfigurationImpl;
|
||||
import com.intellij.compiler.CompilerIOUtil;
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.impl.javaCompiler.ExternalCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.compiler.CompilerPaths;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.*;
|
||||
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
|
||||
import com.intellij.openapi.projectRoots.impl.MockJdkWrapper;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.rt.compiler.JavacRunner;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
|
||||
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
|
||||
import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public class JavacCompiler extends ExternalCompiler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler");
|
||||
public class JavacCompiler implements BackendCompiler {
|
||||
private final Project myProject;
|
||||
private final List<File> myTempFiles = new ArrayList<File>();
|
||||
@NonNls private static final String JAVAC_MAIN_CLASS_OLD = "sun.tools.javac.Main";
|
||||
@NonNls public static final String JAVAC_MAIN_CLASS = "com.sun.tools.javac.Main";
|
||||
private boolean myAnnotationProcessorMode = false;
|
||||
|
||||
public JavacCompiler(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public boolean isAnnotationProcessorMode() {
|
||||
return myAnnotationProcessorMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param annotationProcessorMode
|
||||
* @return previous value
|
||||
*/
|
||||
public boolean setAnnotationProcessorMode(boolean annotationProcessorMode) {
|
||||
final boolean oldValue = myAnnotationProcessorMode;
|
||||
myAnnotationProcessorMode = annotationProcessorMode;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public boolean checkCompiler(final CompileScope scope) {
|
||||
final Module[] modules = scope.getAffectedModules();
|
||||
final Set<Sdk> checkedJdks = new HashSet<Sdk>();
|
||||
for (final Module module : modules) {
|
||||
final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
|
||||
if (jdk == null || checkedJdks.contains(jdk)) {
|
||||
continue;
|
||||
}
|
||||
checkedJdks.add(jdk);
|
||||
final SdkTypeId sdkType = jdk.getSdkType();
|
||||
if (!(sdkType instanceof JavaSdkType)) {
|
||||
continue;
|
||||
}
|
||||
final VirtualFile homeDirectory = jdk.getHomeDirectory();
|
||||
if (homeDirectory == null) {
|
||||
Messages.showMessageDialog(
|
||||
myProject, CompilerBundle.jdkHomeNotFoundMessage(jdk), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
final String vmExecutablePath = ((JavaSdkType)sdkType).getVMExecutablePath(jdk);
|
||||
if (vmExecutablePath == null) {
|
||||
Messages.showMessageDialog(
|
||||
myProject, CompilerBundle.message("javac.error.vm.executable.missing", jdk.getName()), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
final String toolsJarPath = ((JavaSdkType)sdkType).getToolsPath(jdk);
|
||||
if (toolsJarPath == null) {
|
||||
Messages.showMessageDialog(
|
||||
myProject, CompilerBundle.message("javac.error.tools.jar.missing", jdk.getName()), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
final String versionString = jdk.getVersionString();
|
||||
if (versionString == null) {
|
||||
Messages.showMessageDialog(
|
||||
myProject, CompilerBundle.message("javac.error.unknown.jdk.version", jdk.getName()), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CompilerUtil.isOfVersion(versionString, "1.0")) {
|
||||
Messages.showMessageDialog(
|
||||
myProject, CompilerBundle.message("javac.error.1_0_compilation.not.supported"), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getId() { // used for externalization
|
||||
@@ -147,304 +51,8 @@ public class JavacCompiler extends ExternalCompiler {
|
||||
return new JavacConfigurable(JavacConfiguration.getOptions(myProject, JavacConfiguration.class));
|
||||
}
|
||||
|
||||
public OutputParser createErrorParser(@NotNull final String outputDir, Process process) {
|
||||
return new JavacOutputParser(myProject);
|
||||
}
|
||||
|
||||
public OutputParser createOutputParser(@NotNull final String outputDir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class MyException extends RuntimeException {
|
||||
private MyException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] createStartupCommand(final ModuleChunk chunk, final CompileContext context, final String outputPath)
|
||||
throws IOException, IllegalArgumentException {
|
||||
|
||||
try {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
|
||||
public String[] compute() {
|
||||
try {
|
||||
final List<String> commandLine = new ArrayList<String>();
|
||||
createStartupCommand(chunk, commandLine, outputPath, JavacConfiguration.getOptions(myProject, JavacConfiguration.class), context.isAnnotationProcessorsEnabled());
|
||||
return ArrayUtil.toStringArray(commandLine);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new MyException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (MyException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof IOException) {
|
||||
throw (IOException)cause;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void createStartupCommand(final ModuleChunk chunk, @NonNls final List<String> commandLine, final String outputPath,
|
||||
JpsJavaCompilerOptions javacOptions, final boolean annotationProcessorsEnabled) throws IOException {
|
||||
final Sdk jdk = getJdkForStartupCommand(chunk);
|
||||
final String versionString = jdk.getVersionString();
|
||||
JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk);
|
||||
if (versionString == null || version == null || !(jdk.getSdkType() instanceof JavaSdkType)) {
|
||||
throw new IllegalArgumentException(CompilerBundle.message("javac.error.unknown.jdk.version", jdk.getName()));
|
||||
}
|
||||
final boolean isVersion1_0 = version == JavaSdkVersion.JDK_1_0;
|
||||
final boolean isVersion1_1 = version == JavaSdkVersion.JDK_1_1;
|
||||
|
||||
JavaSdkType sdkType = (JavaSdkType)jdk.getSdkType();
|
||||
|
||||
final String toolsJarPath = sdkType.getToolsPath(jdk);
|
||||
if (toolsJarPath == null) {
|
||||
throw new IllegalArgumentException(CompilerBundle.message("javac.error.tools.jar.missing", jdk.getName()));
|
||||
}
|
||||
|
||||
final String vmExePath = sdkType.getVMExecutablePath(jdk);
|
||||
|
||||
commandLine.add(vmExePath);
|
||||
|
||||
if (version.isAtLeast(JavaSdkVersion.JDK_1_2)) {
|
||||
commandLine.add("-Xmx" + javacOptions.MAXIMUM_HEAP_SIZE + "m");
|
||||
}
|
||||
else {
|
||||
commandLine.add("-mx" + javacOptions.MAXIMUM_HEAP_SIZE + "m");
|
||||
}
|
||||
|
||||
final List<String> additionalOptions =
|
||||
addAdditionalSettings(commandLine, javacOptions, myAnnotationProcessorMode, version, chunk, annotationProcessorsEnabled);
|
||||
|
||||
CompilerUtil.addLocaleOptions(commandLine, false);
|
||||
|
||||
commandLine.add("-classpath");
|
||||
|
||||
if (isVersion1_0) {
|
||||
commandLine.add(sdkType.getToolsPath(jdk)); // do not use JavacRunner for jdk 1.0
|
||||
}
|
||||
else {
|
||||
commandLine.add(sdkType.getToolsPath(jdk) + File.pathSeparator + JavaSdkUtil.getIdeaRtJarPath());
|
||||
commandLine.add(JavacRunner.class.getName());
|
||||
commandLine.add("\"" + versionString + "\"");
|
||||
}
|
||||
|
||||
if (version.isAtLeast(JavaSdkVersion.JDK_1_3)) {
|
||||
commandLine.add(JAVAC_MAIN_CLASS);
|
||||
}
|
||||
else {
|
||||
commandLine.add(JAVAC_MAIN_CLASS_OLD);
|
||||
}
|
||||
|
||||
addCommandLineOptions(chunk, commandLine, outputPath, jdk, isVersion1_0, isVersion1_1, myTempFiles, true, true, myAnnotationProcessorMode);
|
||||
|
||||
commandLine.addAll(additionalOptions);
|
||||
|
||||
final List<VirtualFile> files = chunk.getFilesToCompile();
|
||||
|
||||
if (isVersion1_0) {
|
||||
for (VirtualFile file : files) {
|
||||
String path = file.getPath();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Adding path for compilation " + path);
|
||||
}
|
||||
commandLine.add(CompilerUtil.quotePath(path));
|
||||
}
|
||||
}
|
||||
else {
|
||||
File sourcesFile = FileUtil.createTempFile("javac", ".tmp");
|
||||
sourcesFile.deleteOnExit();
|
||||
myTempFiles.add(sourcesFile);
|
||||
final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(sourcesFile)));
|
||||
try {
|
||||
for (final VirtualFile file : files) {
|
||||
// Important: should use "/" slashes!
|
||||
// but not for JDK 1.5 - see SCR 36673
|
||||
final String path = version.isAtLeast(JavaSdkVersion.JDK_1_5) ? file.getPath().replace('/', File.separatorChar) : file.getPath();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Adding path for compilation " + path);
|
||||
}
|
||||
writer.println(isVersion1_1 ? path : CompilerUtil.quotePath(path));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
commandLine.add("@" + sourcesFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> addAdditionalSettings(List<String> commandLine, JpsJavaCompilerOptions javacOptions, boolean isAnnotationProcessing,
|
||||
JavaSdkVersion version, ModuleChunk chunk, boolean annotationProcessorsEnabled) {
|
||||
final List<String> additionalOptions = new ArrayList<String>();
|
||||
StringTokenizer tokenizer = new StringTokenizer(new JavacSettingsBuilder(javacOptions).getOptionsString(chunk), " ");
|
||||
if (!version.isAtLeast(JavaSdkVersion.JDK_1_6)) {
|
||||
isAnnotationProcessing = false; // makes no sense for these versions
|
||||
annotationProcessorsEnabled = false;
|
||||
}
|
||||
if (isAnnotationProcessing) {
|
||||
final AnnotationProcessingConfiguration config = CompilerConfiguration.getInstance(chunk.getProject()).getAnnotationProcessingConfiguration(chunk.getModules()[0]);
|
||||
additionalOptions.add("-Xprefer:source");
|
||||
additionalOptions.add("-implicit:none");
|
||||
additionalOptions.add("-proc:only");
|
||||
if (!config.isObtainProcessorsFromClasspath()) {
|
||||
final String processorPath = config.getProcessorPath();
|
||||
additionalOptions.add("-processorpath");
|
||||
additionalOptions.add(FileUtil.toSystemDependentName(processorPath));
|
||||
}
|
||||
final Set<String> processors = config.getProcessors();
|
||||
if (!processors.isEmpty()) {
|
||||
additionalOptions.add("-processor");
|
||||
additionalOptions.add(StringUtil.join(processors, ","));
|
||||
}
|
||||
for (Map.Entry<String, String> entry : config.getProcessorOptions().entrySet()) {
|
||||
additionalOptions.add("-A" + entry.getKey() + "=" +entry.getValue());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (annotationProcessorsEnabled) {
|
||||
// Unless explicitly specified by user, disable annotation processing by default for 'java compilation' mode
|
||||
// This is needed to suppress unwanted side-effects from auto-discovered processors from compilation classpath
|
||||
additionalOptions.add("-proc:none");
|
||||
}
|
||||
}
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
@NonNls String token = tokenizer.nextToken();
|
||||
if (version == JavaSdkVersion.JDK_1_0 && "-deprecation".equals(token)) {
|
||||
continue; // not supported for this version
|
||||
}
|
||||
if (!version.isAtLeast(JavaSdkVersion.JDK_1_5) && "-Xlint".equals(token)) {
|
||||
continue; // not supported in these versions
|
||||
}
|
||||
if (isAnnotationProcessing) {
|
||||
if (token.startsWith("-proc:")) {
|
||||
continue;
|
||||
}
|
||||
if (token.startsWith("-implicit:")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else { // compiling java
|
||||
if (annotationProcessorsEnabled) {
|
||||
// in this mode we have -proc:none already added above, so user's settings should be ignored
|
||||
if (token.startsWith("-proc:")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (token.startsWith("-J-")) {
|
||||
commandLine.add(token.substring("-J".length()));
|
||||
}
|
||||
else {
|
||||
additionalOptions.add(token);
|
||||
}
|
||||
}
|
||||
|
||||
return additionalOptions;
|
||||
}
|
||||
|
||||
public static void addCommandLineOptions(ModuleChunk chunk, @NonNls List<String> commandLine, String outputPath, Sdk jdk,
|
||||
boolean version1_0,
|
||||
boolean version1_1,
|
||||
List<File> tempFiles, boolean addSourcePath, boolean useTempFile,
|
||||
boolean isAnnotationProcessingMode) throws IOException {
|
||||
|
||||
LanguageLevel languageLevel = chunk.getLanguageLevel();
|
||||
CompilerUtil.addSourceCommandLineSwitch(jdk, languageLevel, commandLine);
|
||||
CompilerUtil.addTargetCommandLineSwitch(chunk, commandLine);
|
||||
|
||||
commandLine.add("-verbose");
|
||||
|
||||
final String cp = chunk.getCompilationClasspath();
|
||||
final String bootCp = chunk.getCompilationBootClasspath();
|
||||
|
||||
final String classPath;
|
||||
if (version1_0 || version1_1) {
|
||||
classPath = bootCp + File.pathSeparator + cp;
|
||||
}
|
||||
else {
|
||||
classPath = cp;
|
||||
commandLine.add("-bootclasspath");
|
||||
addClassPathValue(jdk, false, commandLine, bootCp, "javac_bootcp", tempFiles, useTempFile);
|
||||
}
|
||||
|
||||
commandLine.add("-classpath");
|
||||
addClassPathValue(jdk, version1_0, commandLine, classPath, "javac_cp", tempFiles, useTempFile);
|
||||
|
||||
if (!version1_1 && !version1_0 && addSourcePath) {
|
||||
commandLine.add("-sourcepath");
|
||||
// this way we tell the compiler that the sourcepath is "empty". However, javac thinks that sourcepath is 'new File("")'
|
||||
// this may cause problems if we have java code in IDEA working directory
|
||||
if (isAnnotationProcessingMode) {
|
||||
final int currentSourcesMode = chunk.getSourcesFilter();
|
||||
commandLine.add(chunk.getSourcePath(currentSourcesMode == ModuleChunk.TEST_SOURCES? ModuleChunk.ALL_SOURCES : currentSourcesMode));
|
||||
}
|
||||
else {
|
||||
commandLine.add("\"\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (isAnnotationProcessingMode) {
|
||||
commandLine.add("-s");
|
||||
commandLine.add(outputPath.replace('/', File.separatorChar));
|
||||
final String moduleOutputPath = CompilerPaths.getModuleOutputPath(chunk.getModules()[0], false);
|
||||
if (moduleOutputPath != null) {
|
||||
commandLine.add("-d");
|
||||
commandLine.add(moduleOutputPath.replace('/', File.separatorChar));
|
||||
}
|
||||
}
|
||||
else {
|
||||
commandLine.add("-d");
|
||||
commandLine.add(outputPath.replace('/', File.separatorChar));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addClassPathValue(final Sdk jdk, final boolean isVersion1_0, final List<String> commandLine, final String cpString, @NonNls final String tempFileName,
|
||||
List<File> tempFiles,
|
||||
boolean useTempFile) throws IOException {
|
||||
if (!useTempFile) {
|
||||
commandLine.add(cpString);
|
||||
return;
|
||||
}
|
||||
// must include output path to classpath, otherwise javac will compile all dependent files no matter were they compiled before or not
|
||||
if (isVersion1_0) {
|
||||
commandLine.add(((JavaSdkType)jdk.getSdkType()).getToolsPath(jdk) + File.pathSeparator + cpString);
|
||||
}
|
||||
else {
|
||||
File cpFile = FileUtil.createTempFile(tempFileName, ".tmp");
|
||||
cpFile.deleteOnExit();
|
||||
tempFiles.add(cpFile);
|
||||
final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(cpFile)));
|
||||
try {
|
||||
CompilerIOUtil.writeString(cpString, out);
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
commandLine.add("@" + cpFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private Sdk getJdkForStartupCommand(final ModuleChunk chunk) {
|
||||
final Sdk jdk = chunk.getJdk();
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() && JavacConfiguration.getOptions(myProject, JavacConfiguration.class).isTestsUseExternalCompiler()) {
|
||||
final String jdkHomePath = CompilerConfigurationImpl.getTestsExternalCompilerHome();
|
||||
if (jdkHomePath == null) {
|
||||
throw new IllegalArgumentException("[TEST-MODE] Cannot determine home directory for JDK to use javac from");
|
||||
}
|
||||
// when running under Mock JDK use VM executable from the JDK on which the tests run
|
||||
return new MockJdkWrapper(jdkHomePath, jdk);
|
||||
}
|
||||
return jdk;
|
||||
}
|
||||
|
||||
public void compileFinished() {
|
||||
FileUtil.asyncDelete(myTempFiles);
|
||||
myTempFiles.clear();
|
||||
@NotNull
|
||||
public Set<FileType> getCompilableFileTypes() {
|
||||
return Collections.<FileType>singleton(StdFileTypes.JAVA);
|
||||
}
|
||||
}
|
||||
|
||||
-3
@@ -277,7 +277,4 @@ public class JavacOutputParser extends OutputParser {
|
||||
return Pattern.compile(regexp, Pattern.CASE_INSENSITIVE).matcher("");
|
||||
}
|
||||
|
||||
public boolean isTrimLines() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.javac;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Sep 24, 2005
|
||||
*/
|
||||
public class StatisticsActionJavac extends JavacParserAction {
|
||||
private final String myProgressMessageResourceKey;
|
||||
|
||||
public StatisticsActionJavac(final Matcher matcher, String progressMessageResourceKey) {
|
||||
super(matcher);
|
||||
myProgressMessageResourceKey = progressMessageResourceKey;
|
||||
}
|
||||
|
||||
protected void doExecute(final String line, @Nullable String parsedData, final OutputParser.Callback callback) {
|
||||
callback.setProgressText(CompilerBundle.message(myProgressMessageResourceKey));
|
||||
}
|
||||
}
|
||||
-231
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.jikes;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerConfigurationImpl;
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.ExternalCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.compiler.options.JavaCompilersTab;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class JikesCompiler extends ExternalCompiler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.JikesHandler");
|
||||
private final Project myProject;
|
||||
private File myTempFile;
|
||||
|
||||
public JikesCompiler(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public boolean checkCompiler(final CompileScope scope) {
|
||||
String compilerPath = getCompilerPath();
|
||||
if (StringUtil.isEmpty(compilerPath)) {
|
||||
Messages.showMessageDialog(
|
||||
myProject,
|
||||
CompilerBundle.message("jikes.error.path.to.compiler.unspecified"), CompilerBundle.message("compiler.jikes.name"),
|
||||
Messages.getErrorIcon()
|
||||
);
|
||||
openConfigurationDialog();
|
||||
compilerPath = getCompilerPath(); // update path
|
||||
if (StringUtil.isEmpty(compilerPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
File file = new File(compilerPath);
|
||||
if (!file.exists()) {
|
||||
Messages.showMessageDialog(
|
||||
myProject,
|
||||
CompilerBundle.message("jikes.error.path.to.compiler.missing", compilerPath),
|
||||
CompilerBundle.message("compiler.jikes.name"),
|
||||
Messages.getErrorIcon()
|
||||
);
|
||||
openConfigurationDialog();
|
||||
compilerPath = getCompilerPath(); // update path
|
||||
if (StringUtil.isEmpty(compilerPath)) {
|
||||
return false;
|
||||
}
|
||||
if (!new File(compilerPath).exists()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void openConfigurationDialog() {
|
||||
final CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
|
||||
final Collection<BackendCompiler> compilers = configuration.getRegisteredJavaCompilers();
|
||||
final BackendCompiler defaultCompiler = configuration.getDefaultCompiler();
|
||||
final JavaCompilersTab compilersTab = new JavaCompilersTab(myProject, compilers, defaultCompiler);
|
||||
|
||||
ShowSettingsUtil.getInstance().editConfigurable(myProject, compilersTab);
|
||||
}
|
||||
|
||||
private String getCompilerPath() {
|
||||
return JikesConfiguration.getOptions(myProject).JIKES_PATH.replace('/', File.separatorChar);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getId() // used for externalization
|
||||
{
|
||||
return "Jikes";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getPresentableName() {
|
||||
return CompilerBundle.message("compiler.jikes.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Configurable createConfigurable() {
|
||||
return new JikesConfigurable(JikesConfiguration.getOptions(myProject));
|
||||
}
|
||||
|
||||
public OutputParser createErrorParser(@NotNull final String outputDir, Process process) {
|
||||
return new JikesOutputParser(myProject);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OutputParser createOutputParser(@NotNull final String outputDir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] createStartupCommand(final ModuleChunk chunk, final CompileContext context, final String outputPath)
|
||||
throws IOException {
|
||||
|
||||
final ArrayList<String> commandLine = new ArrayList<String>();
|
||||
ApplicationManager.getApplication().runReadAction(new ThrowableComputable<Void, IOException>() {
|
||||
@Override
|
||||
public Void compute() throws IOException {
|
||||
_createStartupCommand(chunk, commandLine, outputPath);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return ArrayUtil.toStringArray(commandLine);
|
||||
}
|
||||
|
||||
private void _createStartupCommand(final ModuleChunk chunk, final ArrayList<String> commandLine, @NotNull final String outputPath) throws IOException {
|
||||
|
||||
myTempFile = FileUtil.createTempFile("jikes", ".tmp");
|
||||
myTempFile.deleteOnExit();
|
||||
|
||||
final List<VirtualFile> files = chunk.getFilesToCompile();
|
||||
PrintWriter writer = new PrintWriter(new FileWriter(myTempFile));
|
||||
try {
|
||||
for (VirtualFile file : files) {
|
||||
writer.println(file.getPath());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
String compilerPath = getCompilerPath();
|
||||
LOG.assertTrue(compilerPath != null, "No path to compiler configured");
|
||||
|
||||
commandLine.add(compilerPath);
|
||||
|
||||
//noinspection HardCodedStringLiteral
|
||||
commandLine.add("-verbose");
|
||||
//noinspection HardCodedStringLiteral
|
||||
commandLine.add("-classpath");
|
||||
|
||||
// must include output path to classpath, otherwise javac will compile all dependent files no matter were they compiled before or not
|
||||
commandLine.add(chunk.getCompilationBootClasspath() + File.pathSeparator + chunk.getCompilationClasspath());
|
||||
|
||||
setupSourceVersion(chunk, commandLine);
|
||||
//noinspection HardCodedStringLiteral
|
||||
commandLine.add("-sourcepath");
|
||||
String sourcePath = chunk.getSourcePath();
|
||||
if (sourcePath.length() > 0) {
|
||||
commandLine.add(sourcePath);
|
||||
}
|
||||
else {
|
||||
commandLine.add("\"\"");
|
||||
}
|
||||
|
||||
//noinspection HardCodedStringLiteral
|
||||
commandLine.add("-d");
|
||||
commandLine.add(outputPath.replace('/', File.separatorChar));
|
||||
|
||||
JikesSettingsBuilder jikesSettings = new JikesSettingsBuilder(JikesConfiguration.getOptions(myProject));
|
||||
StringTokenizer tokenizer = new StringTokenizer(jikesSettings.getOptionsString(chunk), " ");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
commandLine.add(tokenizer.nextToken());
|
||||
}
|
||||
commandLine.add("@" + myTempFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private static void setupSourceVersion(final ModuleChunk chunk, final ArrayList<String> commandLine) {
|
||||
final Sdk jdk = chunk.getJdk();
|
||||
final String versionString = jdk.getVersionString();
|
||||
|
||||
final LanguageLevel applicableLanguageLevel = CompilerUtil.getApplicableLanguageLevel(versionString, chunk.getLanguageLevel());
|
||||
if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_5)) {
|
||||
commandLine.add("-source");
|
||||
commandLine.add("1.4"); // -source 1.5 not supported yet by jikes, so use the highest possible version
|
||||
}
|
||||
else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_4)) {
|
||||
commandLine.add("-source");
|
||||
commandLine.add("1.4");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void compileFinished() {
|
||||
if (myTempFile != null) {
|
||||
FileUtil.delete(myTempFile);
|
||||
myTempFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.jikes;
|
||||
|
||||
import com.intellij.compiler.options.ComparingUtils;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.RawCommandLineEditor;
|
||||
import org.jetbrains.jps.model.java.compiler.JikesCompilerOptions;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Mar 30, 2004
|
||||
*/
|
||||
public class JikesConfigurable implements Configurable {
|
||||
private JPanel myPanel;
|
||||
private JCheckBox myCbDebuggingInfo;
|
||||
private JCheckBox myCbDeprecation;
|
||||
private JCheckBox myCbGenerateNoWarnings;
|
||||
private RawCommandLineEditor myAdditionalOptionsField;
|
||||
private TextFieldWithBrowseButton myPathField;
|
||||
private final JikesCompilerOptions myJikesSettings;
|
||||
|
||||
public JikesConfigurable(JikesCompilerOptions jikesSettings) {
|
||||
myJikesSettings = jikesSettings;
|
||||
myPathField.getButton().addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor();
|
||||
VirtualFile file = FileChooser.chooseFile(descriptor, myPathField, null, null);
|
||||
if (file != null) {
|
||||
myPathField.setText(file.getPath().replace('/', File.separatorChar));
|
||||
}
|
||||
}
|
||||
});
|
||||
myAdditionalOptionsField.setDialogCaption(CompilerBundle.message("java.compiler.option.additional.command.line.parameters"));
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getHelpTopic() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public JComponent createComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
boolean isModified = false;
|
||||
isModified |= ComparingUtils.isModified(myPathField, myJikesSettings.JIKES_PATH.replace('/', File.separatorChar));
|
||||
isModified |= ComparingUtils.isModified(myCbDeprecation, myJikesSettings.DEPRECATION);
|
||||
isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myJikesSettings.DEBUGGING_INFO);
|
||||
isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myJikesSettings.GENERATE_NO_WARNINGS);
|
||||
isModified |= ComparingUtils.isModified(myAdditionalOptionsField, myJikesSettings.ADDITIONAL_OPTIONS_STRING);
|
||||
return isModified;
|
||||
}
|
||||
|
||||
public void apply() throws ConfigurationException {
|
||||
myJikesSettings.JIKES_PATH = myPathField.getText().trim().replace(File.separatorChar, '/');
|
||||
myJikesSettings.DEPRECATION = myCbDeprecation.isSelected();
|
||||
myJikesSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
|
||||
myJikesSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
|
||||
myJikesSettings.ADDITIONAL_OPTIONS_STRING = myAdditionalOptionsField.getText();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
myPathField.setText(myJikesSettings.JIKES_PATH.replace('/', File.separatorChar));
|
||||
myCbDeprecation.setSelected(myJikesSettings.DEPRECATION);
|
||||
myCbDebuggingInfo.setSelected(myJikesSettings.DEBUGGING_INFO);
|
||||
myCbGenerateNoWarnings.setSelected(myJikesSettings.GENERATE_NO_WARNINGS);
|
||||
myAdditionalOptionsField.setText(myJikesSettings.ADDITIONAL_OPTIONS_STRING);
|
||||
}
|
||||
|
||||
public void disposeUIResources() {
|
||||
}
|
||||
}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.jikes;
|
||||
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.java.compiler.JikesCompilerOptions;
|
||||
|
||||
@State(
|
||||
name = "JikesSettings",
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.PROJECT_FILE),
|
||||
@Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
|
||||
}
|
||||
)
|
||||
public class JikesConfiguration implements PersistentStateComponent<JikesCompilerOptions> {
|
||||
private final JikesCompilerOptions mySettings = new JikesCompilerOptions();
|
||||
|
||||
@NotNull
|
||||
public JikesCompilerOptions getState() {
|
||||
return mySettings;
|
||||
}
|
||||
|
||||
public void loadState(JikesCompilerOptions state) {
|
||||
XmlSerializerUtil.copyBean(state, mySettings);
|
||||
}
|
||||
|
||||
public static JikesCompilerOptions getOptions(Project project) {
|
||||
return ServiceManager.getService(project, JikesConfiguration.class).getState();
|
||||
}
|
||||
}
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.impl.javaCompiler.jikes.JikesConfigurable">
|
||||
<grid id="66887" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="103" y="66" width="439" height="254"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
|
||||
</clientProperties>
|
||||
<border type="etched" title-resource-bundle="messages/CompilerBundle" title-key="jikes.options.group.title"/>
|
||||
<children>
|
||||
<component id="3d38f" class="javax.swing.JCheckBox" binding="myCbDebuggingInfo">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<margin top="5" left="2" bottom="2" right="2"/>
|
||||
<selected value="true"/>
|
||||
<text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.debugging.info"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="90803" class="javax.swing.JCheckBox" binding="myCbGenerateNoWarnings">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<margin top="2" left="2" bottom="2" right="3"/>
|
||||
<selected value="true"/>
|
||||
<text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="8538e" class="javax.swing.JCheckBox" binding="myCbDeprecation">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<margin top="2" left="2" bottom="5" right="2"/>
|
||||
<selected value="true"/>
|
||||
<text resource-bundle="messages/CompilerBundle" key="java.compiler.option.report.deprecated"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="b6f66">
|
||||
<constraints>
|
||||
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="31c1" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="415eb" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myPathField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="327dc" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/CompilerBundle" key="jikes.option.path.to.executable"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="918d2" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="f8a80" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/CompilerBundle" key="java.compiler.option.additional.command.line.parameters"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="479c2" class="com.intellij.ui.RawCommandLineEditor" binding="myAdditionalOptionsField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.jikes;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.jps.model.java.compiler.JikesCompilerOptions;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class JikesOutputParser extends OutputParser {
|
||||
private final JikesCompilerOptions myJikesSettings;
|
||||
@NonNls private static final String JAVA_FILE_MSG_TAIL = ".java:";
|
||||
@NonNls private static final String CAUTION = "Caution";
|
||||
@NonNls private static final String WARNING = "Warning";
|
||||
@NonNls private static final String ERROR = "Error";
|
||||
@NonNls private static final String SEMANTIC_WARNING = "Semantic Warning";
|
||||
@NonNls private static final String SEMANTIC_ERROR = "Semantic Error";
|
||||
@NonNls private static final String ENTER_TO_CONTINUE_REGEXP = ".*Enter\\s+to\\s+continue.*";
|
||||
|
||||
public JikesOutputParser(Project project) {
|
||||
myJikesSettings = JikesConfiguration.getOptions(project);
|
||||
myParserActions.add(new ParserActionJikes());
|
||||
}
|
||||
|
||||
public boolean processMessageLine(Callback callback) {
|
||||
if (super.processMessageLine(callback)) {
|
||||
return true;
|
||||
}
|
||||
String line = callback.getCurrentLine();
|
||||
if (line == null) {
|
||||
return false;
|
||||
}
|
||||
if (line.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
//sae
|
||||
if (myJikesSettings.IS_EMACS_ERRORS_MODE) {
|
||||
|
||||
String filePath = "";
|
||||
final int tailIndex = line.indexOf(JAVA_FILE_MSG_TAIL);
|
||||
if (tailIndex > 5) filePath = line.substring(0, tailIndex + 5);
|
||||
filePath = filePath.replace(File.separatorChar, '/');
|
||||
final String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, filePath);
|
||||
if (tailIndex > 6) {
|
||||
line = line.substring(tailIndex + 6);
|
||||
int lineNum;
|
||||
|
||||
//second token = start line
|
||||
StringTokenizer tokenizer = new StringTokenizer(line, ":");
|
||||
//first token = filename
|
||||
String token = tokenizer.nextToken();
|
||||
|
||||
try {
|
||||
lineNum = Integer.parseInt(token);
|
||||
}
|
||||
catch (Exception e) {
|
||||
addMessage(callback, CompilerMessageCategory.INFORMATION, line);
|
||||
return true;
|
||||
}
|
||||
//thrd token = start column
|
||||
token = tokenizer.nextToken();
|
||||
int colNum;
|
||||
try {
|
||||
colNum = Integer.parseInt(token);
|
||||
}
|
||||
catch (Exception e) {
|
||||
addMessage(callback, CompilerMessageCategory.INFORMATION, line);
|
||||
return true;
|
||||
}
|
||||
//4,5 token = end line/column tmp not used
|
||||
tokenizer.nextToken();
|
||||
tokenizer.nextToken();
|
||||
// 6 error type
|
||||
CompilerMessageCategory category = CompilerMessageCategory.INFORMATION;
|
||||
token = tokenizer.nextToken().trim();
|
||||
if (CAUTION.equalsIgnoreCase(token)) {
|
||||
category = CompilerMessageCategory.WARNING;
|
||||
}
|
||||
else if (WARNING.equalsIgnoreCase(token) || SEMANTIC_WARNING.equalsIgnoreCase(token)) { // Semantic errors/warnings were introduced in jikes 1.18
|
||||
category = CompilerMessageCategory.WARNING;
|
||||
}
|
||||
else if (ERROR.equalsIgnoreCase(token) || SEMANTIC_ERROR.equalsIgnoreCase(token)) {
|
||||
category = CompilerMessageCategory.ERROR;
|
||||
}
|
||||
|
||||
String message = token;
|
||||
message = message.concat(" ");
|
||||
message = message.concat(tokenizer.nextToken(""));
|
||||
ArrayList<String> messages = new ArrayList<String>();
|
||||
messages.add(message);
|
||||
|
||||
if (colNum > 0 && messages.size() > 0) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (String m : messages) {
|
||||
if (buf.length() > 0) {
|
||||
buf.append("\n");
|
||||
}
|
||||
buf.append(m);
|
||||
}
|
||||
addMessage(callback, category, buf.toString(), url, lineNum, colNum);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//--sae
|
||||
|
||||
//Enter to continue
|
||||
if (!line.matches(ENTER_TO_CONTINUE_REGEXP)) {
|
||||
addMessage(callback, CompilerMessageCategory.INFORMATION, line);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.jikes;
|
||||
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacSettingsBuilder;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.jps.model.java.compiler.JikesCompilerOptions;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class JikesSettingsBuilder extends JavacSettingsBuilder {
|
||||
|
||||
public JikesSettingsBuilder(JikesCompilerOptions options) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JikesCompilerOptions getOptions() {
|
||||
return (JikesCompilerOptions)super.getOptions();
|
||||
}
|
||||
|
||||
public Collection<String> getOptions(Chunk<Module> chunk) {
|
||||
final Collection<String> options = super.getOptions(chunk);
|
||||
if(getOptions().IS_EMACS_ERRORS_MODE) {
|
||||
options.add("+E");
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
protected boolean acceptUserOption(String token) {
|
||||
if (!super.acceptUserOption(token)) {
|
||||
return false;
|
||||
}
|
||||
return !("++".equals(token) || "+M".equals(token) || "+F".equals(token) || "+E".equals(token));
|
||||
}
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.jikes;
|
||||
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.compiler.ParserAction;
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.FileObject;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* This class provides compatibility with older javac(english locale) and jikes versions and
|
||||
* implements parsing method from previous IDEA versions for jikes and javac compiler output.
|
||||
* Used in order not to miss some compiler output messages when jikes is configured as a preferred compiler
|
||||
* Also used in test mode in which javac is not run via JavacRunner
|
||||
*
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Sep 24, 2005
|
||||
*/
|
||||
public class ParserActionJikes extends ParserAction {
|
||||
@NonNls private static final String JAVA_EXTENSION = ".java";
|
||||
|
||||
public boolean execute(@NonNls String line, final OutputParser.Callback callback) {
|
||||
if (!StringUtil.startsWithChar(line, '[') || !StringUtil.endsWithChar(line, ']')) {
|
||||
return false;
|
||||
}
|
||||
if (line.startsWith("[parsing started")){ // javac
|
||||
String filePath = line.substring("[parsing started".length(), line.length() - 1).trim();
|
||||
processParsingMessage(callback, filePath.replace(File.separatorChar, '/'));
|
||||
}
|
||||
else if (line.startsWith("[parsed") && line.contains(JAVA_EXTENSION)) { // javac version 1.2.2
|
||||
int index = line.indexOf(JAVA_EXTENSION);
|
||||
String filePath = line.substring("[parsed".length(), index + JAVA_EXTENSION.length()).trim();
|
||||
processParsingMessage(callback, filePath.replace(File.separatorChar, '/'));
|
||||
}
|
||||
else if (line.startsWith("[read") && line.endsWith(".java]")){ // jikes
|
||||
String filePath = line.substring("[read".length(), line.length() - 1).trim();
|
||||
processParsingMessage(callback, filePath.replace(File.separatorChar, '/'));
|
||||
}
|
||||
else if (line.startsWith("[parsing completed")){
|
||||
}
|
||||
else if (line.startsWith("[loading") || line.startsWith("[loaded") || line.startsWith("[read")){
|
||||
callback.setProgressText(CompilerBundle.message("progress.loading.classes"));
|
||||
}
|
||||
else if (line.startsWith("[checking")){
|
||||
String className = line.substring("[checking".length(), line.length() - 1).trim();
|
||||
callback.setProgressText(CompilerBundle.message("progress.compiling.class", className));
|
||||
}
|
||||
else if (line.startsWith("[wrote") || line.startsWith("[write")){
|
||||
String filePath = line.substring("[wrote".length(), line.length() - 1).trim();
|
||||
processParsingMessage(callback, filePath.replace(File.separatorChar, '/'));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void processParsingMessage(final OutputParser.Callback callback, @NonNls final String filePath) {
|
||||
int index = filePath.lastIndexOf('/');
|
||||
final String name = index >= 0 ? filePath.substring(index + 1) : filePath;
|
||||
|
||||
final FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(name);
|
||||
if (StdFileTypes.JAVA.equals(fileType)) {
|
||||
callback.fileProcessed(filePath);
|
||||
callback.setProgressText(CompilerBundle.message("progress.parsing.file", name));
|
||||
}
|
||||
else if (StdFileTypes.CLASS.equals(fileType)) {
|
||||
callback.fileGenerated(new FileObject(new File(filePath)));
|
||||
}
|
||||
}
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
package com.intellij.compiler.impl.packagingCompiler;
|
||||
|
||||
import com.intellij.openapi.compiler.make.BuildInstruction;
|
||||
import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
|
||||
import com.intellij.openapi.compiler.make.BuildRecipe;
|
||||
import com.intellij.openapi.deployment.DeploymentUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public class BuildRecipeImpl implements BuildRecipe {
|
||||
private final List<BuildInstruction> myInstructions = new ArrayList<BuildInstruction>();
|
||||
|
||||
public void addInstruction(BuildInstruction instruction) {
|
||||
if (!contains(instruction)) {
|
||||
myInstructions.add(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(final BuildInstruction instruction) {
|
||||
return myInstructions.contains(instruction);
|
||||
}
|
||||
|
||||
public boolean visitInstructions(BuildInstructionVisitor visitor, boolean reverseOrder){
|
||||
try {
|
||||
return visitInstructionsWithExceptions(visitor, reverseOrder);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException)e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public boolean visitInstructionsWithExceptions(BuildInstructionVisitor visitor, boolean reverseOrder) throws Exception {
|
||||
for (int i = reverseOrder ? myInstructions.size()-1 : 0;
|
||||
reverseOrder ? i>=0 : i < myInstructions.size();
|
||||
i += reverseOrder ? -1 : 1) {
|
||||
BuildInstruction instruction = myInstructions.get(i);
|
||||
if (!instruction.accept(visitor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addFileCopyInstruction(@NotNull File file, boolean isDirectory, String outputRelativePath) {
|
||||
addInstruction(new FileCopyInstructionImpl(file, isDirectory, DeploymentUtil.trimForwardSlashes(outputRelativePath)));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String s = "Build recipe:";
|
||||
for (BuildInstruction buildInstruction : myInstructions) {
|
||||
s += "\n" + buildInstruction + "; ";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
-236
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author: Eugene Zhuravlev
|
||||
* Date: Jan 17, 2003
|
||||
* Time: 3:48:26 PM
|
||||
*/
|
||||
package com.intellij.compiler.impl.resourceCompiler;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerConfigurationImpl;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.make.MakeUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class ResourceCompiler implements TranslatingCompiler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.resourceCompiler.ResourceCompiler");
|
||||
private final Project myProject;
|
||||
private final CompilerConfiguration myConfiguration;
|
||||
private final ResourceCompilerExtension[] myResourceCompilerExtensions = ResourceCompilerExtension.EP_NAME.getExtensions();
|
||||
|
||||
public ResourceCompiler(Project project, CompilerConfiguration compilerConfiguration) {
|
||||
myProject = project;
|
||||
myConfiguration = compilerConfiguration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return CompilerBundle.message("resource.compiler.description");
|
||||
}
|
||||
|
||||
public boolean validateConfiguration(CompileScope scope) {
|
||||
((CompilerConfigurationImpl) CompilerConfiguration.getInstance(myProject)).convertPatterns();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isCompilableFile(VirtualFile file, CompileContext context) {
|
||||
final Module module = context.getModuleByFile(file);
|
||||
if (module != null && skipStandardResourceCompiler(module)) {
|
||||
return false;
|
||||
}
|
||||
return myConfiguration.isResourceFile(file);
|
||||
}
|
||||
|
||||
public void compile(final CompileContext context, Chunk<Module> moduleChunk, final VirtualFile[] files, OutputSink sink) {
|
||||
context.getProgressIndicator().pushState();
|
||||
context.getProgressIndicator().setText(CompilerBundle.message("progress.copying.resources"));
|
||||
|
||||
final Map<String, Collection<OutputItem>> processed = new HashMap<String, Collection<OutputItem>>();
|
||||
final LinkedList<CopyCommand> copyCommands = new LinkedList<CopyCommand>();
|
||||
final Module singleChunkModule = moduleChunk.getNodes().size() == 1? moduleChunk.getNodes().iterator().next() : null;
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
for (final VirtualFile file : files) {
|
||||
if (context.getProgressIndicator().isCanceled()) {
|
||||
break;
|
||||
}
|
||||
final Module module = singleChunkModule != null? singleChunkModule : context.getModuleByFile(file);
|
||||
if (module == null) {
|
||||
continue; // looks like file invalidated
|
||||
}
|
||||
final VirtualFile fileRoot = MakeUtil.getSourceRoot(context, module, file);
|
||||
if (fileRoot == null) {
|
||||
continue;
|
||||
}
|
||||
final String sourcePath = file.getPath();
|
||||
final String relativePath = VfsUtilCore.getRelativePath(file, fileRoot, '/');
|
||||
final boolean inTests = ((CompileContextEx)context).isInTestSourceContent(file);
|
||||
final VirtualFile outputDir = inTests? context.getModuleOutputDirectoryForTests(module) : context.getModuleOutputDirectory(module);
|
||||
if (outputDir == null) {
|
||||
continue;
|
||||
}
|
||||
final String outputPath = outputDir.getPath();
|
||||
|
||||
final String packagePrefix = fileIndex.getPackageNameByDirectory(fileRoot);
|
||||
final String targetPath;
|
||||
if (packagePrefix != null && packagePrefix.length() > 0) {
|
||||
targetPath = outputPath + "/" + packagePrefix.replace('.', '/') + "/" + relativePath;
|
||||
}
|
||||
else {
|
||||
targetPath = outputPath + "/" + relativePath;
|
||||
}
|
||||
if (sourcePath.equals(targetPath)) {
|
||||
addToMap(processed, outputPath, new MyOutputItem(targetPath, file));
|
||||
}
|
||||
else {
|
||||
copyCommands.add(new CopyCommand(outputPath, sourcePath, targetPath, file));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final List<File> filesToRefresh = new ArrayList<File>();
|
||||
// do actual copy outside of read action to reduce the time the application is locked on it
|
||||
while (!copyCommands.isEmpty()) {
|
||||
final CopyCommand command = copyCommands.removeFirst();
|
||||
if (context.getProgressIndicator().isCanceled()) {
|
||||
break;
|
||||
}
|
||||
//context.getProgressIndicator().setFraction((idx++) * 1.0 / total);
|
||||
context.getProgressIndicator().setText2("Copying " + command.getFromPath() + "...");
|
||||
try {
|
||||
final MyOutputItem outputItem = command.copy(filesToRefresh);
|
||||
addToMap(processed, command.getOutputPath(), outputItem);
|
||||
}
|
||||
catch (IOException e) {
|
||||
context.addMessage(
|
||||
CompilerMessageCategory.ERROR,
|
||||
CompilerBundle.message("error.copying", command.getFromPath(), command.getToPath(), e.getMessage()),
|
||||
command.getSourceFileUrl(), -1, -1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!filesToRefresh.isEmpty()) {
|
||||
CompilerUtil.refreshIOFiles(filesToRefresh);
|
||||
filesToRefresh.clear();
|
||||
}
|
||||
|
||||
for (Iterator<Map.Entry<String, Collection<OutputItem>>> it = processed.entrySet().iterator(); it.hasNext();) {
|
||||
Map.Entry<String, Collection<OutputItem>> entry = it.next();
|
||||
sink.add(entry.getKey(), entry.getValue(), VirtualFile.EMPTY_ARRAY);
|
||||
it.remove(); // to free memory
|
||||
}
|
||||
context.getProgressIndicator().popState();
|
||||
}
|
||||
|
||||
private boolean skipStandardResourceCompiler(final Module module) {
|
||||
for (ResourceCompilerExtension extension : myResourceCompilerExtensions) {
|
||||
if (extension.skipStandardResourceCompiler(module)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void addToMap(Map<String, Collection<OutputItem>> map, String outputDir, OutputItem item) {
|
||||
Collection<OutputItem> list = map.get(outputDir);
|
||||
if (list == null) {
|
||||
list = new ArrayList<OutputItem>();
|
||||
map.put(outputDir, list);
|
||||
}
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
private static class CopyCommand {
|
||||
private final String myOutputPath;
|
||||
private final String myFromPath;
|
||||
private final String myToPath;
|
||||
private final VirtualFile mySourceFile;
|
||||
|
||||
private CopyCommand(String outputPath, String fromPath, String toPath, VirtualFile sourceFile) {
|
||||
myOutputPath = outputPath;
|
||||
myFromPath = fromPath;
|
||||
myToPath = toPath;
|
||||
mySourceFile = sourceFile;
|
||||
}
|
||||
|
||||
public MyOutputItem copy(List<File> filesToRefresh) throws IOException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Copying " + myFromPath + " to " + myToPath);
|
||||
}
|
||||
final File targetFile = new File(myToPath);
|
||||
FileUtil.copyContent(new File(myFromPath), targetFile);
|
||||
filesToRefresh.add(targetFile);
|
||||
return new MyOutputItem(myToPath, mySourceFile);
|
||||
}
|
||||
|
||||
public String getOutputPath() {
|
||||
return myOutputPath;
|
||||
}
|
||||
|
||||
public String getFromPath() {
|
||||
return myFromPath;
|
||||
}
|
||||
|
||||
public String getToPath() {
|
||||
return myToPath;
|
||||
}
|
||||
|
||||
public String getSourceFileUrl() {
|
||||
// do not use mySourseFile.getUrl() directly as it requires read action
|
||||
return VirtualFileManager.constructUrl(mySourceFile.getFileSystem().getProtocol(), myFromPath);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyOutputItem implements OutputItem {
|
||||
private final String myTargetPath;
|
||||
private final VirtualFile myFile;
|
||||
|
||||
private MyOutputItem(String targetPath, VirtualFile sourceFile) {
|
||||
myTargetPath = targetPath;
|
||||
myFile = sourceFile;
|
||||
}
|
||||
|
||||
public String getOutputPath() {
|
||||
return myTargetPath;
|
||||
}
|
||||
|
||||
public VirtualFile getSourceFile() {
|
||||
return myFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package com.intellij.compiler.impl.resourceCompiler;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class ResourceCompilerExtension {
|
||||
public static final ExtensionPointName<ResourceCompilerExtension> EP_NAME =
|
||||
ExtensionPointName.create("com.intellij.compiler.resourceCompilerExtension");
|
||||
|
||||
public boolean skipStandardResourceCompiler(final @NotNull Module module) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-117
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.rmiCompiler;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.impl.javaCompiler.CompilerParsingThread;
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacOutputParser;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.rt.compiler.JavacResourcesReader;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Oct 10, 2005
|
||||
*/
|
||||
public class JavacOutputParserPool {
|
||||
protected final Project myProject;
|
||||
private final CompileContext myContext;
|
||||
private final Map<Sdk, OutputParser> myProjectToParserMap = new HashMap<Sdk, OutputParser>();
|
||||
|
||||
protected JavacOutputParserPool(Project project, final CompileContext context) {
|
||||
myProject = project;
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
public OutputParser getJavacOutputParser(Sdk jdk) throws IOException {
|
||||
OutputParser outputParser = myProjectToParserMap.get(jdk);
|
||||
if (outputParser == null) {
|
||||
outputParser = createJavacOutputParser(jdk);
|
||||
myProjectToParserMap.put(jdk, outputParser);
|
||||
}
|
||||
return outputParser;
|
||||
}
|
||||
|
||||
private OutputParser createJavacOutputParser(final Sdk jdk) throws IOException {
|
||||
final JavacOutputParser outputParser = new JavacOutputParser(myProject);
|
||||
// first, need to setup the output parser
|
||||
final String[] setupCmdLine = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
|
||||
public String[] compute() {
|
||||
return createParserSetupCommand(jdk);
|
||||
}
|
||||
});
|
||||
final Process setupProcess = Runtime.getRuntime().exec(setupCmdLine);
|
||||
|
||||
final CompilerParsingThread setupProcessParsingThread = new CompilerParsingThread(setupProcess, outputParser, true, true,myContext);
|
||||
final Future<?> parsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(setupProcessParsingThread);
|
||||
try {
|
||||
setupProcess.waitFor();
|
||||
}
|
||||
catch (InterruptedException ignored) {
|
||||
}
|
||||
finally {
|
||||
setupProcessParsingThread.setProcessTerminated(true);
|
||||
}
|
||||
try {
|
||||
parsingThreadFuture.get();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
}
|
||||
return outputParser;
|
||||
}
|
||||
|
||||
private static String[] createParserSetupCommand(final Sdk jdk) {
|
||||
|
||||
final VirtualFile homeDirectory = jdk.getHomeDirectory();
|
||||
if (homeDirectory == null) {
|
||||
throw new IllegalArgumentException(CompilerBundle.jdkHomeNotFoundMessage(jdk));
|
||||
}
|
||||
|
||||
final List<String> commandLine = new ArrayList<String>();
|
||||
commandLine.add(((JavaSdkType)jdk.getSdkType()).getVMExecutablePath(jdk));
|
||||
|
||||
CompilerUtil.addLocaleOptions(commandLine, false);
|
||||
|
||||
//noinspection HardCodedStringLiteral
|
||||
commandLine.add("-classpath");
|
||||
commandLine.add(((JavaSdkType)jdk.getSdkType()).getToolsPath(jdk) + File.pathSeparator + JavaSdkUtil.getIdeaRtJarPath());
|
||||
|
||||
commandLine.add(JavacResourcesReader.class.getName());
|
||||
|
||||
return ArrayUtil.toStringArray(commandLine);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,522 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.rmiCompiler;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.impl.javaCompiler.CompilerParsingThread;
|
||||
import com.intellij.compiler.impl.javaCompiler.FileObject;
|
||||
import com.intellij.compiler.make.Cache;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.compiler.make.DependencyCache;
|
||||
import com.intellij.compiler.make.MakeUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderEnumerator;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Chunk;
|
||||
import com.intellij.util.PathsList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Mar 29, 2004
|
||||
*/
|
||||
|
||||
public class RmicCompiler implements ClassPostProcessingCompiler{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.rmiCompiler.RmicCompiler");
|
||||
//private static final FileFilter CLASSES_AND_DIRECTORIES_FILTER = new FileFilter() {
|
||||
// public boolean accept(File pathname) {
|
||||
// return pathname.isDirectory() || pathname.getName().endsWith(".class");
|
||||
// }
|
||||
//};
|
||||
//private static final String REMOTE_INTERFACE_NAME = Remote.class.getName();
|
||||
|
||||
@NotNull
|
||||
public ProcessingItem[] getProcessingItems(final CompileContext context) {
|
||||
if (!RmicConfiguration.getOptions(context.getProject()).IS_EANABLED) {
|
||||
return ProcessingItem.EMPTY_ARRAY;
|
||||
}
|
||||
final Project project = context.getProject();
|
||||
final List<ProcessingItem> items = new ArrayList<ProcessingItem>();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
DependencyCache dependencyCache = ((CompileContextEx)context).getDependencyCache();
|
||||
try {
|
||||
final Cache cache = dependencyCache.getCache();
|
||||
final int[] allClassNames = cache.getAllClassNames();
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
final LocalFileSystem lfs = LocalFileSystem.getInstance();
|
||||
for (final int className : allClassNames) {
|
||||
final boolean isRemoteObject = cache.isRemote(className) && !MakeUtil.isInterface(cache.getFlags(className));
|
||||
if (!isRemoteObject && !dependencyCache.wasRemote(className)) {
|
||||
continue;
|
||||
}
|
||||
final String outputPath = cache.getPath(className);
|
||||
if (outputPath == null) {
|
||||
continue;
|
||||
}
|
||||
final VirtualFile outputClassFile = lfs.findFileByPath(outputPath.replace(File.separatorChar, '/'));
|
||||
if (outputClassFile == null) {
|
||||
continue;
|
||||
}
|
||||
final VirtualFile sourceFile = ((CompileContextEx)context).getSourceFileByOutputFile(outputClassFile);
|
||||
if (sourceFile == null) {
|
||||
continue;
|
||||
}
|
||||
final Module module = context.getModuleByFile(sourceFile);
|
||||
if (module == null) {
|
||||
continue;
|
||||
}
|
||||
final VirtualFile outputDir = fileIndex.isInTestSourceContent(sourceFile)
|
||||
? context.getModuleOutputDirectoryForTests(module)
|
||||
: context.getModuleOutputDirectory(module);
|
||||
if (outputDir == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!VfsUtil.isAncestor(outputDir, outputClassFile, true)) {
|
||||
LOG.error(outputClassFile.getPath() + " should be located under the output root " + outputDir.getPath());
|
||||
}
|
||||
|
||||
final ProcessingItem item = createProcessingItem(module, outputClassFile, outputDir,
|
||||
isRemoteObject, dependencyCache.resolve(className));
|
||||
items.add(item);
|
||||
}
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return items.toArray(new ProcessingItem[items.size()]);
|
||||
}
|
||||
|
||||
public static ProcessingItem createProcessingItem(final Module module,
|
||||
final VirtualFile outputClassFile,
|
||||
final VirtualFile outputDir,
|
||||
final boolean remoteObject, String qName) {
|
||||
final RmicProcessingItem item = new RmicProcessingItem(
|
||||
module, outputClassFile, new File(outputDir.getPath()), qName
|
||||
);
|
||||
item.setIsRemoteObject(remoteObject);
|
||||
return item;
|
||||
}
|
||||
|
||||
public ProcessingItem[] process(CompileContext context, ProcessingItem[] items) {
|
||||
final Project project = context.getProject();
|
||||
if (!RmicConfiguration.getOptions(project).IS_EANABLED) {
|
||||
return ProcessingItem.EMPTY_ARRAY;
|
||||
}
|
||||
final ProgressIndicator progressIndicator = context.getProgressIndicator();
|
||||
progressIndicator.pushState();
|
||||
try {
|
||||
progressIndicator.setText(CompilerBundle.message("progress.generating.rmi.stubs"));
|
||||
final Map<Pair<Module, File>, List<RmicProcessingItem>> sortedByModuleAndOutputPath = new HashMap<Pair<Module,File>, List<RmicProcessingItem>>();
|
||||
for (ProcessingItem item1 : items) {
|
||||
final RmicProcessingItem item = (RmicProcessingItem)item1;
|
||||
final Pair<Module, File> moduleOutputPair = Pair.create(item.getModule(), item.getOutputDir());
|
||||
List<RmicProcessingItem> dirItems = sortedByModuleAndOutputPath.get(moduleOutputPair);
|
||||
if (dirItems == null) {
|
||||
dirItems = new ArrayList<RmicProcessingItem>();
|
||||
sortedByModuleAndOutputPath.put(moduleOutputPair, dirItems);
|
||||
}
|
||||
dirItems.add(item);
|
||||
}
|
||||
final List<ProcessingItem> processed = new ArrayList<ProcessingItem>();
|
||||
|
||||
final JavacOutputParserPool parserPool = new JavacOutputParserPool(project, context);
|
||||
|
||||
for (final Pair<Module, File> pair : sortedByModuleAndOutputPath.keySet()) {
|
||||
if (progressIndicator.isCanceled()) {
|
||||
break;
|
||||
}
|
||||
final List<RmicProcessingItem> dirItems = sortedByModuleAndOutputPath.get(pair);
|
||||
try {
|
||||
// should delete all previously generated files for the remote class if there are any
|
||||
for (Iterator itemIterator = dirItems.iterator(); itemIterator.hasNext();) {
|
||||
final RmicProcessingItem item = (RmicProcessingItem)itemIterator.next();
|
||||
item.deleteGeneratedFiles();
|
||||
if (!item.isRemoteObject()) {
|
||||
itemIterator
|
||||
.remove(); // the object was remote and currently is not, so remove it from the list and do not generate stubs for it
|
||||
}
|
||||
}
|
||||
if (!dirItems.isEmpty()) {
|
||||
final RmicProcessingItem[] successfullyProcessed = invokeRmic(context, parserPool, pair.getFirst(), dirItems, pair.getSecond());
|
||||
ContainerUtil.addAll(processed, successfullyProcessed);
|
||||
}
|
||||
progressIndicator.setFraction(((double)processed.size()) / ((double)items.length));
|
||||
}
|
||||
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
|
||||
final ProcessingItem[] processedItems = processed.toArray(new ProcessingItem[processed.size()]);
|
||||
final List<File> filesToRefresh = new ArrayList<File>(processedItems.length * 3);
|
||||
for (ProcessingItem processedItem : processedItems) {
|
||||
RmicProcessingItem item = (RmicProcessingItem)processedItem;
|
||||
item.updateState();
|
||||
filesToRefresh.add(item.myStub);
|
||||
filesToRefresh.add(item.mySkel);
|
||||
filesToRefresh.add(item.myTie);
|
||||
}
|
||||
CompilerUtil.refreshIOFiles(filesToRefresh);
|
||||
return processedItems;
|
||||
}
|
||||
finally {
|
||||
progressIndicator.popState();
|
||||
}
|
||||
}
|
||||
|
||||
private static RmicProcessingItem[] invokeRmic(final CompileContext context,
|
||||
final JavacOutputParserPool parserPool, final Module module,
|
||||
final List<RmicProcessingItem> dirItems,
|
||||
final File outputDir
|
||||
) throws IOException{
|
||||
|
||||
final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
|
||||
|
||||
final Map<String, RmicProcessingItem> pathToItemMap = new HashMap<String, RmicProcessingItem>();
|
||||
final String[] cmdLine = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
|
||||
public String[] compute() {
|
||||
for (final RmicProcessingItem item : dirItems) {
|
||||
pathToItemMap.put(item.myStub.getPath().replace(File.separatorChar, '/'), item);
|
||||
pathToItemMap.put(item.mySkel.getPath().replace(File.separatorChar, '/'), item);
|
||||
pathToItemMap.put(item.myTie.getPath().replace(File.separatorChar, '/'), item);
|
||||
}
|
||||
return createStartupCommand(module, outputDir.getPath(), dirItems.toArray(new RmicProcessingItem[dirItems.size()]));
|
||||
}
|
||||
});
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int idx = 0; idx < cmdLine.length; idx++) {
|
||||
if (idx > 0) {
|
||||
buf.append(" ");
|
||||
}
|
||||
buf.append(cmdLine[idx]);
|
||||
}
|
||||
LOG.debug(buf.toString());
|
||||
}
|
||||
|
||||
// obtain parser before running the process because configuring parser may involve starting another process
|
||||
final OutputParser outputParser = parserPool.getJavacOutputParser(jdk);
|
||||
|
||||
final Process process = Runtime.getRuntime().exec(cmdLine);
|
||||
final Set<RmicProcessingItem> successfullyCompiledItems = new HashSet<RmicProcessingItem>();
|
||||
final CompilerParsingThread parsingThread = new CompilerParsingThread(process, outputParser, false, true,context) {
|
||||
protected void processCompiledClass(FileObject classFileToProcess) {
|
||||
String key = classFileToProcess.getFile().getPath().replace(File.separatorChar, '/');
|
||||
final RmicProcessingItem item = pathToItemMap.get(key);
|
||||
if (item != null) {
|
||||
successfullyCompiledItems.add(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final Future<?> parsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(parsingThread);
|
||||
try {
|
||||
process.waitFor();
|
||||
}
|
||||
catch (InterruptedException ignored) {
|
||||
}
|
||||
finally {
|
||||
parsingThread.setProcessTerminated(true);
|
||||
}
|
||||
|
||||
try {
|
||||
parsingThreadFuture.get();
|
||||
}
|
||||
catch (InterruptedException ignored) {
|
||||
}
|
||||
catch (ExecutionException ignored) {
|
||||
}
|
||||
return successfullyCompiledItems.toArray(new RmicProcessingItem[successfullyCompiledItems.size()]);
|
||||
}
|
||||
|
||||
private static String[] createStartupCommand(final Module module, final String outputPath, final RmicProcessingItem[] items) {
|
||||
final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
|
||||
|
||||
final VirtualFile homeDirectory = jdk.getHomeDirectory();
|
||||
if (homeDirectory == null) {
|
||||
throw new IllegalArgumentException(CompilerBundle.jdkHomeNotFoundMessage(jdk));
|
||||
}
|
||||
final String jdkPath = homeDirectory.getPath().replace('/', File.separatorChar);
|
||||
|
||||
@NonNls final String compilerPath = jdkPath + File.separator + "bin" + File.separator + "rmic";
|
||||
|
||||
@NonNls final List<String> commandLine = new ArrayList<String>();
|
||||
commandLine.add(compilerPath);
|
||||
|
||||
CompilerUtil.addLocaleOptions(commandLine, true);
|
||||
|
||||
commandLine.add("-verbose");
|
||||
|
||||
final Project project = module.getProject();
|
||||
ContainerUtil.addAll(commandLine, new RmicSettingsBuilder(RmicConfiguration.getOptions(project)).getOptions(new Chunk<Module>(module)));
|
||||
|
||||
commandLine.add("-classpath");
|
||||
|
||||
commandLine.add(getCompilationClasspath(module));
|
||||
|
||||
commandLine.add("-d");
|
||||
|
||||
commandLine.add(outputPath);
|
||||
|
||||
for (RmicProcessingItem item : items) {
|
||||
commandLine.add(item.getClassQName());
|
||||
}
|
||||
return ArrayUtil.toStringArray(commandLine);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return CompilerBundle.message("rmi.compiler.description");
|
||||
}
|
||||
|
||||
public boolean validateConfiguration(CompileScope scope) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
private void addAllRemoteFilesFromModuleOutput(final CompileContext context, final Module module, final List<ProcessingItem> items, final File outputDir, File fromDir, final JavaClass remoteInterface) {
|
||||
final File[] children = fromDir.listFiles(CLASSES_AND_DIRECTORIES_FILTER);
|
||||
for (int idx = 0; idx < children.length; idx++) {
|
||||
final File child = children[idx];
|
||||
if (child.isDirectory()) {
|
||||
addAllRemoteFilesFromModuleOutput(context, module, items, outputDir, child, remoteInterface);
|
||||
}
|
||||
else {
|
||||
final String path = child.getPath();
|
||||
try {
|
||||
final ClassParser classParser = new ClassParser(path);
|
||||
final JavaClass javaClass = classParser.parse();
|
||||
// important! Need this in order to resolve other classes in the project (e.g. superclasses)
|
||||
javaClass.setRepository(BcelUtils.getActiveRepository());
|
||||
if (isRmicCompilable(javaClass, remoteInterface)) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final VirtualFile outputClassFile = LocalFileSystem.getInstance().findFileByIoFile(child);
|
||||
if (outputClassFile != null) {
|
||||
items.add(new RmicProcessingItem(module, outputClassFile, outputDir, javaClass.getClassName()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "Cannot parse class file " + path + ": " + e.toString(), null, -1, -1);
|
||||
}
|
||||
catch (ClassFormatException e) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "Class format exception: " + e.getMessage() + " File: " + path, null, -1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
private boolean isRmicCompilable(final JavaClass javaClass, final JavaClass remoteInterface) {
|
||||
// stubs are needed for classes that _directly_ implement remote interfaces
|
||||
if (javaClass.isInterface() || isGenerated(javaClass)) {
|
||||
return false;
|
||||
}
|
||||
final JavaClass[] directlyImplementedInterfaces = javaClass.getInterfaces();
|
||||
if (directlyImplementedInterfaces != null) {
|
||||
for (int i = 0; i < directlyImplementedInterfaces.length; i++) {
|
||||
if (directlyImplementedInterfaces[i].instanceOf(remoteInterface)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
private boolean isGenerated(JavaClass javaClass) {
|
||||
final String sourceFileName = javaClass.getSourceFileName();
|
||||
return sourceFileName == null || !sourceFileName.endsWith(".java");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public ValidityState createValidityState(DataInput in) throws IOException {
|
||||
return new RemoteClassValidityState(in.readLong(), in.readLong(), in.readLong(), in.readLong());
|
||||
}
|
||||
|
||||
private static String getCompilationClasspath(Module module) {
|
||||
final OrderEnumerator enumerator = ModuleRootManager.getInstance(module).orderEntries().withoutSdk().compileOnly().recursively().exportedOnly();
|
||||
final PathsList pathsList = enumerator.getPathsList();
|
||||
return pathsList.getPathsString();
|
||||
}
|
||||
|
||||
private static final class RemoteClassValidityState implements ValidityState {
|
||||
private final long myRemoteClassTimestamp;
|
||||
private final long myStubTimestamp;
|
||||
private final long mySkelTimestamp;
|
||||
private final long myTieTimestamp;
|
||||
|
||||
private RemoteClassValidityState(long remoteClassTimestamp, long stubTimestamp, long skelTimestamp, long tieTimestamp) {
|
||||
myRemoteClassTimestamp = remoteClassTimestamp;
|
||||
myStubTimestamp = stubTimestamp;
|
||||
mySkelTimestamp = skelTimestamp;
|
||||
myTieTimestamp = tieTimestamp;
|
||||
}
|
||||
|
||||
public boolean equalsTo(ValidityState otherState) {
|
||||
if (otherState instanceof RemoteClassValidityState) {
|
||||
final RemoteClassValidityState state = (RemoteClassValidityState)otherState;
|
||||
return myRemoteClassTimestamp == state.myRemoteClassTimestamp &&
|
||||
myStubTimestamp == state.myStubTimestamp &&
|
||||
mySkelTimestamp == state.mySkelTimestamp &&
|
||||
myTieTimestamp == state.myTieTimestamp;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeLong(myRemoteClassTimestamp);
|
||||
out.writeLong(myStubTimestamp);
|
||||
out.writeLong(mySkelTimestamp);
|
||||
out.writeLong(myTieTimestamp);
|
||||
}
|
||||
}
|
||||
private static final class RmicProcessingItem implements ProcessingItem {
|
||||
private final Module myModule;
|
||||
private final VirtualFile myOutputClassFile;
|
||||
private final File myOutputDir;
|
||||
private final String myQName;
|
||||
private RemoteClassValidityState myState;
|
||||
private final File myStub;
|
||||
private final File mySkel;
|
||||
private final File myTie;
|
||||
private boolean myIsRemoteObject = false;
|
||||
|
||||
private RmicProcessingItem(Module module, final VirtualFile outputClassFile, File outputDir, String qName) {
|
||||
myModule = module;
|
||||
myOutputClassFile = outputClassFile;
|
||||
myOutputDir = outputDir;
|
||||
myQName = qName;
|
||||
final String relativePath;
|
||||
final String baseName;
|
||||
|
||||
final int index = qName.lastIndexOf('.');
|
||||
if (index >= 0) {
|
||||
relativePath = qName.substring(0, index + 1).replace('.', '/');
|
||||
baseName = qName.substring(index + 1);
|
||||
}
|
||||
else {
|
||||
relativePath = "";
|
||||
baseName = qName;
|
||||
}
|
||||
final String path = outputDir.getPath().replace(File.separatorChar, '/') + "/" + relativePath;
|
||||
//noinspection HardCodedStringLiteral
|
||||
myStub = new File(path + "/" + baseName + "_Stub.class");
|
||||
//noinspection HardCodedStringLiteral
|
||||
mySkel = new File(path + "/" + baseName + "_Skel.class");
|
||||
//noinspection HardCodedStringLiteral
|
||||
myTie = new File(path + "/_" + baseName + "_Tie.class");
|
||||
updateState();
|
||||
}
|
||||
|
||||
public boolean isRemoteObject() {
|
||||
return myIsRemoteObject;
|
||||
}
|
||||
|
||||
public void setIsRemoteObject(boolean isRemote) {
|
||||
myIsRemoteObject = isRemote;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getFile() {
|
||||
return myOutputClassFile;
|
||||
}
|
||||
|
||||
public ValidityState getValidityState() {
|
||||
return myState;
|
||||
}
|
||||
|
||||
public void updateState() {
|
||||
myState = new RemoteClassValidityState(
|
||||
myOutputClassFile.getTimeStamp(),
|
||||
getTimestamp(myStub),
|
||||
getTimestamp(mySkel),
|
||||
getTimestamp(myTie)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private static long getTimestamp(File file) {
|
||||
long l = file.lastModified();
|
||||
return l == 0 ? -1L : l;
|
||||
}
|
||||
|
||||
public void deleteGeneratedFiles() {
|
||||
if (FileUtil.delete(myStub)) {
|
||||
CompilerUtil.refreshIOFile(myStub);
|
||||
}
|
||||
if (FileUtil.delete(mySkel)) {
|
||||
CompilerUtil.refreshIOFile(mySkel);
|
||||
}
|
||||
if (FileUtil.delete(myTie)) {
|
||||
CompilerUtil.refreshIOFile(myTie);
|
||||
}
|
||||
}
|
||||
|
||||
public String getClassQName() {
|
||||
return myQName;
|
||||
}
|
||||
|
||||
public File getOutputDir() {
|
||||
return myOutputDir;
|
||||
}
|
||||
|
||||
public Module getModule() {
|
||||
return myModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.rmiCompiler;
|
||||
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacSettingsBuilder;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.jps.model.java.compiler.RmicCompilerOptions;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class RmicSettingsBuilder extends JavacSettingsBuilder {
|
||||
|
||||
public RmicSettingsBuilder(final RmicCompilerOptions options) {
|
||||
super(options);
|
||||
getOptions().DEPRECATION = false; // in this configuration deprecation is false by default
|
||||
}
|
||||
|
||||
@Override
|
||||
public RmicCompilerOptions getOptions() {
|
||||
return (RmicCompilerOptions)super.getOptions();
|
||||
}
|
||||
|
||||
public Collection<String> getOptions(Chunk<Module> chunk) {
|
||||
final Collection<String> options = super.getOptions(chunk);
|
||||
if(getOptions().GENERATE_IIOP_STUBS) {
|
||||
options.add("-iiop");
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
protected boolean acceptUserOption(String token) {
|
||||
if (!super.acceptUserOption(token)) {
|
||||
return false;
|
||||
}
|
||||
return !("-iiop".equals(token));
|
||||
}
|
||||
|
||||
protected boolean acceptEncoding() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.make;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Apr 7, 2004
|
||||
*/
|
||||
public interface AnnotationTargets {
|
||||
/** Class, interface or enum declaration */
|
||||
int TYPE = 0x1;
|
||||
|
||||
@NonNls String TYPE_STR = "TYPE";
|
||||
|
||||
/** Field declaration (includes enum constants) */
|
||||
int FIELD = 0x2;
|
||||
|
||||
@NonNls String FIELD_STR = "FIELD";
|
||||
|
||||
/** Method declaration */
|
||||
int METHOD = 0x4;
|
||||
|
||||
@NonNls String METHOD_STR = "METHOD";
|
||||
|
||||
/** Parameter declaration */
|
||||
int PARAMETER = 0x8;
|
||||
|
||||
@NonNls String PARAMETER_STR = "PARAMETER";
|
||||
|
||||
/** Constructor declaration */
|
||||
int CONSTRUCTOR = 0x10;
|
||||
|
||||
@NonNls String CONSTRUCTOR_STR = "CONSTRUCTOR";
|
||||
|
||||
/** Local variable declaration */
|
||||
int LOCAL_VARIABLE = 0x20;
|
||||
|
||||
@NonNls String LOCAL_VARIABLE_STR = "LOCAL_VARIABLE";
|
||||
|
||||
/** Annotation type declaration */
|
||||
int ANNOTATION_TYPE = 0x40;
|
||||
|
||||
@NonNls String ANNOTATION_TYPE_STR = "ANNOTATION_TYPE";
|
||||
|
||||
/** Package declaration */
|
||||
int PACKAGE = 0x80;
|
||||
|
||||
@NonNls String PACKAGE_STR = "PACKAGE";
|
||||
|
||||
int ALL = TYPE | FIELD | METHOD | PARAMETER | CONSTRUCTOR | LOCAL_VARIABLE | ANNOTATION_TYPE | PACKAGE;
|
||||
}
|
||||
@@ -1,511 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.make;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.containers.SLRUCache;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.EnumeratorIntegerDescriptor;
|
||||
import com.intellij.util.io.PersistentHashMap;
|
||||
import gnu.trove.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 1, 2008
|
||||
*/
|
||||
public class BackwardDependenciesStorage implements Flushable, Disposable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CompilerDependencyStorage");
|
||||
protected final PersistentHashMap<Integer, DependenciesSet> myMap;
|
||||
protected final SLRUCache<Integer, ReferencerSetHolder> myCache;
|
||||
private Integer myKeyToRemove;
|
||||
private static final int FIELD = 1;
|
||||
private static final int METHOD = 2;
|
||||
private static final int CLASS = 3;
|
||||
|
||||
public BackwardDependenciesStorage(File file, final int cacheSize) throws IOException {
|
||||
myMap = new PersistentHashMap<Integer, DependenciesSet>(file, EnumeratorIntegerDescriptor.INSTANCE, new MyDataExternalizer());
|
||||
|
||||
myCache = new SLRUCache<Integer, ReferencerSetHolder>(cacheSize * 2, cacheSize) {
|
||||
@NotNull
|
||||
public ReferencerSetHolder createValue(Integer key) {
|
||||
return new ReferencerSetHolder(key);
|
||||
}
|
||||
|
||||
protected void onDropFromCache(Integer key, final ReferencerSetHolder holder) {
|
||||
if (key.equals(myKeyToRemove) || !holder.isDirty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (holder.isDataLoaded() || !myMap.containsMapping(key)) {
|
||||
myMap.put(key, new DependenciesSet(holder.getData()));
|
||||
}
|
||||
else {
|
||||
myMap.appendData(key, new PersistentHashMap.ValueDataAppender() {
|
||||
public void append(final DataOutput out) throws IOException {
|
||||
final Ref<IOException> exception = new Ref<IOException>(null);
|
||||
// process removed
|
||||
holder.myRemoveRequested.forEach(new TIntProcedure() {
|
||||
public boolean execute(int qName) {
|
||||
try {
|
||||
out.writeInt(-qName);
|
||||
return true;
|
||||
}
|
||||
catch (IOException e) {
|
||||
exception.set(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
final IOException _ex = exception.get();
|
||||
if (_ex != null) {
|
||||
throw _ex;
|
||||
}
|
||||
// process added members
|
||||
for (ReferencerItem item : holder.myAdded) {
|
||||
item.save(out);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public synchronized void remove(Integer qName) throws IOException {
|
||||
myKeyToRemove = qName;
|
||||
try {
|
||||
myCache.remove(qName);
|
||||
}
|
||||
finally {
|
||||
myKeyToRemove = null;
|
||||
}
|
||||
myMap.remove(qName);
|
||||
}
|
||||
|
||||
public synchronized void removeReferencer(Integer qName, int referencerQName) throws IOException {
|
||||
if (myMap.containsMapping(qName)) {
|
||||
final ReferencerSetHolder set = myCache.get(qName);
|
||||
set.removeReferencer(referencerQName);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addClassReferencer(Integer qName, int referencerQName) {
|
||||
myCache.get(qName).addReferencer(new ReferencerItem(referencerQName));
|
||||
}
|
||||
|
||||
public synchronized void addFieldReferencer(Integer qName, int referencerQName, int fieldName) {
|
||||
myCache.get(qName).addReferencer(new FieldReferencerItem(referencerQName, fieldName));
|
||||
}
|
||||
|
||||
public synchronized void addMethodReferencer(Integer qName, int referencerQName, int methodName, int descriptor) {
|
||||
myCache.get(qName).addReferencer(new MethodReferencerItem(referencerQName, methodName, descriptor));
|
||||
}
|
||||
|
||||
public synchronized Dependency[] getDependencies(Integer classQName) throws CacheCorruptedException {
|
||||
try {
|
||||
if (!myMap.containsMapping(classQName)) {
|
||||
return Dependency.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
return convertToDependencies(classQName.intValue(), myCache.get(classQName).getData());
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Dependency[] convertToDependencies(int classToSkip, Set<ReferencerItem> data) {
|
||||
final TIntObjectHashMap<Dependency> dependencies = new TIntObjectHashMap<Dependency>();
|
||||
for (ReferencerItem item : data) {
|
||||
if (item.qName == classToSkip) {
|
||||
continue; // skip self-dependencies
|
||||
}
|
||||
final Dependency dependency = addDependency(dependencies, item.qName);
|
||||
if (item instanceof FieldReferencerItem) {
|
||||
dependency.addField(((FieldReferencerItem)item).name);
|
||||
}
|
||||
else if (item instanceof MethodReferencerItem) {
|
||||
final MethodReferencerItem methodItem = (MethodReferencerItem)item;
|
||||
dependency.addMethod(methodItem.name, methodItem.descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
final Dependency[] dependencyArray = new Dependency[dependencies.size()];
|
||||
dependencies.forEachValue(new TObjectProcedure<Dependency>() {
|
||||
private int index = 0;
|
||||
public boolean execute(Dependency object) {
|
||||
dependencyArray[index++] = object;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return dependencyArray;
|
||||
}
|
||||
|
||||
private static Dependency addDependency(TIntObjectHashMap<Dependency> container, int classQName) {
|
||||
Dependency dependency = container.get(classQName);
|
||||
if (dependency == null) {
|
||||
dependency = new Dependency(classQName);
|
||||
container.put(classQName, dependency);
|
||||
}
|
||||
return dependency;
|
||||
}
|
||||
|
||||
public synchronized void flush() throws IOException {
|
||||
myCache.clear();
|
||||
myMap.force();
|
||||
}
|
||||
|
||||
private void flush(Integer key) {
|
||||
myCache.remove(key); // makes changes into PersistentHashMap
|
||||
myMap.force(); // flushes internal caches (which consume memory) and writes unsaved data to disk
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
try {
|
||||
flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
try {
|
||||
myMap.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReferencerItem {
|
||||
public final int qName;
|
||||
|
||||
private ReferencerItem(int qName) {
|
||||
this.qName = qName;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ReferencerItem that = (ReferencerItem)o;
|
||||
|
||||
if (qName != that.qName) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return qName;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeInt(qName);
|
||||
out.writeByte(CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MethodReferencerItem extends ReferencerItem {
|
||||
public final int name;
|
||||
public final int descriptor;
|
||||
|
||||
MethodReferencerItem(int qName, int name, int descriptor) {
|
||||
super(qName);
|
||||
this.name = name;
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
MethodReferencerItem that = (MethodReferencerItem)o;
|
||||
|
||||
if (descriptor != that.descriptor) return false;
|
||||
if (name != that.name) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + name;
|
||||
result = 31 * result + descriptor;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeInt(qName);
|
||||
out.writeByte(METHOD);
|
||||
out.writeInt(name);
|
||||
out.writeInt(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FieldReferencerItem extends ReferencerItem {
|
||||
public final int name;
|
||||
|
||||
FieldReferencerItem(int qName, int name) {
|
||||
super(qName);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
FieldReferencerItem that = (FieldReferencerItem)o;
|
||||
|
||||
if (name != that.name) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + name;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeInt(qName);
|
||||
out.writeByte(FIELD);
|
||||
out.writeInt(name);
|
||||
}
|
||||
}
|
||||
|
||||
private class ReferencerSetHolder {
|
||||
private final Integer myKey;
|
||||
private TIntHashSet myRemoveRequested = new TIntHashSet();
|
||||
private Set<ReferencerItem> myAdded = new THashSet<ReferencerItem>();
|
||||
|
||||
private Set<ReferencerItem> myData = null;
|
||||
private boolean myIsDirty = false;
|
||||
|
||||
public ReferencerSetHolder(Integer key) {
|
||||
myKey = key;
|
||||
}
|
||||
|
||||
public void addReferencer(ReferencerItem referencer) {
|
||||
if (myData != null) {
|
||||
myIsDirty |= myData.add(referencer);
|
||||
return;
|
||||
}
|
||||
myAdded.add(referencer);
|
||||
}
|
||||
|
||||
public void removeReferencer(int qName) {
|
||||
if (myData != null) {
|
||||
myIsDirty |= removeAllReferencerItems(myData, qName);
|
||||
return;
|
||||
}
|
||||
myRemoveRequested.add(qName);
|
||||
removeAllReferencerItems(myAdded, qName);
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return myData != null? myIsDirty : myRemoveRequested.size() > 0 || myAdded.size() > 0;
|
||||
}
|
||||
|
||||
public boolean isDataLoaded() {
|
||||
return myData != null;
|
||||
}
|
||||
|
||||
public Set<ReferencerItem> getData() throws IOException {
|
||||
if (myData == null) {
|
||||
final DependenciesSet ds = myMap.get(myKey);
|
||||
Set<ReferencerItem> set = null;
|
||||
if (ds != null) {
|
||||
set = ds.set;
|
||||
myIsDirty |= ds.needsCompacting;
|
||||
}
|
||||
if (set == null) {
|
||||
set = new THashSet<ReferencerItem>();
|
||||
}
|
||||
myIsDirty |= removeAllReferencerItems(set, myRemoveRequested);
|
||||
myIsDirty |= set.addAll(myAdded);
|
||||
myData = set;
|
||||
myAdded = null;
|
||||
myRemoveRequested = null;
|
||||
}
|
||||
return Collections.unmodifiableSet(myData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MyDataExternalizer implements DataExternalizer<DependenciesSet> {
|
||||
public void save(@NotNull DataOutput out, DependenciesSet ds) throws IOException {
|
||||
final TIntHashSet classes = new TIntHashSet();
|
||||
final Map<Dependency.FieldRef, TIntHashSet> fieldsMap = new HashMap<Dependency.FieldRef, TIntHashSet>();
|
||||
final Map<Dependency.MethodRef, TIntHashSet> methodsMap = new HashMap<Dependency.MethodRef, TIntHashSet>();
|
||||
for (ReferencerItem item : ds.set) {
|
||||
if (item instanceof FieldReferencerItem) {
|
||||
final Dependency.FieldRef ref = new Dependency.FieldRef(((FieldReferencerItem)item).name);
|
||||
TIntHashSet referencers = fieldsMap.get(ref);
|
||||
if (referencers == null) {
|
||||
referencers = new TIntHashSet();
|
||||
fieldsMap.put(ref, referencers);
|
||||
}
|
||||
referencers.add(item.qName);
|
||||
}
|
||||
else if (item instanceof MethodReferencerItem) {
|
||||
final MethodReferencerItem _item = (MethodReferencerItem)item;
|
||||
final Dependency.MethodRef ref = new Dependency.MethodRef(_item.name, _item.descriptor);
|
||||
TIntHashSet referencers = methodsMap.get(ref);
|
||||
if (referencers == null) {
|
||||
referencers = new TIntHashSet();
|
||||
methodsMap.put(ref, referencers);
|
||||
}
|
||||
referencers.add(item.qName);
|
||||
}
|
||||
else {
|
||||
classes.add(item.qName);
|
||||
}
|
||||
}
|
||||
|
||||
out.writeInt(classes.size());
|
||||
for (TIntIterator it = classes.iterator(); it.hasNext();) {
|
||||
out.writeInt(it.next());
|
||||
}
|
||||
|
||||
out.writeInt(fieldsMap.size());
|
||||
for (Map.Entry<Dependency.FieldRef, TIntHashSet> entry : fieldsMap.entrySet()) {
|
||||
out.writeInt(entry.getKey().name);
|
||||
final TIntHashSet referencers = entry.getValue();
|
||||
out.writeInt(referencers.size());
|
||||
for (TIntIterator rit = referencers.iterator(); rit.hasNext();) {
|
||||
out.writeInt(rit.next());
|
||||
}
|
||||
}
|
||||
|
||||
out.writeInt(methodsMap.size());
|
||||
for (Map.Entry<Dependency.MethodRef, TIntHashSet> entry : methodsMap.entrySet()) {
|
||||
final Dependency.MethodRef ref = entry.getKey();
|
||||
out.writeInt(ref.name);
|
||||
out.writeInt(ref.descriptor);
|
||||
final TIntHashSet referencers = entry.getValue();
|
||||
out.writeInt(referencers.size());
|
||||
for (TIntIterator rit = referencers.iterator(); rit.hasNext();) {
|
||||
out.writeInt(rit.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DependenciesSet read(@NotNull DataInput in) throws IOException {
|
||||
final Set<ReferencerItem> set = new THashSet<ReferencerItem>();
|
||||
|
||||
int classesCount = in.readInt();
|
||||
while (classesCount-- > 0) {
|
||||
set.add(new ReferencerItem(in.readInt()));
|
||||
}
|
||||
|
||||
int fieldsCount = in.readInt();
|
||||
while (fieldsCount-- > 0) {
|
||||
final int fieldName = in.readInt();
|
||||
int referencersCount = in.readInt();
|
||||
while (referencersCount-- > 0) {
|
||||
set.add(new FieldReferencerItem(in.readInt(), fieldName));
|
||||
}
|
||||
}
|
||||
|
||||
int methodsCount = in.readInt();
|
||||
while (methodsCount-- > 0) {
|
||||
final int methodName = in.readInt();
|
||||
final int methodDescriptor = in.readInt();
|
||||
int referensersCount = in.readInt();
|
||||
while (referensersCount-- > 0) {
|
||||
set.add(new MethodReferencerItem(in.readInt(), methodName, methodDescriptor));
|
||||
}
|
||||
}
|
||||
boolean needsCompacting = false;
|
||||
// manage appends if exist qName, kind, {field | method}
|
||||
final DataInputStream _in = (DataInputStream)in;
|
||||
while (_in.available() > 0) {
|
||||
needsCompacting = true;
|
||||
final int qName = _in.readInt();
|
||||
if (qName < 0) {
|
||||
removeAllReferencerItems(set, -qName);
|
||||
}
|
||||
else {
|
||||
final byte kind = _in.readByte();
|
||||
if (kind == FIELD) {
|
||||
set.add(new FieldReferencerItem(qName, _in.readInt()));
|
||||
}
|
||||
else if (kind == METHOD) {
|
||||
final int name = _in.readInt();
|
||||
final int descriptor = _in.readInt();
|
||||
set.add(new MethodReferencerItem(qName, name, descriptor));
|
||||
}
|
||||
else if (kind == CLASS){
|
||||
set.add(new ReferencerItem(qName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new DependenciesSet(set, needsCompacting);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DependenciesSet {
|
||||
public final Set<ReferencerItem> set;
|
||||
public final boolean needsCompacting;
|
||||
|
||||
public DependenciesSet(Set<ReferencerItem> set, boolean needsCompacting) {
|
||||
this.set = set;
|
||||
this.needsCompacting = needsCompacting;
|
||||
}
|
||||
|
||||
public DependenciesSet(Set<ReferencerItem> set) {
|
||||
this(set, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean removeAllReferencerItems(final Set<ReferencerItem> from, final TIntHashSet qNames) {
|
||||
boolean removed = false;
|
||||
for (Iterator<ReferencerItem> it = from.iterator(); it.hasNext();) {
|
||||
final ReferencerItem item = it.next();
|
||||
if (qNames.contains(item.qName)) {
|
||||
it.remove();
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
private static boolean removeAllReferencerItems(final Set<ReferencerItem> from, final int qNames) {
|
||||
boolean removed = false;
|
||||
for (Iterator<ReferencerItem> it = from.iterator(); it.hasNext();) {
|
||||
final ReferencerItem item = it.next();
|
||||
if (qNames == item.qName) {
|
||||
it.remove();
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.make;
|
||||
|
||||
import com.intellij.compiler.classParsing.SignatureParser;
|
||||
import com.intellij.compiler.classParsing.SignatureParsingException;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Mar 10, 2004
|
||||
*/
|
||||
public class BoundsParser extends SignatureParser{
|
||||
final List<String> myInterfaceBounds = new ArrayList<String>();
|
||||
private int myParsingBound;
|
||||
|
||||
public void parseClassBound(CharacterIterator it, StringBuilder buf) throws SignatureParsingException {
|
||||
myParsingBound += 1;
|
||||
try {
|
||||
super.parseClassBound(it, buf);
|
||||
}
|
||||
finally {
|
||||
myParsingBound -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void parseInterfaceBound(CharacterIterator it, StringBuilder buf) throws SignatureParsingException {
|
||||
myParsingBound += 1;
|
||||
try {
|
||||
super.parseInterfaceBound(it, buf);
|
||||
}
|
||||
finally {
|
||||
myParsingBound -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void parseClassTypeSignature(CharacterIterator it, StringBuilder buf) throws SignatureParsingException {
|
||||
if (myParsingBound > 0) {
|
||||
final int start = buf.length();
|
||||
|
||||
super.parseClassTypeSignature(it, buf);
|
||||
|
||||
final String qName = convertToQalifiedName(buf.substring(start + 1, buf.length() - 1));
|
||||
myInterfaceBounds.add(qName);
|
||||
}
|
||||
else {
|
||||
super.parseClassTypeSignature(it, buf);
|
||||
}
|
||||
}
|
||||
|
||||
private static String convertToQalifiedName(String ifaceSignature) {
|
||||
ifaceSignature = ifaceSignature.replaceAll("<.*>", "");
|
||||
return ifaceSignature.replace('/', '.');
|
||||
}
|
||||
|
||||
public String[] getBounds() {
|
||||
return ArrayUtil.toStringArray(myInterfaceBounds);
|
||||
}
|
||||
|
||||
public static String[] getBounds(String classSignature) throws SignatureParsingException {
|
||||
final BoundsParser parser = new BoundsParser();
|
||||
parser.parseClassSignature(new StringCharacterIterator(classSignature), new StringBuilder());
|
||||
return parser.getBounds();
|
||||
}
|
||||
}
|
||||
@@ -1,521 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.make;
|
||||
|
||||
import com.intellij.compiler.SymbolTable;
|
||||
import com.intellij.compiler.classParsing.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.cls.ClsFormatException;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.EnumeratorIntegerDescriptor;
|
||||
import com.intellij.util.io.PersistentHashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Aug 8, 2003
|
||||
* Time: 7:03:56 PM
|
||||
*/
|
||||
public class Cache {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.Cache");
|
||||
public static final int UNKNOWN = -1;
|
||||
|
||||
private final PersistentHashMap<Integer, ClassInfo> myQNameToClassInfoMap;
|
||||
|
||||
private final BackwardDependenciesStorage myDependencies;
|
||||
private final CompilerDependencyStorage<Integer> myQNameToReferencedClassesMap;
|
||||
private final CompilerDependencyStorage<Integer> myQNameToSubclassesMap;
|
||||
private final PersistentHashMap<Integer, Boolean> myRemoteQNames;
|
||||
private final String myStorePath;
|
||||
|
||||
public Cache(@NonNls final String storePath, final int cacheSize) throws IOException {
|
||||
myStorePath = storePath;
|
||||
new File(storePath).mkdirs();
|
||||
myQNameToClassInfoMap = new CachedPersistentHashMap<Integer, ClassInfo>(getOrCreateFile("classes"), EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<ClassInfo>() {
|
||||
public void save(@NotNull DataOutput out, ClassInfo value) throws IOException {
|
||||
value.save(out);
|
||||
}
|
||||
public ClassInfo read(@NotNull DataInput in) throws IOException {
|
||||
return new ClassInfo(in);
|
||||
}
|
||||
}, cacheSize * 2) {
|
||||
protected boolean isValueDirty(ClassInfo classInfo) {
|
||||
return classInfo.isDirty();
|
||||
}
|
||||
};
|
||||
|
||||
myDependencies = new BackwardDependenciesStorage(getOrCreateFile("bdeps"), cacheSize);
|
||||
myQNameToReferencedClassesMap = new CompilerDependencyStorage<Integer>(getOrCreateFile("fdeps"), EnumeratorIntegerDescriptor.INSTANCE, cacheSize);
|
||||
myQNameToSubclassesMap = new CompilerDependencyStorage<Integer>(getOrCreateFile("subclasses"), EnumeratorIntegerDescriptor.INSTANCE, cacheSize);
|
||||
|
||||
myRemoteQNames = new PersistentHashMap<Integer, Boolean>(getOrCreateFile("remote"), EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<Boolean>() {
|
||||
public void save(@NotNull DataOutput out, Boolean value) throws IOException {
|
||||
out.writeBoolean(value.booleanValue());
|
||||
}
|
||||
|
||||
public Boolean read(@NotNull DataInput in) throws IOException {
|
||||
return in.readBoolean();
|
||||
}
|
||||
}, cacheSize);
|
||||
}
|
||||
|
||||
private File getOrCreateFile(final String fileName) throws IOException {
|
||||
final File file = new File(myStorePath, fileName);
|
||||
FileUtil.createIfDoesntExist(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
public void dispose() throws CacheCorruptedException {
|
||||
CacheCorruptedException ex = null;
|
||||
try {
|
||||
myQNameToClassInfoMap.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
ex = new CacheCorruptedException(e);
|
||||
}
|
||||
try {
|
||||
myRemoteQNames.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
if (ex != null) {
|
||||
ex = new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
myQNameToReferencedClassesMap.dispose();
|
||||
myDependencies.dispose();
|
||||
myQNameToSubclassesMap.dispose();
|
||||
|
||||
if (ex != null) {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int[] getAllClassNames() throws CacheCorruptedException {
|
||||
try {
|
||||
final Collection<Integer> allKeys = myQNameToClassInfoMap.getAllKeysWithExistingMapping();
|
||||
final int[] array = ArrayUtil.newIntArray(allKeys.size());
|
||||
int idx = 0;
|
||||
for (Integer id : allKeys) {
|
||||
array[idx++] = id.intValue();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int importClassInfo(ClassFileReader reader, SymbolTable symbolTable) throws ClsFormatException, CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = new ClassInfo(reader, symbolTable);
|
||||
myQNameToClassInfoMap.put(classInfo.getQualifiedName(), classInfo);
|
||||
return classInfo.getQualifiedName();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void importClassInfo(Cache fromCache, final int qName) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = fromCache.myQNameToClassInfoMap.get(qName);
|
||||
if (classInfo != null) {
|
||||
final ClassInfo clone = classInfo.clone();
|
||||
clone.clearReferences();
|
||||
myQNameToClassInfoMap.put(qName, clone);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeVisibleAnnotations(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? classInfo.getRuntimeVisibleAnnotations() : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeInvisibleAnnotations(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? classInfo.getRuntimeInvisibleAnnotations() : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getSubclasses(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
return myQNameToSubclassesMap.getValues(classId);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addSubclass(int classId, int subclassQName) throws CacheCorruptedException {
|
||||
try {
|
||||
myQNameToSubclassesMap.addValue(classId, subclassQName);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSubclass(int classId, int subclassQName) throws CacheCorruptedException {
|
||||
try {
|
||||
myQNameToSubclassesMap.removeValue(classId, subclassQName);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getReferencedClasses(int qName) throws CacheCorruptedException {
|
||||
try {
|
||||
return myQNameToReferencedClassesMap.getValues(qName);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearReferencedClasses(int qName) throws CacheCorruptedException {
|
||||
try {
|
||||
myQNameToReferencedClassesMap.remove(qName);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<ReferenceInfo> getReferences(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? Arrays.asList(classInfo.getReferences()) : Collections.<ReferenceInfo>emptyList();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getSourceFileName(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? classInfo.getSourceFileName() : "";
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRemote(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
return myRemoteQNames.containsMapping(classId);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRemote(int classId, boolean remote) throws CacheCorruptedException {
|
||||
try {
|
||||
if (remote) {
|
||||
myRemoteQNames.put(classId, Boolean.TRUE);
|
||||
}
|
||||
else {
|
||||
myRemoteQNames.remove(classId);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSuperQualifiedName(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? classInfo.getSuperQualifiedName() : UNKNOWN;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getPath(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? classInfo.getPath() : "";
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPath(int classId, String path) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
if (classInfo != null) {
|
||||
classInfo.setPath(path);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int getGenericSignature(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? classInfo.getGenericSignature() : UNKNOWN;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsClass(int qName) throws CacheCorruptedException {
|
||||
try {
|
||||
return myQNameToClassInfoMap.containsMapping(qName);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getSuperInterfaces(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? classInfo.getSuperInterfaces() : ArrayUtil.EMPTY_INT_ARRAY;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int getFlags(int classId) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
|
||||
return classInfo != null? classInfo.getFlags() : UNKNOWN;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public FieldInfo[] getFields(int qName) throws CacheCorruptedException{
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(qName);
|
||||
return classInfo != null? classInfo.getFields() : FieldInfo.EMPTY_ARRAY;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FieldInfo findField(final int classDeclarationId, final int name, final int descriptor) throws CacheCorruptedException{
|
||||
try {
|
||||
for (FieldInfo fieldInfo : getFields(classDeclarationId)) {
|
||||
if (fieldInfo.getName() == name && fieldInfo.getDescriptor() == descriptor) {
|
||||
return fieldInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FieldInfo findFieldByName(final int classDeclarationId, final int name) throws CacheCorruptedException{
|
||||
try {
|
||||
for (FieldInfo fieldInfo : getFields(classDeclarationId)) {
|
||||
if (fieldInfo.getName() == name) {
|
||||
return fieldInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public MethodInfo[] getMethods(int classQName) throws CacheCorruptedException{
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(classQName);
|
||||
return classInfo != null? classInfo.getMethods() : MethodInfo.EMPTY_ARRAY;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MethodInfo findMethod(final int classQName, final int name, final int descriptor) throws CacheCorruptedException{
|
||||
try {
|
||||
for (MethodInfo methodInfo : getMethods(classQName)) {
|
||||
if (methodInfo.getName() == name && methodInfo.getDescriptor() == descriptor) {
|
||||
return methodInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<MethodInfo> findMethodsByName(final int classDeclarationId, final int name) throws CacheCorruptedException{
|
||||
try {
|
||||
final List<MethodInfo> methods = new ArrayList<MethodInfo>();
|
||||
for (MethodInfo methodInfo : getMethods(classDeclarationId)) {
|
||||
if (methodInfo.getName() == name) {
|
||||
methods.add(methodInfo);
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MethodInfo findMethodsBySignature(final int classDeclarationId, final String signature, SymbolTable symbolTable) throws CacheCorruptedException{
|
||||
try {
|
||||
for (MethodInfo methodInfo : getMethods(classDeclarationId)) {
|
||||
if (signature.equals(CacheUtils.getMethodSignature(symbolTable.getSymbol(methodInfo.getName()), symbolTable.getSymbol(methodInfo.getDescriptor())))) {
|
||||
return methodInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addClassReferencer(int qName, int referencerQName) throws CacheCorruptedException {
|
||||
try {
|
||||
if (qName == referencerQName) {
|
||||
return; // do not log self-dependencies
|
||||
}
|
||||
if (myQNameToClassInfoMap.containsMapping(qName)) {
|
||||
myDependencies.addClassReferencer(qName, referencerQName);
|
||||
myQNameToReferencedClassesMap.addValue(referencerQName, qName);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeClassReferencer(int qName, int referencerQName) throws CacheCorruptedException {
|
||||
try {
|
||||
myDependencies.removeReferencer(qName, referencerQName);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addFieldReferencer(int qName, int fieldName, int referencerQName) throws CacheCorruptedException {
|
||||
try {
|
||||
if (qName != referencerQName && myQNameToClassInfoMap.containsMapping(qName)) {
|
||||
myDependencies.addFieldReferencer(qName, referencerQName, fieldName);
|
||||
myQNameToReferencedClassesMap.addValue(referencerQName, qName);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addMethodReferencer(int qName, int methodName, int methodDescriptor, int referencerQName) throws CacheCorruptedException {
|
||||
try {
|
||||
if (qName != referencerQName && myQNameToClassInfoMap.containsMapping(qName)) {
|
||||
myDependencies.addMethodReferencer(qName, referencerQName, methodName, methodDescriptor);
|
||||
myQNameToReferencedClassesMap.addValue(referencerQName, qName);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** @NotNull */
|
||||
public Dependency[] getBackDependencies(final int classQName) throws CacheCorruptedException{
|
||||
return myDependencies.getDependencies(classQName);
|
||||
}
|
||||
|
||||
public void wipe() {
|
||||
try {
|
||||
dispose();
|
||||
}
|
||||
catch (CacheCorruptedException ignored) {
|
||||
}
|
||||
finally {
|
||||
final File[] files = new File(myStorePath).listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!file.isDirectory()) {
|
||||
FileUtil.delete(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeClass(final int qName) throws CacheCorruptedException {
|
||||
try {
|
||||
final ClassInfo classInfo = myQNameToClassInfoMap.get(qName);
|
||||
if (classInfo == null) {
|
||||
return;
|
||||
}
|
||||
myDependencies.remove(qName);
|
||||
myQNameToClassInfoMap.remove(qName);
|
||||
myQNameToReferencedClassesMap.remove(qName);
|
||||
myQNameToSubclassesMap.remove(qName);
|
||||
myRemoteQNames.remove(qName);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new CacheCorruptedException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author: Eugene Zhuravlev
|
||||
* Date: Jul 10, 2003
|
||||
* Time: 4:51:25 PM
|
||||
*/
|
||||
package com.intellij.compiler.make;
|
||||
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
|
||||
public class CacheCorruptedException extends Exception{
|
||||
private static final String DEFAULT_MESSAGE = CompilerBundle.message("error.dependency.info.on.disk.corrupted");
|
||||
public CacheCorruptedException(String message) {
|
||||
super((message == null || message.length() == 0)? DEFAULT_MESSAGE : message);
|
||||
}
|
||||
|
||||
public CacheCorruptedException(Throwable cause) {
|
||||
super(DEFAULT_MESSAGE, cause);
|
||||
}
|
||||
|
||||
public CacheCorruptedException(String message, Throwable cause) {
|
||||
super((message == null || message.length() == 0)? DEFAULT_MESSAGE : message, cause);
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return super.getMessage();
|
||||
}
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.make;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerManagerImpl;
|
||||
import com.intellij.compiler.SymbolTable;
|
||||
import com.intellij.compiler.classParsing.MethodInfo;
|
||||
import com.intellij.compiler.impl.ExitException;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.compiler.CompilerMessage;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Aug 18, 2003
|
||||
* Time: 6:32:32 PM
|
||||
*/
|
||||
public class CacheUtils {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CacheUtils");
|
||||
|
||||
public static String[] getParameterSignatures(MethodInfo methodDeclarationId, SymbolTable symbolTable) throws CacheCorruptedException {
|
||||
String descriptor = symbolTable.getSymbol(methodDeclarationId.getDescriptor());
|
||||
int endIndex = descriptor.indexOf(')');
|
||||
if (endIndex <= 0) {
|
||||
LOG.error("Corrupted method descriptor: " + descriptor);
|
||||
}
|
||||
return parseSignature(descriptor.substring(1, endIndex));
|
||||
}
|
||||
|
||||
private static String[] parseSignature(String signature) {
|
||||
final ArrayList<String> list = new ArrayList<String>();
|
||||
String paramSignature = parseParameterSignature(signature);
|
||||
while (paramSignature != null && !"".equals(paramSignature)) {
|
||||
list.add(paramSignature);
|
||||
signature = signature.substring(paramSignature.length());
|
||||
paramSignature = parseParameterSignature(signature);
|
||||
}
|
||||
return ArrayUtil.toStringArray(list);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private static @Nullable String parseParameterSignature(String signature) {
|
||||
if (StringUtil.startsWithChar(signature, 'B')) {
|
||||
return "B";
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, 'C')) {
|
||||
return "C";
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, 'D')) {
|
||||
return "D";
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, 'F')) {
|
||||
return "F";
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, 'I')) {
|
||||
return "I";
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, 'J')) {
|
||||
return "J";
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, 'S')) {
|
||||
return "S";
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, 'Z')) {
|
||||
return "Z";
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, 'L')) {
|
||||
return signature.substring(0, signature.indexOf(";") + 1);
|
||||
}
|
||||
if (StringUtil.startsWithChar(signature, '[')) {
|
||||
String s = parseParameterSignature(signature.substring(1));
|
||||
return (s != null) ? ("[" + s) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getMethodSignature(String name, String descriptor) {
|
||||
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
builder.append(name);
|
||||
builder.append(descriptor.substring(0, descriptor.indexOf(')') + 1));
|
||||
return builder.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(builder);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean areArraysContentsEqual(int[] exceptions1, int[] exceptions2) {
|
||||
if (exceptions1.length != exceptions2.length) {
|
||||
return false;
|
||||
}
|
||||
if (exceptions1.length != 0) { // optimization
|
||||
TIntHashSet exceptionsSet = new TIntHashSet(exceptions1);
|
||||
for (int exception : exceptions2) {
|
||||
if (!exceptionsSet.contains(exception)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Collection<VirtualFile> findDependentFiles(
|
||||
final CompileContextEx context,
|
||||
final Set<VirtualFile> compiledWithErrors,
|
||||
final @Nullable Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> filter)
|
||||
throws CacheCorruptedException, ExitException {
|
||||
|
||||
if (!CompilerConfiguration.MAKE_ENABLED) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
context.getProgressIndicator().setText(CompilerBundle.message("progress.checking.dependencies"));
|
||||
|
||||
final DependencyCache dependencyCache = context.getDependencyCache();
|
||||
|
||||
final Pair<int[], Set<VirtualFile>> deps = dependencyCache.findDependentClasses(context, context.getProject(), compiledWithErrors);
|
||||
final Pair<int[], Set<VirtualFile>> filteredDeps = filter != null ? filter.fun(deps) : deps;
|
||||
|
||||
final Set<VirtualFile> dependentFiles = new HashSet<VirtualFile>();
|
||||
ApplicationManager.getApplication().runReadAction(new ThrowableComputable<Void, CacheCorruptedException>() {
|
||||
@Override
|
||||
public Void compute() throws CacheCorruptedException {
|
||||
CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(context.getProject());
|
||||
SourceFileFinder sourceFileFinder = new SourceFileFinder(context.getProject(), context);
|
||||
final Cache cache = dependencyCache.getCache();
|
||||
for (final int infoQName : filteredDeps.getFirst()) {
|
||||
final String qualifiedName = dependencyCache.resolve(infoQName);
|
||||
final String sourceFileName = cache.getSourceFileName(infoQName);
|
||||
final VirtualFile file = sourceFileFinder.findSourceFile(qualifiedName, sourceFileName, true);
|
||||
if (file != null) {
|
||||
dependentFiles.add(file);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
LOG.assertTrue(file.isValid());
|
||||
CompilerManagerImpl.addRecompiledPath(file.getPath());
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.info("No source file for " + dependencyCache.resolve(infoQName) + " found; source file name=" + sourceFileName);
|
||||
}
|
||||
}
|
||||
for (final VirtualFile file : filteredDeps.getSecond()) {
|
||||
if (!compilerConfiguration.isExcludedFromCompilation(file)) {
|
||||
dependentFiles.add(file);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
LOG.assertTrue(file.isValid());
|
||||
CompilerManagerImpl.addRecompiledPath(file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
context.getProgressIndicator().setText(
|
||||
dependentFiles.size() > 0 ? CompilerBundle.message("progress.found.dependent.files", dependentFiles.size()) : ""
|
||||
);
|
||||
|
||||
return dependentFiles;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<VirtualFile> getFilesCompiledWithErrors(final CompileContextEx context) {
|
||||
CompilerMessage[] messages = context.getMessages(CompilerMessageCategory.ERROR);
|
||||
Set<VirtualFile> compiledWithErrors = Collections.emptySet();
|
||||
if (messages.length > 0) {
|
||||
compiledWithErrors = new HashSet<VirtualFile>(messages.length);
|
||||
for (CompilerMessage message : messages) {
|
||||
final VirtualFile file = message.getVirtualFile();
|
||||
if (file != null) {
|
||||
compiledWithErrors.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return compiledWithErrors;
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.make;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.containers.SLRUMap;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import com.intellij.util.io.PersistentHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 1, 2008
|
||||
*/
|
||||
public class CachedPersistentHashMap<Key, Value> extends PersistentHashMap<Key, Value> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CachedPersistentHashMap");
|
||||
protected final SLRUMap<Key, Value> myCache;
|
||||
|
||||
public CachedPersistentHashMap(File file, KeyDescriptor<Key> keyDescriptor, DataExternalizer<Value> valDescriptor, final int cacheSize) throws IOException {
|
||||
super(file, keyDescriptor, valDescriptor);
|
||||
myCache = new SLRUMap<Key,Value>(cacheSize * 2, cacheSize) {
|
||||
protected void onDropFromCache(Key key, Value value) {
|
||||
if (isValueDirty(value)) {
|
||||
try {
|
||||
CachedPersistentHashMap.super.put(key, value);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected boolean isValueDirty(Value value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPut(Key key, Value value) throws IOException {
|
||||
myCache.remove(key);
|
||||
super.doPut(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doAppendData(Key key, @NotNull ValueDataAppender appender) throws IOException {
|
||||
myCache.remove(key);
|
||||
super.doAppendData(key, appender);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Value doGet(Key key) throws IOException {
|
||||
Value value = myCache.get(key);
|
||||
if (value == null) {
|
||||
value = super.doGet(key);
|
||||
if (value != null) {
|
||||
myCache.put(key, value);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doContainsMapping(Key key) throws IOException {
|
||||
final Value value = myCache.get(key);
|
||||
return value != null || super.doContainsMapping(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRemove(Key key) throws IOException {
|
||||
myCache.remove(key);
|
||||
super.doRemove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doForce() {
|
||||
try {
|
||||
clearCache();
|
||||
}
|
||||
finally {
|
||||
super.doForce();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doClose() throws IOException {
|
||||
try {
|
||||
clearCache();
|
||||
}
|
||||
finally {
|
||||
super.doClose();
|
||||
}
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
myCache.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.make;
|
||||
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.util.Query;
|
||||
import com.intellij.util.containers.SoftHashMap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Oct 15
|
||||
* @author 2003
|
||||
*/
|
||||
public class CachingSearcher {
|
||||
private final Project myProject;
|
||||
private final Map<Pair<PsiElement, Boolean>, Collection<PsiReference>> myElementToReferencersMap = new SoftHashMap<Pair<PsiElement, Boolean>, Collection<PsiReference>>();
|
||||
|
||||
public CachingSearcher(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public Collection<PsiReference> findReferences(PsiElement element, final boolean ignoreAccessScope) {
|
||||
final Pair<PsiElement, Boolean> key = Pair.create(element, ignoreAccessScope ? Boolean.TRUE : Boolean.FALSE);
|
||||
Collection<PsiReference> psiReferences = myElementToReferencersMap.get(key);
|
||||
if (psiReferences == null) {
|
||||
GlobalSearchScope searchScope = GlobalSearchScope.projectScope(myProject);
|
||||
searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes(searchScope, StdFileTypes.JAVA);
|
||||
final Query<PsiReference> query = ReferencesSearch.search(element, searchScope, ignoreAccessScope);
|
||||
psiReferences = query.findAll();
|
||||
myElementToReferencersMap.put(key, psiReferences);
|
||||
}
|
||||
return psiReferences;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.make;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Apr 7, 2004
|
||||
*/
|
||||
abstract class ChangeDescription {
|
||||
public abstract boolean isChanged();
|
||||
}
|
||||
-370
@@ -1,370 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Feb 24, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.make;
|
||||
|
||||
import com.intellij.compiler.classParsing.FieldInfo;
|
||||
import com.intellij.compiler.impl.ExitException;
|
||||
import com.intellij.compiler.impl.ExitStatus;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ChangedConstantsDependencyProcessor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.ChangedConstantsDependencyProcessor");
|
||||
private final Project myProject;
|
||||
private final CachingSearcher mySearcher;
|
||||
private final DependencyCache myDependencyCache;
|
||||
private final int myQName;
|
||||
private final CompileContext myContext;
|
||||
private final FieldChangeInfo[] myChangedFields;
|
||||
private final FieldChangeInfo[] myRemovedFields;
|
||||
private final int MAX_CONSTANT_SEARCHES = Registry.intValue("compiler.max.static.constants.searches");
|
||||
|
||||
|
||||
public ChangedConstantsDependencyProcessor(Project project,
|
||||
CachingSearcher searcher,
|
||||
DependencyCache dependencyCache,
|
||||
int qName, CompileContext context, FieldChangeInfo[] changedFields,
|
||||
FieldChangeInfo[] removedFields) {
|
||||
myProject = project;
|
||||
mySearcher = searcher;
|
||||
myDependencyCache = dependencyCache;
|
||||
myQName = qName;
|
||||
myContext = context;
|
||||
myChangedFields = changedFields;
|
||||
myRemovedFields = removedFields;
|
||||
}
|
||||
|
||||
public void run() throws CacheCorruptedException, ExitException {
|
||||
final Ref<CacheCorruptedException> _ex = new Ref<CacheCorruptedException>();
|
||||
final Ref<ExitException> exitException = new Ref<ExitException>(null);
|
||||
DumbService.getInstance(myProject).runReadActionInSmartMode(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final String qName = myDependencyCache.resolve(myQName);
|
||||
PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(qName.replace('$', '.'), GlobalSearchScope.allScope(myProject));
|
||||
for (PsiClass aClass : classes) {
|
||||
PsiField[] psiFields = aClass.getFields();
|
||||
for (PsiField psiField : psiFields) {
|
||||
final FieldChangeInfo changeInfo = findChangeInfo(psiField);
|
||||
if (changeInfo != null) { // this field has been changed
|
||||
processFieldChanged(psiField, aClass, changeInfo.isAccessibilityChange);
|
||||
}
|
||||
}
|
||||
for (FieldChangeInfo removedField : myRemovedFields) {
|
||||
processFieldRemoved(removedField.fieldInfo, aClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
_ex.set(e);
|
||||
}
|
||||
catch (ExitException e) {
|
||||
exitException.set(e);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
// supressed deliberately
|
||||
}
|
||||
}
|
||||
});
|
||||
if (_ex.get() != null) {
|
||||
throw _ex.get();
|
||||
}
|
||||
if (exitException.get() != null) {
|
||||
throw exitException.get();
|
||||
}
|
||||
}
|
||||
|
||||
private void processFieldRemoved(FieldInfo info, final PsiClass aClass) throws CacheCorruptedException {
|
||||
if (info.isPrivate()) {
|
||||
return; // optimization: don't need to search, cause may be used only in this class
|
||||
}
|
||||
SearchScope searchScope = GlobalSearchScope.projectScope(myProject);
|
||||
if (info.isPackageLocal()) {
|
||||
final PsiFile containingFile = aClass.getContainingFile();
|
||||
if (containingFile instanceof PsiJavaFile) {
|
||||
final String packageName = ((PsiJavaFile)containingFile).getPackageName();
|
||||
final PsiPackage aPackage = JavaPsiFacade.getInstance(myProject).findPackage(packageName);
|
||||
if (aPackage != null) {
|
||||
searchScope = PackageScope.packageScope(aPackage, false);
|
||||
searchScope = searchScope.intersectWith(aClass.getUseScope());
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiSearchHelper psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(myProject);
|
||||
|
||||
final Ref<CacheCorruptedException> exRef = new Ref<CacheCorruptedException>(null);
|
||||
processIdentifiers(psiSearchHelper, new PsiElementProcessor<PsiIdentifier>() {
|
||||
@Override
|
||||
public synchronized boolean execute(@NotNull PsiIdentifier identifier) {
|
||||
try {
|
||||
final PsiElement parent = identifier.getParent();
|
||||
if (parent instanceof PsiReferenceExpression) {
|
||||
final PsiClass ownerClass = getOwnerClass(parent);
|
||||
if (ownerClass != null && !ownerClass.equals(aClass)) {
|
||||
final String _qName = ownerClass.getQualifiedName();
|
||||
if (_qName != null) {
|
||||
int qualifiedName = myDependencyCache.getSymbolTable().getId(_qName);
|
||||
// should force marking of the class no matter was it compiled or not
|
||||
// This will ensure the class was recompiled _after_ all the constants get their new values
|
||||
if (myDependencyCache.markClass(qualifiedName, true)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Mark dependent class " + myDependencyCache.resolve(qualifiedName) + "; reason: some constants were removed from " + myDependencyCache.resolve(myQName));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.warn("Class with null qualified name was not expected here: " + ownerClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
exRef.set(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}, myDependencyCache.resolve(info.getName()), searchScope, UsageSearchContext.IN_CODE);
|
||||
|
||||
final CacheCorruptedException cacheCorruptedException = exRef.get();
|
||||
if (cacheCorruptedException != null) {
|
||||
throw cacheCorruptedException;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean processIdentifiers(PsiSearchHelper helper,
|
||||
@NotNull final PsiElementProcessor<PsiIdentifier> processor,
|
||||
@NotNull final String identifier,
|
||||
@NotNull SearchScope searchScope,
|
||||
short searchContext) {
|
||||
TextOccurenceProcessor processor1 = new TextOccurenceProcessor() {
|
||||
public boolean execute(PsiElement element, int offsetInElement) {
|
||||
return !(element instanceof PsiIdentifier) || processor.execute((PsiIdentifier)element);
|
||||
}
|
||||
};
|
||||
return helper.processElementsWithWord(processor1, searchScope, identifier, searchContext, true);
|
||||
}
|
||||
|
||||
private void processFieldChanged(PsiField field, PsiClass aClass, final boolean isAccessibilityChange)
|
||||
throws CacheCorruptedException, ExitException {
|
||||
if (!isAccessibilityChange && field.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
return; // optimization: don't need to search, cause may be used only in this class
|
||||
}
|
||||
Set<PsiElement> usages = new HashSet<PsiElement>();
|
||||
addUsages(field, usages, isAccessibilityChange);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||
LOG.debug("Processing changed field: " + aClass.getQualifiedName() + "." + field.getName());
|
||||
}
|
||||
for (final PsiElement usage : usages) {
|
||||
PsiClass ownerClass = getOwnerClass(usage);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
if (ownerClass != null) {
|
||||
LOG.debug("Usage " + usage + " found in class: " + ownerClass.getQualifiedName());
|
||||
}
|
||||
else {
|
||||
LOG.debug("Usage " + usage + " found in class: null");
|
||||
}
|
||||
}
|
||||
if (ownerClass != null && !ownerClass.equals(aClass)) {
|
||||
int qualifiedName = myDependencyCache.getSymbolTable().getId(ownerClass.getQualifiedName());
|
||||
// should force marking of the class no matter was it compiled or not
|
||||
// This will ensure the class was recompiled _after_ all the constants get their new values
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Marking class id = [" + qualifiedName + "], name=[" + myDependencyCache.resolve(qualifiedName) + "]");
|
||||
}
|
||||
if (myDependencyCache.markClass(qualifiedName, true)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Marked dependent class " + myDependencyCache.resolve(qualifiedName) + "; reason: constants changed in " +
|
||||
myDependencyCache.resolve(myQName));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ownerClass == null) {
|
||||
final PsiFile containingFile = usage.getContainingFile();
|
||||
if (containingFile != null) {
|
||||
final VirtualFile file = containingFile.getVirtualFile();
|
||||
if (file != null) {
|
||||
myDependencyCache.markFile(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("+++++++++++++++++++++++++++++++++++++++++++++++");
|
||||
}
|
||||
}
|
||||
|
||||
private void addUsages(PsiField psiField, Collection<PsiElement> usages, final boolean ignoreAccessScope) throws ExitException {
|
||||
final int count = getConstantSearchesCount();
|
||||
if (count > MAX_CONSTANT_SEARCHES) {
|
||||
myContext.requestRebuildNextTime("Too many changed compile-time constants, project rebuild scheduled");
|
||||
throw new ExitException(ExitStatus.CANCELLED);
|
||||
}
|
||||
Collection<PsiReference> references = mySearcher.findReferences(psiField, ignoreAccessScope)/*doFindReferences(searchHelper, psiField)*/;
|
||||
|
||||
incConstantSearchesCount();
|
||||
|
||||
for (final PsiReference ref : references) {
|
||||
if (!(ref instanceof PsiReferenceExpression)) {
|
||||
continue;
|
||||
}
|
||||
PsiElement e = ref.getElement();
|
||||
usages.add(e);
|
||||
PsiField ownerField = getOwnerField(e);
|
||||
if (ownerField != null) {
|
||||
if (ownerField.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
PsiExpression initializer = ownerField.getInitializer();
|
||||
if (initializer != null && PsiUtil.isConstantExpression(initializer)) {
|
||||
// if the field depends on the compile-time-constant expression and is itself final
|
||||
addUsages(ownerField, usages, ignoreAccessScope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private PsiReference[] doFindReferences(final PsiSearchHelper searchHelper, final PsiField psiField) {
|
||||
final ProgressManager progressManager = ProgressManager.getInstance();
|
||||
final ProgressIndicator currentProgress = progressManager.getProgressIndicator();
|
||||
final PsiReference[][] references = new PsiReference[][] {null};
|
||||
progressManager.runProcess(new Runnable() {
|
||||
public void run() {
|
||||
references[0] = searchHelper.findReferences(psiField, GlobalSearchScope.projectScope(myProject), false);
|
||||
if (ENABLE_TRACING) {
|
||||
System.out.println("Finding referencers for " + psiField);
|
||||
}
|
||||
}
|
||||
}, new NonCancellableProgressAdapter(currentProgress));
|
||||
return references[0];
|
||||
}
|
||||
*/
|
||||
|
||||
@Nullable
|
||||
private static PsiField getOwnerField(PsiElement element) {
|
||||
while (!(element instanceof PsiFile)) {
|
||||
if (element instanceof PsiClass) {
|
||||
break;
|
||||
}
|
||||
if (element instanceof PsiField) { // top-level class
|
||||
return (PsiField)element;
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FieldChangeInfo findChangeInfo(PsiField field) throws CacheCorruptedException {
|
||||
String name = field.getName();
|
||||
for (final FieldChangeInfo changeInfo : myChangedFields) {
|
||||
if (name.equals(myDependencyCache.resolve(changeInfo.fieldInfo.getName()))) {
|
||||
return changeInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getOwnerClass(PsiElement element) {
|
||||
while (!(element instanceof PsiFile)) {
|
||||
if (element instanceof PsiClass && element.getParent() instanceof PsiJavaFile) { // top-level class
|
||||
final PsiClass psiClass = (PsiClass)element;
|
||||
if (JspPsiUtil.isInJspFile(psiClass)) {
|
||||
return null;
|
||||
}
|
||||
final PsiFile containingFile = psiClass.getContainingFile();
|
||||
if (containingFile == null) {
|
||||
return null;
|
||||
}
|
||||
return StdLanguages.JAVA.equals(containingFile.getLanguage())? psiClass : null;
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class FieldChangeInfo {
|
||||
final FieldInfo fieldInfo;
|
||||
final boolean isAccessibilityChange;
|
||||
|
||||
public FieldChangeInfo(final FieldInfo fieldId) {
|
||||
this(fieldId, false);
|
||||
}
|
||||
|
||||
public FieldChangeInfo(final FieldInfo fieldInfo, final boolean accessibilityChange) {
|
||||
this.fieldInfo = fieldInfo;
|
||||
isAccessibilityChange = accessibilityChange;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final FieldChangeInfo fieldChangeInfo = (FieldChangeInfo)o;
|
||||
|
||||
if (isAccessibilityChange != fieldChangeInfo.isAccessibilityChange) return false;
|
||||
if (!fieldInfo.equals(fieldChangeInfo.fieldInfo)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = fieldInfo.hashCode();
|
||||
result = 29 * result + (isAccessibilityChange ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Key<Integer> CONSTANTS_COUNTER = Key.create("_constant_searches_counter_");
|
||||
|
||||
private int getConstantSearchesCount() {
|
||||
return getConstantSearchesCount(myContext);
|
||||
}
|
||||
|
||||
public static int getConstantSearchesCount(CompileContext context) {
|
||||
final Integer value = CONSTANTS_COUNTER.get(context);
|
||||
return value != null? value.intValue() : 0;
|
||||
}
|
||||
|
||||
private void incConstantSearchesCount() {
|
||||
CONSTANTS_COUNTER.set(myContext, getConstantSearchesCount() + 1);
|
||||
}
|
||||
}
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.make;
|
||||
|
||||
import com.intellij.compiler.SymbolTable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.cls.ClsUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ChangedRetentionPolicyDependencyProcessor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.ChangedConstantsDependencyProcessor");
|
||||
private final Project myProject;
|
||||
private final CachingSearcher mySearcher;
|
||||
private final DependencyCache myDependencyCache;
|
||||
|
||||
public ChangedRetentionPolicyDependencyProcessor(Project project, CachingSearcher searcher, DependencyCache dependencyCache) {
|
||||
myProject = project;
|
||||
mySearcher = searcher;
|
||||
myDependencyCache = dependencyCache;
|
||||
}
|
||||
|
||||
public void checkAnnotationRetentionPolicyChanges(final int annotationQName) throws CacheCorruptedException {
|
||||
final Cache oldCache = myDependencyCache.getCache();
|
||||
if (!ClsUtil.isAnnotation(oldCache.getFlags(annotationQName))) {
|
||||
return;
|
||||
}
|
||||
if (!hasRetentionPolicyChanged(annotationQName, oldCache, myDependencyCache.getNewClassesCache(), myDependencyCache.getSymbolTable())) {
|
||||
return;
|
||||
}
|
||||
final CacheCorruptedException[] _ex = new CacheCorruptedException[] {null};
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final String qName = myDependencyCache.resolve(annotationQName);
|
||||
PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(qName.replace('$', '.'), GlobalSearchScope.allScope(myProject));
|
||||
for (final PsiClass aClass : classes) {
|
||||
if (!aClass.isAnnotationType()) {
|
||||
continue;
|
||||
}
|
||||
final Collection<PsiReference> references = mySearcher.findReferences(aClass, true);
|
||||
for (PsiReference reference : references) {
|
||||
final PsiClass ownerClass = getOwnerClass(reference.getElement());
|
||||
if (ownerClass != null && !ownerClass.equals(aClass)) {
|
||||
int qualifiedName = myDependencyCache.getSymbolTable().getId(ownerClass.getQualifiedName());
|
||||
if (myDependencyCache.markClass(qualifiedName, false)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Marked dependent class " + myDependencyCache.resolve(qualifiedName) +
|
||||
"; reason: annotation's retention policy changed from SOURCE to CLASS or RUNTIME " +
|
||||
myDependencyCache.resolve(annotationQName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
_ex[0] = e;
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
// supressed deliberately
|
||||
}
|
||||
}
|
||||
});
|
||||
if (_ex[0] != null) {
|
||||
throw _ex[0];
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasRetentionPolicyChanged(int annotationQName, final Cache oldCache, final Cache newCache, SymbolTable symbolTable) throws CacheCorruptedException {
|
||||
// if retention policy changed from SOURCE to CLASS or RUNTIME, all sources should be recompiled to propagate changes
|
||||
final int oldPolicy = MakeUtil.getAnnotationRetentionPolicy(annotationQName, oldCache, symbolTable);
|
||||
final int newPolicy = MakeUtil.getAnnotationRetentionPolicy(annotationQName, newCache, symbolTable);
|
||||
if ((oldPolicy == RetentionPolicies.SOURCE) && (newPolicy == RetentionPolicies.CLASS || newPolicy == RetentionPolicies.RUNTIME)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static PsiClass getOwnerClass(PsiElement element) {
|
||||
while (!(element instanceof PsiFile)) {
|
||||
if (element instanceof PsiClass && element.getParent() instanceof PsiJavaFile) { // top-level class
|
||||
return (PsiClass)element;
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author: Eugene Zhuravlev
|
||||
* Date: May 14, 2003
|
||||
* Time: 10:42:29 AM
|
||||
*/
|
||||
package com.intellij.compiler.make;
|
||||
|
||||
|
||||
|
||||
public interface ClassInfoProcessor {
|
||||
/**
|
||||
* @param classQName of a class info to be processed
|
||||
* @return true if superclasses of info should be processed and false otherwise
|
||||
*/
|
||||
boolean process(int classQName) throws CacheCorruptedException;
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.make;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.containers.SLRUCache;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import com.intellij.util.io.PersistentHashMap;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 1, 2008
|
||||
*/
|
||||
public class CompilerDependencyStorage<Key> implements Flushable, Disposable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CompilerDependencyStorage");
|
||||
protected final PersistentHashMap<Key, int[]> myMap;
|
||||
protected final SLRUCache<Key, IntSet> myCache;
|
||||
private Key myKeyToRemove;
|
||||
|
||||
public CompilerDependencyStorage(File file, KeyDescriptor<Key> keyDescriptor, final int cacheSize) throws IOException {
|
||||
myMap = new PersistentHashMap<Key, int[]>(file, keyDescriptor, new DataExternalizer<int[]>() {
|
||||
public void save(@NotNull DataOutput out, int[] array) throws IOException {
|
||||
out.writeInt(array.length);
|
||||
for (int value : array) {
|
||||
out.writeInt(value);
|
||||
}
|
||||
}
|
||||
|
||||
public int[] read(@NotNull DataInput in) throws IOException {
|
||||
final TIntHashSet set = new TIntHashSet();
|
||||
DataInputStream stream = (DataInputStream)in;
|
||||
while(stream.available() > 0) {
|
||||
final int size = stream.readInt();
|
||||
final int _size = Math.abs(size);
|
||||
for (int idx = 0; idx < _size; idx++) {
|
||||
if (size > 0) {
|
||||
set.add(stream.readInt());
|
||||
}
|
||||
else {
|
||||
set.remove(stream.readInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
return set.toArray();
|
||||
}
|
||||
});
|
||||
|
||||
myCache = new SLRUCache<Key, IntSet>(cacheSize * 2, cacheSize) {
|
||||
@NotNull
|
||||
public IntSet createValue(Key key) {
|
||||
return new IntSet(key);
|
||||
}
|
||||
|
||||
protected void onDropFromCache(Key key, final IntSet set) {
|
||||
if (key == myKeyToRemove || !set.isDirty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (set.needsCompacting()) {
|
||||
myMap.put(key, set.getValues());
|
||||
}
|
||||
else {
|
||||
myMap.appendData(key, new PersistentHashMap.ValueDataAppender() {
|
||||
public void append(final DataOutput out) throws IOException {
|
||||
final Ref<IOException> exception = new Ref<IOException>(null);
|
||||
final TIntProcedure saveProc = new TIntProcedure() {
|
||||
public boolean execute(int value) {
|
||||
try {
|
||||
out.writeInt(value);
|
||||
return true;
|
||||
}
|
||||
catch (IOException e) {
|
||||
exception.set(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
out.writeInt(-set.getRemovedCount());
|
||||
set.processRemovedValues(saveProc);
|
||||
if (exception.get() != null) {
|
||||
throw exception.get();
|
||||
}
|
||||
|
||||
out.writeInt(set.getAddedCount());
|
||||
set.processAddedValues(saveProc);
|
||||
if (exception.get() != null) {
|
||||
throw exception.get();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public synchronized void remove(Key key) throws IOException {
|
||||
myKeyToRemove = key;
|
||||
try {
|
||||
myCache.remove(key);
|
||||
}
|
||||
finally {
|
||||
myKeyToRemove = null;
|
||||
}
|
||||
myMap.remove(key);
|
||||
}
|
||||
|
||||
public synchronized void removeValue(Key key, int value) throws IOException {
|
||||
final IntSet set = myCache.get(key);
|
||||
set.remove(value);
|
||||
if (set.needsFlushing()) {
|
||||
flush(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public synchronized void addValue(Key key, int value) throws IOException {
|
||||
final IntSet set = myCache.get(key);
|
||||
set.add(value);
|
||||
if (set.needsFlushing()) {
|
||||
flush(key);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized int[] getValues(Key key) throws IOException {
|
||||
return myCache.get(key).getValues();
|
||||
}
|
||||
|
||||
|
||||
public synchronized void flush() throws IOException {
|
||||
myCache.clear();
|
||||
myMap.force();
|
||||
}
|
||||
|
||||
private void flush(Key key) {
|
||||
myCache.remove(key); // makes changes into PersistentHashMap
|
||||
myMap.force(); // flushes internal caches (which consume memory) and writes unsaved data to disk
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
try {
|
||||
flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
try {
|
||||
myMap.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
|
||||
private class IntSet {
|
||||
private final TIntHashSet myAdded = new TIntHashSet();
|
||||
private final TIntHashSet myRemoved = new TIntHashSet();
|
||||
private TIntHashSet myMerged = null;
|
||||
private final Key myKey;
|
||||
|
||||
public IntSet(Key key) {
|
||||
myKey = key;
|
||||
}
|
||||
|
||||
public void add(int value) {
|
||||
if (myMerged != null) {
|
||||
myMerged.add(value);
|
||||
}
|
||||
if (!myRemoved.remove(value)) {
|
||||
myAdded.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(int value) {
|
||||
if (myMerged != null) {
|
||||
myMerged.remove(value);
|
||||
}
|
||||
if (!myAdded.remove(value)) {
|
||||
myRemoved.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return myAdded.size() > 0 || myRemoved.size() > 0;
|
||||
}
|
||||
|
||||
public boolean needsCompacting() {
|
||||
return myMerged != null;
|
||||
}
|
||||
|
||||
public boolean needsFlushing() {
|
||||
return myAdded.size() > 3000 || myRemoved.size() > 3000;
|
||||
}
|
||||
|
||||
public int getAddedCount() {
|
||||
return myAdded.size();
|
||||
}
|
||||
|
||||
public void processAddedValues(final TIntProcedure procedure) {
|
||||
myAdded.forEach(procedure);
|
||||
}
|
||||
|
||||
public int getRemovedCount() {
|
||||
return myRemoved.size();
|
||||
}
|
||||
|
||||
public void processRemovedValues(final TIntProcedure procedure) {
|
||||
myRemoved.forEach(procedure);
|
||||
}
|
||||
|
||||
public int[] getValues() throws IOException {
|
||||
return getMerged().toArray();
|
||||
}
|
||||
|
||||
private TIntHashSet getMerged() throws IOException {
|
||||
if (myMerged == null) {
|
||||
myMerged = new TIntHashSet();
|
||||
final int[] fromDisk = myMap.get(myKey);
|
||||
if (fromDisk != null) {
|
||||
myMerged.addAll(fromDisk);
|
||||
}
|
||||
if (myRemoved.size() > 0) {
|
||||
myMerged.removeAll(myRemoved.toArray());
|
||||
}
|
||||
if (myAdded.size() > 0) {
|
||||
myMerged.addAll(myAdded.toArray());
|
||||
}
|
||||
}
|
||||
return myMerged;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Jan 4, 2002
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.compiler.make;
|
||||
|
||||
import com.intellij.compiler.SymbolTable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Dependency {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.Dependency");
|
||||
public static final Dependency[] EMPTY_ARRAY = new Dependency[0];
|
||||
private final int myClassQualifiedName;
|
||||
private Set<FieldRef> myUsedFields;
|
||||
private Set<MethodRef> myUsedMethods;
|
||||
|
||||
public static class FieldRef {
|
||||
public final int name;
|
||||
|
||||
public FieldRef(int name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
FieldRef fieldRef = (FieldRef)o;
|
||||
|
||||
if (name != fieldRef.name) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MethodRef {
|
||||
public final int name;
|
||||
public final int descriptor;
|
||||
private String[] myParameterDescriptors;
|
||||
|
||||
public MethodRef(int name, int descriptor) {
|
||||
this.name = name;
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
MethodRef methodRef = (MethodRef)o;
|
||||
|
||||
if (descriptor != methodRef.descriptor) return false;
|
||||
if (name != methodRef.name) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = name;
|
||||
result = 31 * result + descriptor;
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getDescriptor(SymbolTable symbolTable) throws CacheCorruptedException {
|
||||
final String descriptorStr = symbolTable.getSymbol(descriptor);
|
||||
final String nameStr = symbolTable.getSymbol(name);
|
||||
return CacheUtils.getMethodSignature(nameStr, descriptorStr);
|
||||
}
|
||||
|
||||
|
||||
public String[] getParameterDescriptors(SymbolTable symbolTable) throws CacheCorruptedException {
|
||||
if (myParameterDescriptors == null) {
|
||||
String descriptorStr = symbolTable.getSymbol(descriptor);
|
||||
int endIndex = descriptorStr.indexOf(')');
|
||||
if (endIndex <= 0) {
|
||||
LOG.error("Corrupted method descriptor: " + descriptorStr);
|
||||
}
|
||||
myParameterDescriptors = parseParameterDescriptors(descriptorStr.substring(1, endIndex));
|
||||
}
|
||||
return myParameterDescriptors;
|
||||
}
|
||||
}
|
||||
|
||||
public Dependency(int classQualifiedName) {
|
||||
myClassQualifiedName = classQualifiedName;
|
||||
}
|
||||
|
||||
public int getClassQualifiedName() {
|
||||
return myClassQualifiedName;
|
||||
}
|
||||
|
||||
public void addMethod(int name, int descriptor) {
|
||||
if (myUsedMethods == null) {
|
||||
myUsedMethods = new HashSet<MethodRef>();
|
||||
}
|
||||
myUsedMethods.add(new MethodRef(name, descriptor));
|
||||
}
|
||||
|
||||
public void addField(int name) {
|
||||
if (myUsedFields == null) {
|
||||
myUsedFields = new HashSet<FieldRef>();
|
||||
}
|
||||
myUsedFields.add(new FieldRef(name));
|
||||
}
|
||||
|
||||
public Collection<FieldRef> getFieldRefs() {
|
||||
return myUsedFields != null? Collections.unmodifiableSet(myUsedFields) : Collections.<FieldRef>emptySet();
|
||||
}
|
||||
|
||||
public Collection<MethodRef> getMethodRefs() {
|
||||
return myUsedMethods != null? Collections.unmodifiableSet(myUsedMethods) : Collections.<MethodRef>emptySet();
|
||||
}
|
||||
|
||||
private static String[] parseParameterDescriptors(String signature) {
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
String paramSignature = parseFieldType(signature);
|
||||
while (paramSignature != null && !paramSignature.isEmpty()) {
|
||||
list.add(paramSignature);
|
||||
signature = signature.substring(paramSignature.length());
|
||||
paramSignature = parseFieldType(signature);
|
||||
}
|
||||
return ArrayUtil.toStringArray(list);
|
||||
}
|
||||
|
||||
private static String parseFieldType(@NonNls String signature) {
|
||||
if (signature.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
char first = signature.charAt(0);
|
||||
if (first == 'I') {
|
||||
return "I";
|
||||
}
|
||||
if (first == 'L') {
|
||||
return signature.substring(0, signature.indexOf(';') + 1);
|
||||
}
|
||||
if (first == 'B') {
|
||||
return "B";
|
||||
}
|
||||
if (first == 'C') {
|
||||
return "C";
|
||||
}
|
||||
if (first == 'D') {
|
||||
return "D";
|
||||
}
|
||||
if (first == 'F') {
|
||||
return "F";
|
||||
}
|
||||
if (first == 'J') {
|
||||
return "J";
|
||||
}
|
||||
if (first == 'S') {
|
||||
return "S";
|
||||
}
|
||||
if (first == 'Z') {
|
||||
return "Z";
|
||||
}
|
||||
if (first == '[') {
|
||||
String s = parseFieldType(signature.substring(1));
|
||||
return s == null ? null : "[" + s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user