mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
+4
-1
@@ -16,8 +16,11 @@
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -27,5 +30,5 @@ public abstract class AdditionalCompileScopeProvider {
|
||||
public static final ExtensionPointName<AdditionalCompileScopeProvider> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.additionalCompileScopeProvider");
|
||||
|
||||
@Nullable
|
||||
public abstract CompileScope getAdditionalScope(CompileScope baseScope);
|
||||
public abstract CompileScope getAdditionalScope(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.CommonBundle;
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.compiler.*;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.compiler.make.CacheUtils;
|
||||
import com.intellij.compiler.make.DependencyCache;
|
||||
import com.intellij.compiler.progress.CompilerTask;
|
||||
import com.intellij.diagnostic.IdeErrorsDialog;
|
||||
@@ -47,6 +48,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
@@ -311,7 +313,7 @@ public class CompileDriver {
|
||||
final AdditionalCompileScopeProvider[] scopeProviders = Extensions.getExtensions(AdditionalCompileScopeProvider.EXTENSION_POINT_NAME);
|
||||
CompileScope baseScope = scope;
|
||||
for (AdditionalCompileScopeProvider scopeProvider : scopeProviders) {
|
||||
final CompileScope additionalScope = scopeProvider.getAdditionalScope(baseScope);
|
||||
final CompileScope additionalScope = scopeProvider.getAdditionalScope(baseScope, filter, myProject);
|
||||
if (additionalScope != null) {
|
||||
scope = new CompositeScope(scope, additionalScope);
|
||||
}
|
||||
@@ -840,67 +842,121 @@ public class CompileDriver {
|
||||
|
||||
final TranslatingCompiler[] translators = compilerManager.getCompilers(TranslatingCompiler.class, myCompilerFilter);
|
||||
|
||||
final Set<FileType> generatedTypes = new HashSet<FileType>();
|
||||
VirtualFile[] snapshot = null;
|
||||
|
||||
final List<Chunk<Module>> sortedChunks = Collections.unmodifiableList(ApplicationManager.getApplication().runReadAction(new Computable<List<Chunk<Module>>>() {
|
||||
public List<Chunk<Module>> compute() {
|
||||
final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
|
||||
return ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(moduleManager.getModules()));
|
||||
}
|
||||
}));
|
||||
|
||||
final TranslatorsOutputSink sink = new TranslatorsOutputSink(context, translators);
|
||||
try {
|
||||
for (int currentCompiler = 0, translatorsLength = translators.length; currentCompiler < translatorsLength; currentCompiler++) {
|
||||
sink.setCurrentCompilerIndex(currentCompiler);
|
||||
final TranslatingCompiler translator = translators[currentCompiler];
|
||||
if (context.getProgressIndicator().isCanceled()) {
|
||||
throw new ExitException(ExitStatus.CANCELLED);
|
||||
}
|
||||
|
||||
DumbService.getInstance(myProject).waitForSmartMode();
|
||||
|
||||
if (snapshot == null || ContainerUtil.intersects(generatedTypes, compilerManager.getRegisteredInputTypes(translator))) {
|
||||
// rescan snapshot if previously generated files can influence the input of this compiler
|
||||
snapshot = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile[]>() {
|
||||
public VirtualFile[] compute() {
|
||||
return context.getCompileScope().getFiles(null, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CompileContextEx _context;
|
||||
if (translator instanceof IntermediateOutputCompiler) {
|
||||
// wrap compile context so that output goes into intermediate directories
|
||||
final IntermediateOutputCompiler _translator = (IntermediateOutputCompiler)translator;
|
||||
_context = new CompileContextExProxy(context) {
|
||||
public VirtualFile getModuleOutputDirectory(final Module module) {
|
||||
return getGenerationOutputDir(_translator, module, false);
|
||||
VirtualFile[] snapshot = null;
|
||||
final Map<Chunk<Module>, Collection<VirtualFile>> chunkMap = new HashMap<Chunk<Module>, Collection<VirtualFile>>();
|
||||
int total = 0;
|
||||
int processed = 0;
|
||||
for (final Chunk<Module> currentChunk : sortedChunks) {
|
||||
final TranslatorsOutputSink sink = new TranslatorsOutputSink(context, translators);
|
||||
final Set<FileType> generatedTypes = new HashSet<FileType>();
|
||||
Collection<VirtualFile> chunkFiles = chunkMap.get(currentChunk);
|
||||
try {
|
||||
for (int currentCompiler = 0, translatorsLength = translators.length; currentCompiler < translatorsLength; currentCompiler++) {
|
||||
sink.setCurrentCompilerIndex(currentCompiler);
|
||||
final TranslatingCompiler compiler = translators[currentCompiler];
|
||||
if (context.getProgressIndicator().isCanceled()) {
|
||||
throw new ExitException(ExitStatus.CANCELLED);
|
||||
}
|
||||
|
||||
public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
|
||||
return getGenerationOutputDir(_translator, module, true);
|
||||
DumbService.getInstance(myProject).waitForSmartMode();
|
||||
|
||||
if (snapshot == null || ContainerUtil.intersects(generatedTypes, compilerManager.getRegisteredInputTypes(compiler))) {
|
||||
// rescan snapshot if previously generated files may influence the input of this compiler
|
||||
snapshot = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile[]>() {
|
||||
public VirtualFile[] compute() {
|
||||
return context.getCompileScope().getFiles(null, true);
|
||||
}
|
||||
});
|
||||
final Map<Module, List<VirtualFile>> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(context, snapshot);
|
||||
for (Chunk<Module> moduleChunk : sortedChunks) {
|
||||
List<VirtualFile> files = Collections.emptyList();
|
||||
for (Module module : moduleChunk.getNodes()) {
|
||||
final List<VirtualFile> moduleFiles = moduleToFilesMap.get(module);
|
||||
if (moduleFiles != null) {
|
||||
files = ContainerUtil.concat(files, moduleFiles);
|
||||
}
|
||||
}
|
||||
chunkMap.put(moduleChunk, files);
|
||||
}
|
||||
total = snapshot.length * translatorsLength;
|
||||
chunkFiles = chunkMap.get(currentChunk);
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
_context = context;
|
||||
}
|
||||
final boolean compiledSomething =
|
||||
compileSources(_context, translators, currentCompiler, snapshot, forceCompile, isRebuild, trackDependencies, onlyCheckStatus, sink);
|
||||
|
||||
if (compiledSomething) {
|
||||
generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(translator));
|
||||
}
|
||||
final CompileContextEx _context;
|
||||
if (compiler instanceof IntermediateOutputCompiler) {
|
||||
// wrap compile context so that output goes into intermediate directories
|
||||
final IntermediateOutputCompiler _compiler = (IntermediateOutputCompiler)compiler;
|
||||
_context = new CompileContextExProxy(context) {
|
||||
public VirtualFile getModuleOutputDirectory(final Module module) {
|
||||
return getGenerationOutputDir(_compiler, module, false);
|
||||
}
|
||||
|
||||
if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
|
||||
throw new ExitException(ExitStatus.ERRORS);
|
||||
}
|
||||
public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
|
||||
return getGenerationOutputDir(_compiler, module, true);
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
_context = context;
|
||||
}
|
||||
final boolean compiledSomething =
|
||||
compileSources(_context, currentChunk, compiler, chunkFiles, forceCompile, isRebuild, trackDependencies, onlyCheckStatus, sink);
|
||||
|
||||
didSomething |= compiledSomething;
|
||||
processed += chunkFiles.size();
|
||||
_context.getProgressIndicator().setFraction(((double)processed) / total);
|
||||
|
||||
if (compiledSomething) {
|
||||
generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(compiler));
|
||||
}
|
||||
|
||||
if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
|
||||
throw new ExitException(ExitStatus.ERRORS);
|
||||
}
|
||||
|
||||
didSomething |= compiledSomething;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
// perform update only if there were no errors, so it is guaranteed that the file was processd by all neccesary compilers
|
||||
sink.flushPostponedItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
ProgressManager.getInstance().executeNonCancelableSection(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final Collection<VirtualFile> deps = CacheUtils.findDependentFiles(context, Collections.<VirtualFile>emptySet(), null, null);
|
||||
if (deps.size() > 0) {
|
||||
TranslatingCompilerFilesMonitor.getInstance().update(context, null, Collections.<TranslatingCompiler.OutputItem>emptyList(), deps.toArray(new VirtualFile[deps.size()]));
|
||||
}
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
LOG.info(ignored);
|
||||
}
|
||||
catch (CacheCorruptedException ignored) {
|
||||
LOG.info(ignored);
|
||||
}
|
||||
}
|
||||
});
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
if (context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
// perform update only if there were no errors, so it is guaranteed that the file was processd by all neccesary compilers
|
||||
sink.flushPostponedItems();
|
||||
}
|
||||
dropDependencyCache(context);
|
||||
if (didSomething) {
|
||||
TranslatingCompilerFilesMonitor.getInstance().updateOutputRootsLayout(myProject);
|
||||
}
|
||||
}
|
||||
return didSomething;
|
||||
}
|
||||
@@ -1353,15 +1409,13 @@ public class CompileDriver {
|
||||
};
|
||||
}
|
||||
|
||||
private boolean compileSources(final CompileContextEx context, TranslatingCompiler[] compilers, int currentCompiler, final VirtualFile[] sources,
|
||||
private boolean compileSources(final CompileContextEx context, final Chunk<Module> moduleChunk, final TranslatingCompiler compiler, final Collection<VirtualFile> srcSnapshot,
|
||||
final boolean forceCompile,
|
||||
final boolean isRebuild,
|
||||
final boolean trackDependencies,
|
||||
final boolean onlyCheckStatus,
|
||||
TranslatingCompiler.OutputSink sink) throws ExitException {
|
||||
|
||||
final TranslatingCompiler compiler = compilers[currentCompiler];
|
||||
|
||||
final Set<VirtualFile> toCompile = new HashSet<VirtualFile>();
|
||||
final List<Trinity<File, String, Boolean>> toDelete = new ArrayList<Trinity<File, String, Boolean>>();
|
||||
context.getProgressIndicator().pushState();
|
||||
@@ -1372,13 +1426,13 @@ public class CompileDriver {
|
||||
public void run() {
|
||||
|
||||
TranslatingCompilerFilesMonitor.getInstance().collectFiles(
|
||||
context, compiler, Arrays.asList(sources).iterator(), forceCompile, isRebuild, toCompile, toDelete
|
||||
context, compiler, srcSnapshot.iterator(), forceCompile, isRebuild, toCompile, toDelete
|
||||
);
|
||||
if (trackDependencies && !toCompile.isEmpty()) { // should add dependent files
|
||||
// todo: drop this?
|
||||
final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
|
||||
final PsiManager psiManager = PsiManager.getInstance(myProject);
|
||||
final VirtualFile[] filesToCompile = toCompile.toArray(new VirtualFile[toCompile.size()]);
|
||||
for (final VirtualFile file : filesToCompile) {
|
||||
for (final VirtualFile file : toCompile.toArray(new VirtualFile[toCompile.size()])) {
|
||||
if (fileTypeManager.getFileTypeByFile(file) == StdFileTypes.JAVA) {
|
||||
final PsiFile psiFile = psiManager.findFile(file);
|
||||
if (psiFile != null) {
|
||||
@@ -1414,9 +1468,9 @@ public class CompileDriver {
|
||||
context.requestRebuildNextTime(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((wereFilesDeleted[0] || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
compiler.compile(context, toCompile.toArray(new VirtualFile[toCompile.size()]), sink);
|
||||
compiler.compile(context, moduleChunk, toCompile.toArray(new VirtualFile[toCompile.size()]), sink);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -1729,7 +1783,6 @@ public class CompileDriver {
|
||||
return true;
|
||||
}
|
||||
|
||||
// todo: add validation for module chunks: all modules that form a chunk must have the same JDK
|
||||
private boolean validateCompilerConfiguration(final CompileScope scope, boolean checkOutputAndSourceIntersection) {
|
||||
final Module[] scopeModules = scope.getAffectedModules()/*ModuleManager.getInstance(myProject).getModules()*/;
|
||||
final List<String> modulesWithoutOutputPathSpecified = new ArrayList<String>();
|
||||
@@ -2188,9 +2241,6 @@ public class CompileDriver {
|
||||
LOG.info(e);
|
||||
myContext.requestRebuildNextTime(e.getMessage());
|
||||
}
|
||||
finally {
|
||||
filesMonitor.updateOutputRootsLayout(myContext.getProject());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -34,6 +34,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
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.io.DataInput;
|
||||
@@ -90,7 +91,8 @@ public class AnnotationProcessingCompiler implements SourceProcessingCompiler{
|
||||
private void compile(final CompileContext context, final VirtualFile[] files) {
|
||||
final JavacCompiler javacCompiler = getBackEndCompiler();
|
||||
final boolean processorMode = javacCompiler.setAnnotationProcessorMode(true);
|
||||
final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(myProject, Arrays.asList(files), (CompileContextEx)context, javacCompiler, DummySink.INSTANCE);
|
||||
final Chunk<Module> dummyChunk = new Chunk<Module>(Collections.<Module>emptySet()); // TODO!
|
||||
final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(dummyChunk, myProject, Arrays.asList(files), (CompileContextEx)context, javacCompiler, DummySink.INSTANCE);
|
||||
try {
|
||||
wrapper.compile();
|
||||
}
|
||||
|
||||
+73
-146
@@ -51,12 +51,13 @@ import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Chunk;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.cls.ClsFormatException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
@@ -78,6 +79,7 @@ public class BackendCompilerWrapper {
|
||||
private final CompileContextEx myCompileContext;
|
||||
private final List<VirtualFile> myFilesToCompile;
|
||||
private final TranslatingCompiler.OutputSink mySink;
|
||||
private final Chunk<Module> myChunk;
|
||||
private final Project myProject;
|
||||
private final Set<VirtualFile> myFilesToRecompile;
|
||||
private final Map<Module, VirtualFile> myModuleToTempDirMap = new THashMap<Module, VirtualFile>();
|
||||
@@ -88,10 +90,11 @@ public class BackendCompilerWrapper {
|
||||
public final Map<String, Set<CompiledClass>> myFileNameToSourceMap= new THashMap<String, Set<CompiledClass>>();
|
||||
|
||||
|
||||
public BackendCompilerWrapper(@NotNull final Project project,
|
||||
public BackendCompilerWrapper(Chunk<Module> chunk, @NotNull final Project project,
|
||||
@NotNull List<VirtualFile> filesToCompile,
|
||||
@NotNull CompileContextEx compileContext,
|
||||
@NotNull BackendCompiler compiler, TranslatingCompiler.OutputSink sink) {
|
||||
myChunk = chunk;
|
||||
myProject = project;
|
||||
myCompiler = compiler;
|
||||
myCompileContext = compileContext;
|
||||
@@ -102,7 +105,7 @@ public class BackendCompilerWrapper {
|
||||
mySuccesfullyCompiledJavaFiles = new HashSet<VirtualFile>(filesToCompile.size());
|
||||
}
|
||||
|
||||
public List<TranslatingCompiler.OutputItem> compile() throws CompilerException, CacheCorruptedException {
|
||||
public void compile() throws CompilerException, CacheCorruptedException {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
final Set<VirtualFile> allDependent = new HashSet<VirtualFile>();
|
||||
COMPILE:
|
||||
@@ -112,13 +115,12 @@ public class BackendCompilerWrapper {
|
||||
saveTestData();
|
||||
}
|
||||
|
||||
final Map<Module, List<VirtualFile>> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(myCompileContext, myFilesToCompile);
|
||||
compileModules(moduleToFilesMap);
|
||||
compileModules(buildModuleToFilesMap(myFilesToCompile));
|
||||
}
|
||||
|
||||
Collection<VirtualFile> dependentFiles;
|
||||
do {
|
||||
dependentFiles = findDependentFiles();
|
||||
dependentFiles = CacheUtils.findDependentFiles(myCompileContext, mySuccesfullyCompiledJavaFiles, myCompiler.getDependencyProcessor(), DEPENDENCY_FILTER);
|
||||
|
||||
if (!dependentFiles.isEmpty()) {
|
||||
myFilesToRecompile.addAll(dependentFiles);
|
||||
@@ -130,9 +132,8 @@ public class BackendCompilerWrapper {
|
||||
if (filesInScope.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
final Map<Module, List<VirtualFile>> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(myCompileContext, filesInScope);
|
||||
myCompileContext.getDependencyCache().clearTraverseRoots();
|
||||
compileModules(moduleToFilesMap);
|
||||
compileModules(buildModuleToFilesMap(filesInScope));
|
||||
}
|
||||
}
|
||||
while (!dependentFiles.isEmpty() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0);
|
||||
@@ -154,26 +155,24 @@ public class BackendCompilerWrapper {
|
||||
myModuleToTempDirMap.clear();
|
||||
}
|
||||
|
||||
if (myCompileContext.getProgressIndicator().isCanceled()) {
|
||||
myFilesToRecompile.clear();
|
||||
// when cancelled pretend nothing was compiled and next compile will compile everything from the scratch
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// do not update caches if cancelled because there is a chance that they will be incomplete
|
||||
if (CompilerConfiguration.MAKE_ENABLED) {
|
||||
ProgressIndicator indicator = myCompileContext.getProgressIndicator();
|
||||
final DependencyCache cache = myCompileContext.getDependencyCache();
|
||||
if (!myCompileContext.getProgressIndicator().isCanceled()) {
|
||||
// when cancelled pretend nothing was compiled and next compile will compile everything from the scratch
|
||||
final ProgressIndicator indicator = myCompileContext.getProgressIndicator();
|
||||
final DependencyCache cache = myCompileContext.getDependencyCache();
|
||||
|
||||
indicator.setText(CompilerBundle.message("progress.updating.caches"));
|
||||
indicator.setText2("");
|
||||
indicator.pushState();
|
||||
indicator.setText(CompilerBundle.message("progress.updating.caches"));
|
||||
indicator.setText2("");
|
||||
|
||||
cache.update(indicator);
|
||||
cache.update();
|
||||
|
||||
indicator.setText(CompilerBundle.message("progress.saving.caches"));
|
||||
cache.resetState();
|
||||
indicator.setText(CompilerBundle.message("progress.saving.caches"));
|
||||
cache.resetState();
|
||||
|
||||
indicator.setText("");
|
||||
indicator.popState();
|
||||
}
|
||||
}
|
||||
|
||||
myFilesToRecompile.removeAll(mySuccesfullyCompiledJavaFiles);
|
||||
@@ -184,13 +183,19 @@ public class BackendCompilerWrapper {
|
||||
if (myFilesToRecompile.size() > 0 || outputs.size() > 0) {
|
||||
mySink.add(null, outputs, myFilesToRecompile.toArray(new VirtualFile[myFilesToRecompile.size()]));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<Module, List<VirtualFile>> buildModuleToFilesMap(final List<VirtualFile> filesToCompile) {
|
||||
if (myChunk.getNodes().size() == 1) {
|
||||
return Collections.singletonMap(myChunk.getNodes().iterator().next(), Collections.unmodifiableList(filesToCompile));
|
||||
}
|
||||
return CompilerUtil.buildModuleToFilesMap(myCompileContext, filesToCompile);
|
||||
}
|
||||
|
||||
// package-info.java hack
|
||||
private List<TranslatingCompiler.OutputItem> processPackageInfoFiles() {
|
||||
if (myFilesToRecompile.isEmpty()) {
|
||||
return Collections.EMPTY_LIST;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<TranslatingCompiler.OutputItem> outputs = new ArrayList<TranslatingCompiler.OutputItem>();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@@ -215,13 +220,16 @@ public class BackendCompilerWrapper {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
private List<VirtualFile> getFilesInScope(final Collection<VirtualFile> dependentFiles) {
|
||||
final List<VirtualFile> filesInScope = new ArrayList<VirtualFile>(dependentFiles.size());
|
||||
private List<VirtualFile> getFilesInScope(final Collection<VirtualFile> files) {
|
||||
final List<VirtualFile> filesInScope = new ArrayList<VirtualFile>(files.size());
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
for (VirtualFile dependentFile : dependentFiles) {
|
||||
if (myCompileContext.getCompileScope().belongs(dependentFile.getUrl())) {
|
||||
filesInScope.add(dependentFile);
|
||||
for (VirtualFile file : files) {
|
||||
if (myCompileContext.getCompileScope().belongs(file.getUrl())) {
|
||||
final Module module = myCompileContext.getModuleByFile(file);
|
||||
if (myChunk.getNodes().contains(module)) {
|
||||
filesInScope.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,25 +238,21 @@ public class BackendCompilerWrapper {
|
||||
}
|
||||
|
||||
private void compileModules(final Map<Module, List<VirtualFile>> moduleToFilesMap) throws CompilerException {
|
||||
final List<ModuleChunk> chunks = getModuleChunks(moduleToFilesMap);
|
||||
List<VirtualFile> files = ContainerUtil.concat(moduleToFilesMap.values());
|
||||
myProcessedFilesCount = 0;
|
||||
myTotalFilesToCompile = files.size();
|
||||
//myTotalFilesToCompile = 0;
|
||||
//for (List<VirtualFile> list : moduleToFilesMap.values()) {
|
||||
// myTotalFilesToCompile += list.size();
|
||||
//}
|
||||
|
||||
for (final ModuleChunk chunk : chunks) {
|
||||
try {
|
||||
boolean success = compileChunk(chunk);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new CompilerException(e.getMessage(), e);
|
||||
}
|
||||
try {
|
||||
compileChunk(new ModuleChunk(myCompileContext, myChunk, moduleToFilesMap));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new CompilerException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean compileChunk(ModuleChunk chunk) throws IOException {
|
||||
private void compileChunk(ModuleChunk chunk) throws IOException {
|
||||
runTransformingCompilers(chunk);
|
||||
|
||||
setPresentableNameFor(chunk);
|
||||
@@ -259,9 +263,6 @@ public class BackendCompilerWrapper {
|
||||
try {
|
||||
for (final OutputDir outputDir : outs) {
|
||||
doCompile(chunk, outputDir.getPath(), outputDir.getKind());
|
||||
if (myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -269,8 +270,6 @@ public class BackendCompilerWrapper {
|
||||
FileUtil.asyncDelete(fileToDelete);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -295,6 +294,7 @@ public class BackendCompilerWrapper {
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private File getOutputDirsToCompileTo(ModuleChunk chunk, final List<OutputDir> pairs) throws IOException {
|
||||
File fileToDelete = null;
|
||||
if (chunk.getModuleCount() == 1) { // optimization
|
||||
@@ -333,19 +333,6 @@ public class BackendCompilerWrapper {
|
||||
return fileToDelete;
|
||||
}
|
||||
|
||||
private List<ModuleChunk> getModuleChunks(final Map<Module, List<VirtualFile>> moduleToFilesMap) {
|
||||
final List<Module> modules = new ArrayList<Module>(moduleToFilesMap.keySet());
|
||||
final List<Chunk<Module>> chunks = ApplicationManager.getApplication().runReadAction(new Computable<List<Chunk<Module>>>() {
|
||||
public List<Chunk<Module>> compute() {
|
||||
return ModuleCompilerUtil.getSortedModuleChunks(myProject, modules);
|
||||
}
|
||||
});
|
||||
final List<ModuleChunk> moduleChunks = new ArrayList<ModuleChunk>(chunks.size());
|
||||
for (final Chunk<Module> chunk : chunks) {
|
||||
moduleChunks.add(new ModuleChunk(myCompileContext, chunk, moduleToFilesMap));
|
||||
}
|
||||
return moduleChunks;
|
||||
}
|
||||
|
||||
private boolean shouldCompileTestsSeparately(Module module) {
|
||||
final String moduleTestOutputDirectory = getTestsOutputDir(module);
|
||||
@@ -368,77 +355,18 @@ public class BackendCompilerWrapper {
|
||||
|
||||
private final TIntHashSet myProcessedNames = new TIntHashSet();
|
||||
private final Set<VirtualFile> myProcessedFiles = new HashSet<VirtualFile>();
|
||||
private final Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> DEPENDENCY_FILTER = new Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>>() {
|
||||
public Pair<int[], Set<VirtualFile>> fun(Pair<int[], Set<VirtualFile>> deps) {
|
||||
final TIntHashSet currentDeps = new TIntHashSet(deps.getFirst());
|
||||
currentDeps.removeAll(myProcessedNames.toArray());
|
||||
myProcessedNames.addAll(deps.getFirst());
|
||||
|
||||
private Collection<VirtualFile> findDependentFiles() throws CacheCorruptedException {
|
||||
if (!CompilerConfiguration.MAKE_ENABLED) {
|
||||
return Collections.emptyList();
|
||||
final Set<VirtualFile> depFiles = new HashSet<VirtualFile>(deps.getSecond());
|
||||
depFiles.removeAll(myProcessedFiles);
|
||||
myProcessedFiles.addAll(deps.getSecond());
|
||||
return new Pair<int[], Set<VirtualFile>>(currentDeps.toArray(), depFiles);
|
||||
}
|
||||
myCompileContext.getProgressIndicator().setText(CompilerBundle.message("progress.checking.dependencies"));
|
||||
|
||||
final DependencyCache dependencyCache = myCompileContext.getDependencyCache();
|
||||
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
final Pair<int[], Set<VirtualFile>> deps =
|
||||
dependencyCache.findDependentClasses(myCompileContext, myProject, mySuccesfullyCompiledJavaFiles, myCompiler.getDependencyProcessor());
|
||||
|
||||
final TIntHashSet currentDeps = new TIntHashSet(deps.getFirst());
|
||||
currentDeps.removeAll(myProcessedNames.toArray());
|
||||
final int[] depQNames = currentDeps.toArray();
|
||||
myProcessedNames.addAll(deps.getFirst());
|
||||
|
||||
final Set<VirtualFile> depFiles = new HashSet<VirtualFile>(deps.getSecond());
|
||||
depFiles.removeAll(myProcessedFiles);
|
||||
myProcessedFiles.addAll(deps.getSecond());
|
||||
|
||||
final Set<VirtualFile> dependentFiles = new HashSet<VirtualFile>();
|
||||
final CacheCorruptedException[] _ex = {null};
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject);
|
||||
SourceFileFinder sourceFileFinder = new SourceFileFinder(myProject, myCompileContext);
|
||||
final Cache cache = dependencyCache.getCache();
|
||||
for (final int infoQName : depQNames) {
|
||||
final String qualifiedName = dependencyCache.resolve(infoQName);
|
||||
final String sourceFileName = cache.getSourceFileName(infoQName);
|
||||
final VirtualFile file = sourceFileFinder.findSourceFile(qualifiedName, sourceFileName);
|
||||
if (file != null) {
|
||||
if (!compilerConfiguration.isExcludedFromCompilation(file)) {
|
||||
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 : depFiles) {
|
||||
if (!compilerConfiguration.isExcludedFromCompilation(file)) {
|
||||
dependentFiles.add(file);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
LOG.assertTrue(file.isValid());
|
||||
CompilerManagerImpl.addRecompiledPath(file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
_ex[0] = e;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (_ex[0] != null) {
|
||||
throw _ex[0];
|
||||
}
|
||||
myCompileContext.getProgressIndicator().setText(CompilerBundle.message("progress.found.dependent.files", dependentFiles.size()));
|
||||
|
||||
CompilerUtil.logDuration("Finding dependencies", System.currentTimeMillis() - start);
|
||||
return dependentFiles;
|
||||
}
|
||||
};
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
@@ -736,11 +664,11 @@ public class BackendCompilerWrapper {
|
||||
return compiledWithErrors;
|
||||
}
|
||||
|
||||
private void buildOutputItemsList(final String outputDir, Module module, VirtualFile from,
|
||||
final FileTypeManager typeManager,
|
||||
final Set<VirtualFile> compiledWithErrors,
|
||||
final VirtualFile sourceRoot,
|
||||
final String packagePrefix, final List<File> filesToRefresh, final Map<String, Collection<TranslatingCompiler.OutputItem>> results) throws CacheCorruptedException {
|
||||
private void buildOutputItemsList(final String outputDir, Module module, VirtualFile from,
|
||||
final FileTypeManager typeManager,
|
||||
final Set<VirtualFile> compiledWithErrors,
|
||||
final VirtualFile sourceRoot,
|
||||
final String packagePrefix, final List<File> filesToRefresh, final Map<String, Collection<TranslatingCompiler.OutputItem>> results) throws CacheCorruptedException {
|
||||
final Ref<CacheCorruptedException> exRef = new Ref<CacheCorruptedException>(null);
|
||||
final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex();
|
||||
final ContentIterator contentIterator = new ContentIterator() {
|
||||
@@ -777,8 +705,9 @@ public class BackendCompilerWrapper {
|
||||
}
|
||||
}.iterateContent(from);
|
||||
}
|
||||
if (exRef.get() != null) {
|
||||
throw exRef.get();
|
||||
final CacheCorruptedException exc = exRef.get();
|
||||
if (exc != null) {
|
||||
throw exc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -843,6 +772,7 @@ public class BackendCompilerWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Pair<String, String> moveToRealLocation(String tempOutputDir, String pathToClass, VirtualFile sourceFile, final List<File> filesToRefresh) {
|
||||
final Module module = myCompileContext.getModuleByFile(sourceFile);
|
||||
if (module == null) {
|
||||
@@ -873,11 +803,9 @@ public class BackendCompilerWrapper {
|
||||
boolean success = fromFile.renameTo(toFile);
|
||||
if (!success) {
|
||||
// assuming cause of the fail: intermediate dirs do not exist
|
||||
final File parentFile = toFile.getParentFile();
|
||||
if (parentFile != null) {
|
||||
parentFile.mkdirs();
|
||||
success = fromFile.renameTo(toFile); // retry after making non-existent dirs
|
||||
}
|
||||
FileUtil.createParentDirs(toFile);
|
||||
// retry after making non-existent dirs
|
||||
success = fromFile.renameTo(toFile);
|
||||
}
|
||||
if (!success) { // failed to move the file: e.g. because source and destination reside on different mountpoints.
|
||||
try {
|
||||
@@ -921,9 +849,8 @@ public class BackendCompilerWrapper {
|
||||
return out;
|
||||
}
|
||||
|
||||
private int myProcessedFilesCount = 0;
|
||||
private int myTotalFilesToCompile = 0;
|
||||
private int myClassesCount = 0;
|
||||
private volatile int myProcessedFilesCount = 0;
|
||||
private volatile int myClassesCount = 0;
|
||||
private volatile String myModuleName = null;
|
||||
|
||||
private void sourceFileProcessed() {
|
||||
@@ -941,7 +868,7 @@ public class BackendCompilerWrapper {
|
||||
msg = CompilerBundle.message("statistics.files.classes", myProcessedFilesCount, myClassesCount);
|
||||
}
|
||||
myCompileContext.getProgressIndicator().setText2(msg);
|
||||
myCompileContext.getProgressIndicator().setFraction(1.0* myProcessedFilesCount /myTotalFilesToCompile);
|
||||
//myCompileContext.getProgressIndicator().setFraction(1.0* myProcessedFilesCount /myTotalFilesToCompile);
|
||||
}
|
||||
|
||||
private class ClassParsingThread implements Runnable {
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ 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;
|
||||
|
||||
@@ -40,7 +41,7 @@ public class DummyTranslatingCompiler implements TranslatingCompiler, Intermedia
|
||||
return file.getName().endsWith(FILETYPE_EXTENSION);
|
||||
}
|
||||
|
||||
public void compile(final CompileContext context, final VirtualFile[] files, OutputSink sink) {
|
||||
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() {
|
||||
|
||||
@@ -30,8 +30,10 @@ import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
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;
|
||||
@@ -54,10 +56,9 @@ public class JavaCompiler implements TranslatingCompiler {
|
||||
return FILE_TYPE_MANAGER.getFileTypeByFile(file).equals(StdFileTypes.JAVA);
|
||||
}
|
||||
|
||||
public void compile(CompileContext context, VirtualFile[] files, OutputSink sink) {
|
||||
public void compile(CompileContext context, Chunk<Module> moduleChunk, VirtualFile[] files, OutputSink sink) {
|
||||
final BackendCompiler backEndCompiler = getBackEndCompiler();
|
||||
final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(myProject, Arrays.asList(files), (CompileContextEx)context, backEndCompiler,
|
||||
sink);
|
||||
final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(moduleChunk, myProject, Arrays.asList(files), (CompileContextEx)context, backEndCompiler, sink);
|
||||
try {
|
||||
wrapper.compile();
|
||||
}
|
||||
|
||||
+7
-42
@@ -35,9 +35,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
@@ -49,7 +47,6 @@ public class JarsBuilder {
|
||||
private final FileFilter myFileFilter;
|
||||
private final CompileContext myContext;
|
||||
private Map<JarInfo, File> myBuiltJars;
|
||||
private final List<ExplodedDestinationInfo> myJarsDestinations;
|
||||
private Set<File> myJarsToDelete;
|
||||
|
||||
public JarsBuilder(Set<JarInfo> jarsToBuild, FileFilter fileFilter, CompileContext context) {
|
||||
@@ -60,7 +57,6 @@ public class JarsBuilder {
|
||||
myJarsToBuild = evaluator.getJars();
|
||||
myFileFilter = fileFilter;
|
||||
myContext = context;
|
||||
myJarsDestinations = new ArrayList<ExplodedDestinationInfo>();
|
||||
}
|
||||
|
||||
public boolean buildJars(Set<String> writtenPaths) throws IOException {
|
||||
@@ -87,18 +83,10 @@ public class JarsBuilder {
|
||||
|
||||
private void deleteTemporaryJars() {
|
||||
for (File file : myJarsToDelete) {
|
||||
deleteFile(file);
|
||||
FileUtil.delete(file);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteFile(final File file) {
|
||||
FileUtil.delete(file);
|
||||
}
|
||||
|
||||
public List<ExplodedDestinationInfo> getJarsDestinations() {
|
||||
return myJarsDestinations;
|
||||
}
|
||||
|
||||
private void copyJars(final Set<String> writtenPaths) throws IOException {
|
||||
myJarsToDelete = new HashSet<File>(myBuiltJars.values());
|
||||
|
||||
@@ -107,7 +95,6 @@ public class JarsBuilder {
|
||||
boolean first = true;
|
||||
for (DestinationInfo destination : entry.getKey().getAllDestinations()) {
|
||||
if (destination instanceof ExplodedDestinationInfo) {
|
||||
myJarsDestinations.add((ExplodedDestinationInfo)destination);
|
||||
File toFile = new File(FileUtil.toSystemDependentName(destination.getOutputPath()));
|
||||
|
||||
if (first) {
|
||||
@@ -116,7 +103,7 @@ public class JarsBuilder {
|
||||
fromFile = toFile;
|
||||
}
|
||||
else {
|
||||
copyFile(fromFile, toFile, writtenPaths);
|
||||
DeploymentUtil.getInstance().copyFile(fromFile, toFile, myContext, writtenPaths, myFileFilter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -124,15 +111,11 @@ public class JarsBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
protected void renameFile(final File fromFile, final File toFile, final Set<String> writtenPaths) throws IOException {
|
||||
private static void renameFile(final File fromFile, final File toFile, final Set<String> writtenPaths) throws IOException {
|
||||
FileUtil.rename(fromFile, toFile);
|
||||
writtenPaths.add(toFile.getPath());
|
||||
}
|
||||
|
||||
protected void copyFile(final File fromFile, final File toFile, final Set<String> writtenPaths) throws IOException {
|
||||
DeploymentUtil.getInstance().copyFile(fromFile, toFile, myContext, writtenPaths, myFileFilter);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JarInfo[] sortJars() {
|
||||
final DFSTBuilder<JarInfo> builder = new DFSTBuilder<JarInfo>(GraphGenerator.create(CachingSemiGraph.create(new JarsGraph())));
|
||||
@@ -158,11 +141,11 @@ public class JarsBuilder {
|
||||
private void buildJar(final JarInfo jar) throws IOException {
|
||||
myContext.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.building.0",
|
||||
jar.getPresentableDestination()));
|
||||
File jarFile = createTempFile();
|
||||
File jarFile = FileUtil.createTempFile("artifactCompiler", "tmp");
|
||||
myBuiltJars.put(jar, jarFile);
|
||||
|
||||
Manifest manifest = null;
|
||||
final JarOutputStream jarOutputStream = createJarOutputStream(jarFile, manifest);
|
||||
FileUtil.createParentDirs(jarFile);
|
||||
final JarOutputStream jarOutputStream = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(jarFile)));
|
||||
|
||||
try {
|
||||
final THashSet<String> writtenPaths = new THashSet<String>();
|
||||
@@ -181,25 +164,7 @@ public class JarsBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private static Manifest createManifest(final JarInfo jar) throws IOException {
|
||||
for (Pair<String, VirtualFile> pair : jar.getPackedFiles()) {
|
||||
if (JarFile.MANIFEST_NAME.equalsIgnoreCase(pair.getFirst())) {
|
||||
return new Manifest(pair.getSecond().getInputStream());
|
||||
}
|
||||
}
|
||||
return new Manifest();
|
||||
}
|
||||
|
||||
protected JarOutputStream createJarOutputStream(final File jarFile, final Manifest manifest) throws IOException {
|
||||
FileUtil.createParentDirs(jarFile);
|
||||
return new JarOutputStream(new BufferedOutputStream(new FileOutputStream(jarFile)));
|
||||
}
|
||||
|
||||
protected File createTempFile() throws IOException {
|
||||
return FileUtil.createTempFile("packagingCompiler", "tmp");
|
||||
}
|
||||
|
||||
protected void addFileToJar(final JarOutputStream jarOutputStream, final File file, String relativePath,
|
||||
private void addFileToJar(final JarOutputStream jarOutputStream, final File file, String relativePath,
|
||||
final THashSet<String> writtenPaths) throws IOException {
|
||||
//todo[nik] check file exists?
|
||||
while (relativePath.startsWith("/")) {
|
||||
|
||||
+12
-7
@@ -39,6 +39,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
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;
|
||||
@@ -70,12 +71,13 @@ public class ResourceCompiler implements TranslatingCompiler {
|
||||
return !StdFileTypes.JAVA.equals(FILE_TYPE_MANAGER.getFileTypeByFile(file)) && myConfiguration.isResourceFile(file);
|
||||
}
|
||||
|
||||
public void compile(final CompileContext context, final VirtualFile[] files, OutputSink sink) {
|
||||
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;
|
||||
final long start = System.currentTimeMillis();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
@@ -84,7 +86,7 @@ public class ResourceCompiler implements TranslatingCompiler {
|
||||
if (context.getProgressIndicator().isCanceled()) {
|
||||
break;
|
||||
}
|
||||
final Module module = context.getModuleByFile(file);
|
||||
final Module module = singleChunkModule != null? singleChunkModule : context.getModuleByFile(file);
|
||||
if (module == null) {
|
||||
continue; // looks like file invalidated
|
||||
}
|
||||
@@ -94,17 +96,20 @@ public class ResourceCompiler implements TranslatingCompiler {
|
||||
}
|
||||
final String sourcePath = file.getPath();
|
||||
final String relativePath = VfsUtil.getRelativePath(file, fileRoot, '/');
|
||||
final String outputPath = CompilerPaths.getModuleOutputPath(module, ((CompileContextEx)context).isInTestSourceContent(file));
|
||||
if (outputPath == null) {
|
||||
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;
|
||||
targetPath = outputPath + "/" + packagePrefix.replace('.', '/') + "/" + relativePath;
|
||||
}
|
||||
else {
|
||||
targetPath = outputPath+"/"+relativePath;
|
||||
targetPath = outputPath + "/" + relativePath;
|
||||
}
|
||||
if (sourcePath.equals(targetPath)) {
|
||||
addToMap(processed, outputPath, new MyOutputItem(targetPath, file));
|
||||
@@ -126,7 +131,7 @@ public class ResourceCompiler implements TranslatingCompiler {
|
||||
if (context.getProgressIndicator().isCanceled()) {
|
||||
break;
|
||||
}
|
||||
context.getProgressIndicator().setFraction((idx++) * 1.0 / total);
|
||||
//context.getProgressIndicator().setFraction((idx++) * 1.0 / total);
|
||||
context.getProgressIndicator().setText2("Copying " + command.getFromPath() + "...");
|
||||
try {
|
||||
rootsToRefresh.add(command.getOutputPath());
|
||||
|
||||
@@ -15,16 +15,26 @@
|
||||
*/
|
||||
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.CompilerUtil;
|
||||
import com.intellij.compiler.impl.javaCompiler.DependencyProcessor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
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.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
@@ -116,4 +126,69 @@ public class CacheUtils {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Collection<VirtualFile> findDependentFiles(final CompileContextEx context, final Set<VirtualFile> succesfullyCompiledJavaFiles,
|
||||
final @Nullable DependencyProcessor additionalDependencyProcessor,
|
||||
final @Nullable Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> filter) throws CacheCorruptedException {
|
||||
if (!CompilerConfiguration.MAKE_ENABLED) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
context.getProgressIndicator().setText(CompilerBundle.message("progress.checking.dependencies"));
|
||||
|
||||
final DependencyCache dependencyCache = context.getDependencyCache();
|
||||
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
final Pair<int[], Set<VirtualFile>> deps =
|
||||
dependencyCache.findDependentClasses(context, context.getProject(), succesfullyCompiledJavaFiles, additionalDependencyProcessor);
|
||||
final Pair<int[], Set<VirtualFile>> filteredDeps = filter != null? filter.fun(deps) : deps;
|
||||
|
||||
final Set<VirtualFile> dependentFiles = new HashSet<VirtualFile>();
|
||||
final CacheCorruptedException[] _ex = {null};
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
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);
|
||||
if (file != null) {
|
||||
if (!compilerConfiguration.isExcludedFromCompilation(file)) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
_ex[0] = e;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (_ex[0] != null) {
|
||||
throw _ex[0];
|
||||
}
|
||||
context.getProgressIndicator().setText(CompilerBundle.message("progress.found.dependent.files", dependentFiles.size()));
|
||||
|
||||
CompilerUtil.logDuration("Finding dependencies", System.currentTimeMillis() - start);
|
||||
return dependentFiles;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -150,7 +149,7 @@ public class DependencyCache {
|
||||
}
|
||||
*/
|
||||
|
||||
public void update(ProgressIndicator indicator) throws CacheCorruptedException {
|
||||
public void update() throws CacheCorruptedException {
|
||||
if (myToUpdate.isEmpty()) {
|
||||
return; // optimization
|
||||
}
|
||||
@@ -163,10 +162,8 @@ public class DependencyCache {
|
||||
final Cache newCache = getNewClassesCache();
|
||||
final DependencyCacheNavigator navigator = getCacheNavigator();
|
||||
|
||||
int i = 0;
|
||||
// remove unnecesary dependencies
|
||||
for (final int qName : namesToUpdate) {
|
||||
indicator.setFraction(i++*1.0/namesToUpdate.length/4);
|
||||
// process use-dependencies
|
||||
for (int referencedClassQName : cache.getReferencedClasses(qName)) {
|
||||
if (!cache.containsClass(referencedClassQName)) {
|
||||
@@ -186,7 +183,6 @@ public class DependencyCache {
|
||||
|
||||
// do update of classInfos
|
||||
for (final int qName : namesToUpdate) {
|
||||
indicator.setFraction(i++*1.0/namesToUpdate.length/4);
|
||||
cache.importClassInfo(newCache, qName);
|
||||
}
|
||||
|
||||
@@ -195,7 +191,6 @@ public class DependencyCache {
|
||||
final SymbolTable symbolTable = getSymbolTable();
|
||||
|
||||
for (final int qName : namesToUpdate) {
|
||||
indicator.setFraction(i++*1.0/namesToUpdate.length/4);
|
||||
if (!newCache.containsClass(qName)) {
|
||||
continue;
|
||||
}
|
||||
@@ -223,9 +218,7 @@ public class DependencyCache {
|
||||
|
||||
// building subclass dependencies
|
||||
for (final int qName : namesToUpdate) {
|
||||
indicator.setFraction(i++*1.0/namesToUpdate.length/4);
|
||||
final int classId = qName;
|
||||
buildSubclassDependencies(getCache(), qName, classId);
|
||||
buildSubclassDependencies(getCache(), qName, qName);
|
||||
}
|
||||
|
||||
for (final int qName : myClassesWithSourceRemoved.toArray()) {
|
||||
@@ -410,11 +403,11 @@ public class DependencyCache {
|
||||
LOG.debug("====================Marking dependent files=====================");
|
||||
}
|
||||
// myToUpdate can be modified during the mark procedure, so use toArray() to iterate it
|
||||
int[] qNamesToUpdate = myTraverseRoots.toArray();
|
||||
final int[] traverseRoots = myTraverseRoots.toArray();
|
||||
final SourceFileFinder sourceFileFinder = new SourceFileFinder(project, context);
|
||||
final CachingSearcher searcher = new CachingSearcher(project);
|
||||
final ChangedRetentionPolicyDependencyProcessor changedRetentionPolicyDependencyProcessor = new ChangedRetentionPolicyDependencyProcessor(project, searcher, this);
|
||||
for (final int qName : qNamesToUpdate) {
|
||||
for (final int qName : traverseRoots) {
|
||||
if (!getCache().containsClass(qName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,46 +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: Dec 1, 2008
|
||||
*/
|
||||
public class StorageClassId {
|
||||
private final int myQName;
|
||||
|
||||
public StorageClassId(int QName) {
|
||||
myQName = QName;
|
||||
}
|
||||
|
||||
public int getClassQName() {
|
||||
return myQName;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof StorageClassId)) return false;
|
||||
|
||||
if (myQName != ((StorageClassId)o).myQName) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myQName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +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: Dec 1, 2008
|
||||
*/
|
||||
public final class StorageFieldId extends StorageClassId{
|
||||
private final int myFieldName;
|
||||
|
||||
public StorageFieldId(int QName, int fieldName) {
|
||||
super(QName);
|
||||
myFieldName = fieldName;
|
||||
}
|
||||
|
||||
public int getFieldName() {
|
||||
return myFieldName;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof StorageFieldId)) return false;
|
||||
|
||||
final StorageFieldId that = (StorageFieldId)o;
|
||||
return myFieldName == that.myFieldName && getClassQName() == that.getClassQName();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + myFieldName;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +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: Dec 1, 2008
|
||||
*/
|
||||
public final class StorageMethodId extends StorageClassId{
|
||||
private final int myMethodName;
|
||||
private final int myMethodDescriptor;
|
||||
|
||||
public StorageMethodId(int QName, int methodName, int methodDescriptor) {
|
||||
super(QName);
|
||||
myMethodName = methodName;
|
||||
myMethodDescriptor = methodDescriptor;
|
||||
}
|
||||
|
||||
public int getMethodName() {
|
||||
return myMethodName;
|
||||
}
|
||||
|
||||
public int getMethodDescriptor() {
|
||||
return myMethodDescriptor;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof StorageMethodId)) return false;
|
||||
|
||||
StorageMethodId that = (StorageMethodId)o;
|
||||
return myMethodDescriptor == that.myMethodDescriptor && myMethodName == that.myMethodName && getClassQName() == that.getClassQName();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + myMethodName;
|
||||
result = 31 * result + myMethodDescriptor;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.packaging.impl.compiler;
|
||||
|
||||
import com.intellij.compiler.impl.AdditionalCompileScopeProvider;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerFilter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class ArtifactAdditionalCompileScopeProvider extends AdditionalCompileScopeProvider {
|
||||
@Override
|
||||
public CompileScope getAdditionalScope(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project) {
|
||||
if (ArtifactCompileScope.getArtifacts(baseScope) != null) {
|
||||
return null;
|
||||
}
|
||||
final IncrementalArtifactsCompiler compiler = IncrementalArtifactsCompiler.getInstance(project);
|
||||
if (compiler == null || !filter.acceptCompiler(compiler)) {
|
||||
return null;
|
||||
}
|
||||
final Set<Artifact> artifacts = ArtifactCompileScope.getArtifactsToBuild(project, baseScope);
|
||||
return ArtifactCompileScope.createScopeForModulesInArtifacts(project, artifacts);
|
||||
}
|
||||
}
|
||||
+15
-1
@@ -29,6 +29,7 @@ import com.intellij.packaging.impl.elements.ModuleOutputElementType;
|
||||
import com.intellij.packaging.impl.elements.ModuleOutputPackagingElement;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -40,6 +41,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class ArtifactCompileScope {
|
||||
private static final Key<Artifact[]> ARTIFACTS_KEY = Key.create("artifacts");
|
||||
private static final Key<Set<Artifact>> CACHED_ARTIFACTS_KEY = Key.create("cached_artifacts");
|
||||
|
||||
private ArtifactCompileScope() {
|
||||
}
|
||||
@@ -72,10 +74,16 @@ public class ArtifactCompileScope {
|
||||
}
|
||||
|
||||
public static Set<Artifact> getArtifactsToBuild(final Project project, final CompileScope compileScope) {
|
||||
final Artifact[] artifactsFromScope = compileScope.getUserData(ARTIFACTS_KEY);
|
||||
final Artifact[] artifactsFromScope = getArtifacts(compileScope);
|
||||
if (artifactsFromScope != null) {
|
||||
return new HashSet<Artifact>(Arrays.asList(artifactsFromScope));
|
||||
}
|
||||
|
||||
final Set<Artifact> cached = compileScope.getUserData(CACHED_ARTIFACTS_KEY);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
Set<Artifact> artifacts = new HashSet<Artifact>();
|
||||
final ArtifactManager artifactManager = ArtifactManager.getInstance(project);
|
||||
final Set<Module> modules = new HashSet<Module>(Arrays.asList(compileScope.getAffectedModules()));
|
||||
@@ -87,9 +95,15 @@ public class ArtifactCompileScope {
|
||||
}
|
||||
}
|
||||
}
|
||||
compileScope.putUserData(CACHED_ARTIFACTS_KEY, artifacts);
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Artifact[] getArtifacts(CompileScope compileScope) {
|
||||
return compileScope.getUserData(ARTIFACTS_KEY);
|
||||
}
|
||||
|
||||
private static boolean containsModuleOutput(Artifact artifact, final Set<Module> modules, ArtifactManager artifactManager) {
|
||||
final PackagingElementResolvingContext context = artifactManager.getResolvingContext();
|
||||
return !ArtifactUtil.processPackagingElements(artifact, ModuleOutputElementType.MODULE_OUTPUT_ELEMENT_TYPE,
|
||||
|
||||
+6
@@ -73,6 +73,12 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler {
|
||||
private static final Key<ArtifactsProcessingItemsBuilderContext> BUILDER_CONTEXT_KEY = Key.create("artifacts_builder_context");
|
||||
@Nullable private PackagingCompilerCache myOutputItemsCache;
|
||||
|
||||
@Nullable
|
||||
public static IncrementalArtifactsCompiler getInstance(@NotNull Project project) {
|
||||
final IncrementalArtifactsCompiler[] compilers = CompilerManager.getInstance(project).getCompilers(IncrementalArtifactsCompiler.class);
|
||||
return compilers.length == 1 ? compilers[0] : null;
|
||||
}
|
||||
|
||||
private static ArtifactPackagingProcessingItem[] collectItems(ArtifactsProcessingItemsBuilderContext builderContext, final Project project) {
|
||||
final CompileContext context = builderContext.getCompileContext();
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package com.intellij.openapi.compiler;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Chunk;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -63,7 +65,7 @@ public interface TranslatingCompiler extends Compiler {
|
||||
* @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.openapi.vfs.VirtualFile[], com.intellij.openapi.compiler.TranslatingCompiler.OutputSink)}.
|
||||
* will not be included in the list of files passed to {@link #compile(CompileContext,Chunk<Module>,com.intellij.openapi.vfs.VirtualFile[], com.intellij.openapi.compiler.TranslatingCompiler.OutputSink)}.
|
||||
*/
|
||||
boolean isCompilableFile(VirtualFile file, CompileContext context);
|
||||
|
||||
@@ -71,8 +73,9 @@ public interface TranslatingCompiler extends Compiler {
|
||||
* Compiles the specified files.
|
||||
*
|
||||
* @param context the context for the current compile operation.
|
||||
* @param files the source files to compile.
|
||||
* @param moduleChunk contains modules that form a cycle. If project module graph has no cycles, a chunk corresponds to a single module
|
||||
* @param files the source files to compile that correspond to the module chunk
|
||||
* @param sink storage that accepts compiler output results
|
||||
*/
|
||||
void compile(CompileContext context, VirtualFile[] files, OutputSink sink);
|
||||
void compile(CompileContext context, Chunk<Module> moduleChunk, VirtualFile[] files, OutputSink sink);
|
||||
}
|
||||
|
||||
+19
-18
@@ -44,6 +44,7 @@ import com.intellij.openapi.util.WriteExternalException;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AbstractRerunFailedTestsAction extends AnAction {
|
||||
@@ -122,18 +123,16 @@ public class AbstractRerunFailedTestsAction extends AnAction {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static abstract class MyRunProfile implements ModuleRunProfile, RunConfiguration {
|
||||
private final RunConfiguration myConfiguration;
|
||||
protected static abstract class MyRunProfile extends RunConfigurationBase implements ModuleRunProfile{
|
||||
private final RunConfigurationBase myConfiguration;
|
||||
|
||||
public MyRunProfile(RunConfiguration configuration) {
|
||||
public MyRunProfile(RunConfigurationBase configuration) {
|
||||
super(configuration.getProject(), configuration.getFactory(), ActionsBundle.message("action.RerunFailedTests.text"));
|
||||
myConfiguration = configuration;
|
||||
}
|
||||
|
||||
public void clear() { }
|
||||
|
||||
public String getName() {
|
||||
return ActionsBundle.message("action.RerunFailedTests.text");
|
||||
}
|
||||
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {}
|
||||
|
||||
@@ -146,22 +145,10 @@ public class AbstractRerunFailedTestsAction extends AnAction {
|
||||
myConfiguration.writeExternal(element);
|
||||
}
|
||||
|
||||
public ConfigurationFactory getFactory() {
|
||||
return myConfiguration.getFactory();
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
myConfiguration.setName(name);
|
||||
}
|
||||
|
||||
public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
|
||||
return myConfiguration.getConfigurationEditor();
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myConfiguration.getProject();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigurationType getType() {
|
||||
return myConfiguration.getType();
|
||||
@@ -183,6 +170,20 @@ public class AbstractRerunFailedTestsAction extends AnAction {
|
||||
return myConfiguration.getUniqueID();
|
||||
}
|
||||
|
||||
public LogFileOptions getOptionsForPredefinedLogFile(PredefinedLogFile predefinedLogFile) {
|
||||
return myConfiguration.getOptionsForPredefinedLogFile(predefinedLogFile);
|
||||
}
|
||||
|
||||
public ArrayList<PredefinedLogFile> getPredefinedLogFiles() {
|
||||
return myConfiguration.getPredefinedLogFiles();
|
||||
}
|
||||
|
||||
public ArrayList<LogFileOptions> getAllLogFiles() {
|
||||
return myConfiguration.getAllLogFiles();
|
||||
}
|
||||
|
||||
public ArrayList<LogFileOptions> getLogFiles() {
|
||||
return myConfiguration.getLogFiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,11 +213,11 @@ public class ClasspathEditor extends ModuleElementsEditor implements ModuleRootL
|
||||
return ClasspathStorage.getStorageType(getModel().getModule());
|
||||
}
|
||||
|
||||
boolean isModified () {
|
||||
boolean isModified() {
|
||||
return cbClasspathFormat != null && !getSelectedClasspathFormat().equals(getModuleClasspathFormat());
|
||||
}
|
||||
|
||||
void apply () throws ConfigurationException {
|
||||
void apply() throws ConfigurationException {
|
||||
final String storageID = getSelectedClasspathFormat();
|
||||
ClasspathStorage.getProvider(storageID).assertCompatible(getModel());
|
||||
ClasspathStorage.setStorageType(getModel(), storageID);
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.StdModuleTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.*;
|
||||
@@ -83,7 +82,7 @@ public class ClasspathPanel extends JPanel {
|
||||
private PopupAction[] myPopupActions = null;
|
||||
private Icon[] myIcons = null;
|
||||
private JButton myEditButton;
|
||||
private ModuleConfigurationState myState;
|
||||
private final ModuleConfigurationState myState;
|
||||
|
||||
protected ClasspathPanel(ModuleConfigurationState state) {
|
||||
super(new BorderLayout());
|
||||
@@ -322,7 +321,7 @@ public class ClasspathPanel extends JPanel {
|
||||
removeButton.addActionListener(new ButtonAction() {
|
||||
protected void executeImpl() {
|
||||
final List removedRows = TableUtil.removeSelectedItems(myEntryTable);
|
||||
if (removedRows.size() == 0) {
|
||||
if (removedRows.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (final Object removedRow : removedRows) {
|
||||
@@ -475,13 +474,12 @@ public class ClasspathPanel extends JPanel {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final List<ItemType> chosen;
|
||||
dialog.doChoose();
|
||||
if (!dialog.isOK()) {
|
||||
return;
|
||||
}
|
||||
chosen = dialog.getChosenElements();
|
||||
if (chosen.size() == 0) {
|
||||
final List<ItemType> chosen = dialog.getChosenElements();
|
||||
if (chosen.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final ModuleStructureConfigurable rootConfigurable = ModuleStructureConfigurable.getInstance(myState.getProject());
|
||||
@@ -512,7 +510,8 @@ public class ClasspathPanel extends JPanel {
|
||||
@Nullable
|
||||
protected abstract TableItem createTableItem(final ItemType item);
|
||||
|
||||
protected abstract @Nullable ChooserDialog<ItemType> createChooserDialog();
|
||||
@Nullable
|
||||
protected abstract ChooserDialog<ItemType> createChooserDialog();
|
||||
}
|
||||
|
||||
private void initPopupActions() {
|
||||
@@ -572,7 +571,7 @@ public class ClasspathPanel extends JPanel {
|
||||
}
|
||||
protected ChooserDialog<Module> createChooserDialog() {
|
||||
final List<Module> chooseItems = getDependencyModules();
|
||||
if (chooseItems.size() == 0) {
|
||||
if (chooseItems.isEmpty()) {
|
||||
Messages.showMessageDialog(ClasspathPanel.this, ProjectBundle.message("message.no.module.dependency.candidates"), getTitle(), Messages.getInformationIcon());
|
||||
return null;
|
||||
}
|
||||
@@ -615,7 +614,8 @@ public class ClasspathPanel extends JPanel {
|
||||
myEntryTable.getCellEditor().stopCellEditing();
|
||||
}
|
||||
final ListSelectionModel selectionModel = myEntryTable.getSelectionModel();
|
||||
for(int row = increment < 0? 0 : myModel.getRowCount() - 1; increment < 0? row < myModel.getRowCount() : row >= 0; row += (increment < 0? +1 : -1)){
|
||||
for(int row = increment < 0? 0 : myModel.getRowCount() - 1; increment < 0? row < myModel.getRowCount() : row >= 0; row +=
|
||||
increment < 0? +1 : -1){
|
||||
if (selectionModel.isSelectedIndex(row)) {
|
||||
final int newRow = moveRow(row, increment);
|
||||
selectionModel.removeSelectionInterval(row, row);
|
||||
@@ -703,8 +703,8 @@ public class ClasspathPanel extends JPanel {
|
||||
}
|
||||
|
||||
|
||||
private static abstract class TableItem<T extends OrderEntry> {
|
||||
protected @Nullable T myEntry;
|
||||
private abstract static class TableItem<T extends OrderEntry> {
|
||||
@Nullable protected final T myEntry;
|
||||
|
||||
protected TableItem(@Nullable T entry) {
|
||||
myEntry = entry;
|
||||
@@ -715,12 +715,12 @@ public class ClasspathPanel extends JPanel {
|
||||
}
|
||||
|
||||
public final boolean isExported() {
|
||||
return isExportable() && myEntry != null && ((ExportableOrderEntry)myEntry).isExported();
|
||||
return isExportable() && ((ExportableOrderEntry)getEntry()).isExported();
|
||||
}
|
||||
|
||||
public final void setExported(boolean isExported) {
|
||||
if (isExportable() && myEntry != null) {
|
||||
((ExportableOrderEntry)myEntry).setExported(isExported);
|
||||
if (isExportable()) {
|
||||
((ExportableOrderEntry)getEntry()).setExported(isExported);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@ public class ClasspathPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
public final @Nullable T getEntry() {
|
||||
public final T getEntry() {
|
||||
return myEntry;
|
||||
}
|
||||
|
||||
@@ -807,7 +807,7 @@ public class ClasspathPanel extends JPanel {
|
||||
public static final int ITEM_COLUMN = 1;
|
||||
public static final int SCOPE_COLUMN = 2;
|
||||
private final List<TableItem> myItems = new ArrayList<TableItem>();
|
||||
private ModuleConfigurationState myState;
|
||||
private final ModuleConfigurationState myState;
|
||||
|
||||
public MyTableModel(final ModuleConfigurationState state) {
|
||||
myState = state;
|
||||
@@ -834,16 +834,16 @@ public class ClasspathPanel extends JPanel {
|
||||
|
||||
private void addOrderEntry(OrderEntry orderEntry) {
|
||||
if (orderEntry instanceof JdkOrderEntry) {
|
||||
addItem(new JdkItem(((JdkOrderEntry)orderEntry)));
|
||||
addItem(new JdkItem((JdkOrderEntry)orderEntry));
|
||||
}
|
||||
else if (orderEntry instanceof LibraryOrderEntry) {
|
||||
addItem(new LibItem(((LibraryOrderEntry)orderEntry)));
|
||||
addItem(new LibItem((LibraryOrderEntry)orderEntry));
|
||||
}
|
||||
else if (orderEntry instanceof ModuleOrderEntry) {
|
||||
addItem(new ModuleItem(((ModuleOrderEntry)orderEntry)));
|
||||
addItem(new ModuleItem((ModuleOrderEntry)orderEntry));
|
||||
}
|
||||
else if (orderEntry instanceof ModuleSourceOrderEntry) {
|
||||
addItem(new SelfModuleItem(((ModuleSourceOrderEntry)orderEntry)));
|
||||
addItem(new SelfModuleItem((ModuleSourceOrderEntry)orderEntry));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1054,7 +1054,7 @@ public class ClasspathPanel extends JPanel {
|
||||
private static class ChooseModuleLibrariesDialog extends LibraryFileChooser implements ChooserDialog<Library> {
|
||||
private Pair<String, VirtualFile[]> myLastChosen;
|
||||
private final LibraryTable myLibraryTable;
|
||||
private final @Nullable VirtualFile myFileToSelect;
|
||||
@Nullable private final VirtualFile myFileToSelect;
|
||||
|
||||
public ChooseModuleLibrariesDialog(Component parent, final LibraryTable libraryTable, final VirtualFile fileToSelect) {
|
||||
super(createFileChooserDescriptor(parent), parent, false, null);
|
||||
@@ -1166,8 +1166,6 @@ public class ClasspathPanel extends JPanel {
|
||||
public List<Library> getChosenElements() {
|
||||
final List<Library> chosen = new ArrayList<Library>(Arrays.asList(myEditor.getSelectedLibraries()));
|
||||
chosen.removeAll(getAlreadyAddedLibraries());
|
||||
final Module module = getRootModel().getModule();
|
||||
final Project project = module.getProject();
|
||||
return chosen;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public class JavaContentEntriesEditor extends CommonContentEntriesEditor {
|
||||
@Override
|
||||
protected List<ContentEntry> addContentEntries(VirtualFile[] files) {
|
||||
List<ContentEntry> contentEntries = super.addContentEntries(files);
|
||||
if (contentEntries.size() > 0) {
|
||||
if (!contentEntries.isEmpty()) {
|
||||
final ContentEntry[] contentEntriesArray = contentEntries.toArray(new ContentEntry[contentEntries.size()]);
|
||||
addSourceRoots(myProject, contentEntriesArray, new Runnable() {
|
||||
public void run() {
|
||||
|
||||
+6
-8
@@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorEx;
|
||||
import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorImpl;
|
||||
import com.intellij.openapi.roots.ui.configuration.artifacts.sourceItems.SourceItemsTree;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
@@ -100,10 +101,7 @@ public class PutSourceItemIntoParentAndLinkViaManifestAction extends PutIntoDefa
|
||||
final Artifact artifact = parentsInfo.getGrandparentArtifact();
|
||||
final ArtifactEditorContext context = myArtifactEditor.getContext();
|
||||
//todo[nik] improve
|
||||
final Runnable emptyRunnable = new Runnable() {
|
||||
public void run() {
|
||||
}
|
||||
};
|
||||
final Runnable emptyRunnable = EmptyRunnable.getInstance();
|
||||
context.editLayout(artifact, emptyRunnable);
|
||||
context.editLayout(parentsInfo.getParentArtifact(), emptyRunnable);
|
||||
parentsInfo = findParentAndGrandParent(myArtifactEditor.getArtifact());//find elements under modifiable root
|
||||
@@ -134,10 +132,10 @@ public class PutSourceItemIntoParentAndLinkViaManifestAction extends PutIntoDefa
|
||||
}
|
||||
|
||||
private static class ParentElementsInfo {
|
||||
private Artifact myParentArtifact;
|
||||
private CompositePackagingElement<?> myParentElement;
|
||||
private Artifact myGrandparentArtifact;
|
||||
private CompositePackagingElement<?> myGrandparentElement;
|
||||
private final Artifact myParentArtifact;
|
||||
private final CompositePackagingElement<?> myParentElement;
|
||||
private final Artifact myGrandparentArtifact;
|
||||
private final CompositePackagingElement<?> myGrandparentElement;
|
||||
|
||||
private ParentElementsInfo(Artifact parentArtifact,
|
||||
CompositePackagingElement<?> parentElement,
|
||||
|
||||
+5
@@ -457,6 +457,11 @@ public String getAccessorsVisibility() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (getCheckedRows().length == 0) {
|
||||
CommonRefactoringUtil.showErrorMessage(REFACTORING_NAME, "Nothing found to encapsulate", HelpID.ENCAPSULATE_FIELDS, myProject);
|
||||
return;
|
||||
}
|
||||
|
||||
invokeRefactoring(new EncapsulateFieldsProcessor(myProject, this));
|
||||
JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
|
||||
settings.ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE = myCbUseAccessorsWhenAccessible.isSelected();
|
||||
|
||||
+5
@@ -106,6 +106,11 @@ public class EncapsulateFieldsHandler implements RefactoringActionHandler {
|
||||
}
|
||||
|
||||
LOG.assertTrue(aClass != null);
|
||||
final PsiField[] fields = aClass.getFields();
|
||||
if (fields.length == 0) {
|
||||
CommonRefactoringUtil.showErrorHint(project, PlatformDataKeys.EDITOR.getData(dataContext), "Class has no fields to encapsulate", REFACTORING_NAME, HelpID.ENCAPSULATE_FIELDS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aClass.isInterface()) {
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("encapsulate.fields.refactoring.cannot.be.applied.to.interface"));
|
||||
|
||||
+8
-5
@@ -79,8 +79,11 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor {
|
||||
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
|
||||
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
|
||||
|
||||
checkExistingMethods(myDescriptor.getGetterPrototypes(), conflicts, true);
|
||||
checkExistingMethods(myDescriptor.getSetterPrototypes(), conflicts, false);
|
||||
final PsiMethod[] getterPrototypes = myDescriptor.getGetterPrototypes();
|
||||
final PsiMethod[] setterPrototypes = myDescriptor.getSetterPrototypes();
|
||||
|
||||
checkExistingMethods(getterPrototypes, conflicts, true);
|
||||
checkExistingMethods(setterPrototypes, conflicts, false);
|
||||
final Collection<PsiClass> classes = ClassInheritorsSearch.search(myClass).findAll();
|
||||
for (int i = 0; i < myFields.length; i++) {
|
||||
final PsiField field = myFields[i];
|
||||
@@ -88,11 +91,11 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor {
|
||||
final Set<PsiMethod> getters = new HashSet<PsiMethod>();
|
||||
|
||||
for (PsiClass aClass : classes) {
|
||||
final PsiMethod getterOverrider = aClass.findMethodBySignature(myDescriptor.getGetterPrototypes()[i], false);
|
||||
final PsiMethod getterOverrider = getterPrototypes != null ? aClass.findMethodBySignature(getterPrototypes[i], false) : null;
|
||||
if (getterOverrider != null) {
|
||||
getters.add(getterOverrider);
|
||||
}
|
||||
final PsiMethod setterOverrider = aClass.findMethodBySignature(myDescriptor.getSetterPrototypes()[i], false);
|
||||
final PsiMethod setterOverrider = setterPrototypes != null ? aClass.findMethodBySignature(setterPrototypes[i], false) : null;
|
||||
if (setterOverrider != null) {
|
||||
setters.add(setterOverrider);
|
||||
}
|
||||
@@ -534,7 +537,7 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor {
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
if(containingClass.isInheritor(myClass, false)) {
|
||||
if(containingClass != null && containingClass.isInheritor(myClass, false)) {
|
||||
final PsiExpression newMethodExpression =
|
||||
factory.createExpressionFromText("super." + targetMethod.getName(), context);
|
||||
methodCall.getMethodExpression().replace(newMethodExpression);
|
||||
|
||||
+45
-5
@@ -34,13 +34,13 @@ import com.intellij.refactoring.memberPushDown.PushDownProcessor;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.FixableUsageInfo;
|
||||
import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfoStorage;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.Processor;import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -79,6 +79,7 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject);
|
||||
final PsiElementFactory elementFactory = facade.getElementFactory();
|
||||
final PsiResolveHelper resolveHelper = facade.getResolveHelper();
|
||||
|
||||
ReferencesSearch.search(mySuperClass).forEach(new Processor<PsiReference>() {
|
||||
public boolean process(final PsiReference reference) {
|
||||
final PsiElement element = reference.getElement();
|
||||
@@ -134,12 +135,14 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori
|
||||
for (PsiReference reference : ReferencesSearch.search(member, member.getUseScope(), true)) {
|
||||
final PsiElement element = reference.getElement();
|
||||
if (element instanceof PsiReferenceExpression &&
|
||||
((PsiReferenceExpression)element).getQualifierExpression() instanceof PsiSuperExpression && PsiTreeUtil.isAncestor(
|
||||
targetClass, element, false)) {
|
||||
((PsiReferenceExpression)element).getQualifierExpression() instanceof PsiSuperExpression &&
|
||||
PsiTreeUtil.isAncestor(targetClass, element, false)) {
|
||||
usages.add(new RemoveQualifierUsageInfo((PsiReferenceExpression)element));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final PsiMethod[] superConstructors = mySuperClass.getConstructors();
|
||||
for (PsiMethod constructor : targetClass.getConstructors()) {
|
||||
final PsiCodeBlock constrBody = constructor.getBody();
|
||||
LOG.assertTrue(constrBody != null);
|
||||
@@ -154,11 +157,30 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori
|
||||
final PsiMethod superConstructor = ((PsiMethodCallExpression)expression).resolveMethod();
|
||||
if (superConstructor != null && superConstructor.getBody() != null) {
|
||||
usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//insert implicit call to super
|
||||
for (PsiMethod superConstructor : superConstructors) {
|
||||
if (superConstructor.getParameterList().getParametersCount() == 0) {
|
||||
final PsiExpression expression = JavaPsiFacade.getElementFactory(myProject).createExpressionFromText("super()", constructor);
|
||||
usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression, constrBody));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetClass.getConstructors().length == 0) {
|
||||
//copy default constructor
|
||||
for (PsiMethod superConstructor : superConstructors) {
|
||||
if (superConstructor.getParameterList().getParametersCount() == 0) {
|
||||
usages.add(new CopyDefaultConstructorUsageInfo(targetClass, superConstructor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,7 +213,25 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori
|
||||
}
|
||||
}.run();
|
||||
replaceInnerTypeUsages();
|
||||
super.performRefactoring(usages);
|
||||
|
||||
RefactoringUtil.sortDepthFirstRightLeftOrder(usages);
|
||||
for (UsageInfo usageInfo : usages) {
|
||||
if (!(usageInfo instanceof ReplaceExtendsListUsageInfo)) {
|
||||
try {
|
||||
((FixableUsageInfo)usageInfo).fixUsage();
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//postpone broken hierarchy
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage instanceof ReplaceExtendsListUsageInfo) {
|
||||
((ReplaceExtendsListUsageInfo)usage).fixUsage();
|
||||
}
|
||||
}
|
||||
try {
|
||||
mySuperClass.delete();
|
||||
}
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* User: anna
|
||||
* Date: 27-Aug-2008
|
||||
*/
|
||||
package com.intellij.refactoring.inlineSuperClass.usageInfo;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiCodeBlock;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.refactoring.util.FixableUsageInfo;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
public class CopyDefaultConstructorUsageInfo extends FixableUsageInfo{
|
||||
private final PsiClass myTargetClass;
|
||||
private final PsiMethod myConstructor;
|
||||
|
||||
|
||||
public CopyDefaultConstructorUsageInfo(PsiClass targetClass, PsiMethod constructor) {
|
||||
super(targetClass);
|
||||
myTargetClass = targetClass;
|
||||
myConstructor = constructor;
|
||||
}
|
||||
|
||||
public void fixUsage() throws IncorrectOperationException {
|
||||
final PsiCodeBlock body = myConstructor.getBody();
|
||||
assert body != null;
|
||||
if (body.getFirstBodyElement() != null) { //do not copy empty constructor
|
||||
myTargetClass.add(myConstructor.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -34,14 +34,25 @@ import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class InlineSuperCallUsageInfo extends FixableUsageInfo {
|
||||
private PsiCodeBlock myConstrBody;
|
||||
|
||||
public InlineSuperCallUsageInfo(PsiMethodCallExpression methodCallExpression) {
|
||||
super(methodCallExpression);
|
||||
}
|
||||
|
||||
public InlineSuperCallUsageInfo(PsiMethodCallExpression methodCallExpression, PsiCodeBlock constrBody) {
|
||||
super(methodCallExpression);
|
||||
myConstrBody = constrBody;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixUsage() throws IncorrectOperationException {
|
||||
final PsiElement element = getElement();
|
||||
PsiElement element = getElement();
|
||||
if (element != null && myConstrBody != null) {
|
||||
assert !element.isPhysical();
|
||||
final PsiStatement statement = JavaPsiFacade.getElementFactory(getProject()).createStatementFromText("super();", myConstrBody);
|
||||
element = ((PsiExpressionStatement)myConstrBody.addBefore(statement, myConstrBody.getFirstBodyElement())).getExpression();
|
||||
}
|
||||
if (element instanceof PsiMethodCallExpression) {
|
||||
PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)element).getMethodExpression();
|
||||
final PsiMethod superConstructor = (PsiMethod)methodExpression.resolve();
|
||||
|
||||
@@ -24,12 +24,8 @@
|
||||
*/
|
||||
package com.intellij.refactoring.memberPullUp;
|
||||
|
||||
import com.intellij.history.LocalHistory;
|
||||
import com.intellij.history.LocalHistoryAction;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
@@ -43,12 +39,9 @@ import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import com.intellij.refactoring.ui.ConflictsDialog;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfoStorage;
|
||||
import com.intellij.usageView.UsageViewUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -145,44 +138,9 @@ public class JavaPullUpHandler implements RefactoringActionHandler, PullUpDialog
|
||||
|
||||
|
||||
dialog.show();
|
||||
|
||||
if (!dialog.isOK()) return;
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
final Runnable action = new Runnable() {
|
||||
public void run() {
|
||||
doRefactoring(dialog);
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().runWriteAction(action);
|
||||
}
|
||||
}, REFACTORING_NAME, null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void doRefactoring(PullUpDialog dialog) {
|
||||
LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName());
|
||||
try {
|
||||
try {
|
||||
PullUpHelper helper = new PullUpHelper(mySubclass, dialog.getSuperClass(), dialog.getSelectedMemberInfos(),
|
||||
new DocCommentPolicy(dialog.getJavaDocPolicy()));
|
||||
helper.moveMembersToBase();
|
||||
helper.moveFieldInitializations();
|
||||
}
|
||||
finally {
|
||||
a.finish();
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getCommandName() {
|
||||
return RefactoringBundle.message("pullUp.command", UsageViewUtil.getDescriptiveName(mySubclass));
|
||||
}
|
||||
|
||||
public boolean checkConflicts(PullUpDialog dialog) {
|
||||
final MemberInfo[] infos = dialog.getSelectedMemberInfos();
|
||||
|
||||
@@ -26,8 +26,8 @@ package com.intellij.refactoring.memberPullUp;
|
||||
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
@@ -35,6 +35,8 @@ import com.intellij.refactoring.classMembers.MemberInfoChange;
|
||||
import com.intellij.refactoring.ui.ClassCellRenderer;
|
||||
import com.intellij.refactoring.ui.DocCommentPanel;
|
||||
import com.intellij.refactoring.ui.MemberSelectionPanel;
|
||||
import com.intellij.refactoring.ui.RefactoringDialog;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
@@ -51,7 +53,7 @@ import java.awt.event.ItemListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PullUpDialog extends DialogWrapper {
|
||||
public class PullUpDialog extends RefactoringDialog {
|
||||
private final Callback myCallback;
|
||||
private MemberSelectionPanel myMemberSelectionPanel;
|
||||
private MyMemberInfoModel myMemberInfoModel;
|
||||
@@ -174,9 +176,12 @@ public class PullUpDialog extends DialogWrapper {
|
||||
}*/
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
protected void doAction() {
|
||||
if (!myCallback.checkConflicts(this)) return;
|
||||
JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
|
||||
|
||||
invokeRefactoring(new PullUpHelper(myClass, getSuperClass(), getSelectedMemberInfos(),
|
||||
new DocCommentPolicy(getJavaDocPolicy())));
|
||||
close(OK_EXIT_CODE);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,21 +40,28 @@ import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.listeners.JavaRefactoringListenerManager;
|
||||
import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUIUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import com.intellij.usageView.UsageViewUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PullUpHelper {
|
||||
public class PullUpHelper extends BaseRefactoringProcessor{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHelper");
|
||||
private final PsiClass mySourceClass;
|
||||
private final PsiClass myTargetSuperClass;
|
||||
@@ -67,6 +74,7 @@ public class PullUpHelper {
|
||||
|
||||
public PullUpHelper(PsiClass sourceClass, PsiClass targetSuperClass, MemberInfo[] membersToMove,
|
||||
DocCommentPolicy javaDocPolicy) {
|
||||
super(sourceClass.getProject());
|
||||
mySourceClass = sourceClass;
|
||||
myTargetSuperClass = targetSuperClass;
|
||||
myMembersToMove = membersToMove;
|
||||
@@ -75,6 +83,27 @@ public class PullUpHelper {
|
||||
myManager = mySourceClass.getManager();
|
||||
}
|
||||
|
||||
protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
|
||||
return new PullUpUsageViewDescriptor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected UsageInfo[] findUsages() {
|
||||
return new UsageInfo[0];
|
||||
}
|
||||
|
||||
protected void refreshElements(PsiElement[] elements) {
|
||||
}
|
||||
|
||||
protected void performRefactoring(UsageInfo[] usages) {
|
||||
moveMembersToBase();
|
||||
moveFieldInitializations();
|
||||
}
|
||||
|
||||
protected String getCommandName() {
|
||||
return RefactoringBundle.message("pullUp.command", UsageViewUtil.getDescriptiveName(mySourceClass));
|
||||
}
|
||||
|
||||
public void moveMembersToBase()
|
||||
throws IncorrectOperationException {
|
||||
final HashSet<PsiMember> movedMembers = new HashSet<PsiMember>();
|
||||
@@ -743,4 +772,22 @@ public class PullUpHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
private class PullUpUsageViewDescriptor implements UsageViewDescriptor {
|
||||
public String getProcessedElementsHeader() {
|
||||
return "Pull up members from";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement[] getElements() {
|
||||
return new PsiElement[]{mySourceClass};
|
||||
}
|
||||
|
||||
public String getCodeReferencesText(int usagesCount, int filesCount) {
|
||||
return "Class to pull up members to \"" + RefactoringUIUtil.getDescription(myTargetSuperClass, true) + "\"";
|
||||
}
|
||||
|
||||
public String getCommentReferencesText(int usagesCount, int filesCount) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -26,6 +26,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
@@ -108,6 +109,8 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
|
||||
final ActionListener enableDisableListener = new ActionListener() {
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
setEnabled(myCreateBuilderClassRadioButton.isSelected());
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(
|
||||
myCreateBuilderClassRadioButton.isSelected() ? myNewClassName : myExistentClassTF.getChildComponent(), true);
|
||||
validateButtons();
|
||||
}
|
||||
};
|
||||
@@ -209,7 +212,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
|
||||
};
|
||||
|
||||
myPackageTextField =
|
||||
new PackageNameReferenceEditorCombo("", myProject, RECENT_KEYS, RefactoringBundle.message("choose.destination.package"));
|
||||
new PackageNameReferenceEditorCombo(((PsiJavaFile)myConstructors[0].getContainingFile()).getPackageName(), myProject, RECENT_KEYS, RefactoringBundle.message("choose.destination.package"));
|
||||
myPackageTextField.getChildComponent().getDocument().addDocumentListener(adapter);
|
||||
|
||||
|
||||
@@ -307,7 +310,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
|
||||
case PARAM:
|
||||
return "Parameter";
|
||||
case FIELD:
|
||||
return "Fieled Name";
|
||||
return "Field Name";
|
||||
case SETTER:
|
||||
return "Setter Name";
|
||||
case DEFAULT_VALUE:
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public class ReplaceConstructorWithSettersChainInfo extends FixableUsageInfo {
|
||||
final PsiParameter[] parameters = constructor.getParameterList().getParameters();
|
||||
|
||||
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(constructor.getProject());
|
||||
for (int i = 0; i < constructor.getParameterList().getParametersCount(); i++) {
|
||||
for (int i = 0; i < Math.min(constructor.getParameterList().getParametersCount(), args.length); i++) {
|
||||
String arg = args[i].getText();
|
||||
if (parameters[i].isVarArgs()) {
|
||||
for(int ia = i + 1; ia < args.length; ia++) {
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
Test() {
|
||||
System.out.println("Super");
|
||||
System.out.println("Test");
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Super {
|
||||
Super() {
|
||||
System.out.println("Super");
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Test extends Super{
|
||||
Test() {
|
||||
System.out.println("Test");
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
class Test {
|
||||
Test(String s){super(s);}
|
||||
Test(String s){
|
||||
}
|
||||
|
||||
void foo() {
|
||||
Test s = new Test("");
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
|
||||
Test() {
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Super {
|
||||
Super() {
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Test extends Super{
|
||||
|
||||
}
|
||||
+4
-2
@@ -2,8 +2,10 @@ class Test {
|
||||
String s;
|
||||
|
||||
Test(String s){
|
||||
super(s);
|
||||
System.out.println("hello");
|
||||
if (s != null) {
|
||||
this.s = s;
|
||||
}
|
||||
System.out.println("hello");
|
||||
}
|
||||
|
||||
void foo() {
|
||||
|
||||
+1
@@ -3,5 +3,6 @@ public class Test {
|
||||
void foo(){}
|
||||
public static void main(String[] args){
|
||||
new Builder().setI(1, 2, 3).createTest().foo();
|
||||
new Builder().createTest().foo();
|
||||
}
|
||||
}
|
||||
+1
@@ -3,5 +3,6 @@ public class Test {
|
||||
void foo(){}
|
||||
public static void main(String[] args){
|
||||
new Test(1, 2, 3).foo();
|
||||
new Test().foo();
|
||||
}
|
||||
}
|
||||
@@ -147,6 +147,14 @@ public class InlineSuperClassTest extends MultiFileTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testChildConstructorImplicitlyCallsSuper() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoChildConstructorCallsSuperDefault() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testMultipleSubclasses() throws Exception {
|
||||
doTest(new PerformAction() {
|
||||
public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception {
|
||||
|
||||
@@ -91,8 +91,7 @@ public class PullUpTest extends LightCodeInsightTestCase {
|
||||
};
|
||||
JavaRefactoringListenerManager.getInstance(getProject()).addMoveMembersListener(listener);
|
||||
final PullUpHelper helper = new PullUpHelper(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS));
|
||||
helper.moveMembersToBase();
|
||||
helper.moveFieldInitializations();
|
||||
helper.run();
|
||||
JavaRefactoringListenerManager.getInstance(getProject()).removeMoveMembersListener(listener);
|
||||
assertEquals(countMoved[0], membersToFind.length);
|
||||
checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.List;
|
||||
*/
|
||||
public class AnnotationOrderRootType extends PersistentOrderRootType {
|
||||
/**
|
||||
* External annotations path
|
||||
* @return External annotations path
|
||||
*/
|
||||
public static OrderRootType getInstance() {
|
||||
return getOrderRootType(AnnotationOrderRootType.class);
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ProblemsHolder {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ProblemsHolder");
|
||||
private final InspectionManager myManager;
|
||||
private final PsiFile myFile;
|
||||
private boolean myOnTheFly;
|
||||
private final boolean myOnTheFly;
|
||||
private List<ProblemDescriptor> myProblems = null;
|
||||
|
||||
public ProblemsHolder(@NotNull InspectionManager manager, @NotNull PsiFile file, boolean onTheFly) {
|
||||
@@ -63,7 +63,13 @@ public class ProblemsHolder {
|
||||
}
|
||||
PsiElement element = problemDescriptor.getPsiElement();
|
||||
if (element != null && !isInPsiFile(element)) {
|
||||
LOG.error("Reported element " + element + " is not from the file '" + myFile + "' the inspection was invoked for. Message:" + problemDescriptor.getDescriptionTemplate());
|
||||
PsiFile containingFile = element.getContainingFile();
|
||||
PsiElement context = containingFile.getContext();
|
||||
PsiElement myContext = myFile.getContext();
|
||||
LOG.error("Reported element " + element + " is not from the file '" + myFile + "' the inspection was invoked for. Message: '" + problemDescriptor.getDescriptionTemplate()+"'.\n" +
|
||||
"Element' containing file: "+ containingFile +"; context: "+(context == null ? null : context.getContainingFile())+"\n"
|
||||
+"Inspection invoked for file: "+ myFile +"; context: "+(myContext == null ? null : myContext.getContainingFile())+"\n"
|
||||
);
|
||||
}
|
||||
myProblems.add(problemDescriptor);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public abstract class ProjectJdkTable {
|
||||
|
||||
public abstract void updateJdk(Sdk originalJdk, Sdk modifiedJdk);
|
||||
|
||||
public static interface Listener extends EventListener {
|
||||
public interface Listener extends EventListener {
|
||||
void jdkAdded(Sdk jdk);
|
||||
|
||||
void jdkRemoved(Sdk jdk);
|
||||
|
||||
@@ -19,10 +19,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Root types that can be queried from OrderEntry.
|
||||
@@ -111,13 +108,22 @@ public class OrderRootType {
|
||||
}
|
||||
|
||||
protected static <T> T getOrderRootType(final Class<? extends T> orderRootTypeClass) {
|
||||
for(OrderRootType rootType: Extensions.getExtensions(EP_NAME)) {
|
||||
OrderRootType[] rootTypes = Extensions.getExtensions(EP_NAME);
|
||||
for(OrderRootType rootType: rootTypes) {
|
||||
if (orderRootTypeClass.isInstance(rootType)) {
|
||||
//noinspection unchecked
|
||||
return (T)rootType;
|
||||
}
|
||||
}
|
||||
assert false;
|
||||
assert false : "Root type "+orderRootTypeClass+" not found. All roots: "+ Arrays.asList(rootTypes);
|
||||
return null;
|
||||
}
|
||||
|
||||
public final int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
public final boolean equals(Object obj) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class PersistentOrderRootType extends OrderRootType {
|
||||
}
|
||||
|
||||
/**
|
||||
* Element name used for storing roots of this type in JDK and library definitions.
|
||||
* @return Element name used for storing roots of this type in JDK and library definitions.
|
||||
*/
|
||||
public String getSdkRootName() {
|
||||
return mySdkRootName;
|
||||
@@ -48,10 +48,9 @@ public class PersistentOrderRootType extends OrderRootType {
|
||||
}
|
||||
|
||||
/**
|
||||
* Element name used for storing roots of this type in module definitions.
|
||||
* @return Element name used for storing roots of this type in module definitions.
|
||||
*/
|
||||
public String getModulePathsName() {
|
||||
return myModulePathsName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ public class TargetElementUtilBase {
|
||||
|
||||
final List<PomTarget> targets = CollectionFactory.arrayList();
|
||||
final Consumer<PomTarget> consumer = new Consumer<PomTarget>() {
|
||||
public void consume(PomTarget target) {
|
||||
public void consume(@NotNull PomTarget target) {
|
||||
if (target instanceof PsiDeclaredTarget) {
|
||||
final PsiDeclaredTarget declaredTarget = (PsiDeclaredTarget)target;
|
||||
final PsiElement navigationElement = declaredTarget.getNavigationElement();
|
||||
@@ -221,7 +221,10 @@ public class TargetElementUtilBase {
|
||||
for (PomDeclarationSearcher searcher : PomDeclarationSearcher.EP_NAME.getExtensions()) {
|
||||
searcher.findDeclarationsAt(parent, offset, consumer);
|
||||
if (!targets.isEmpty()) {
|
||||
return PomService.convertToPsi(element.getProject(), targets.get(0));
|
||||
final PomTarget target = targets.get(0);
|
||||
if (target != null) {
|
||||
return PomService.convertToPsi(element.getProject(), target);
|
||||
}
|
||||
}
|
||||
}
|
||||
offset += parent.getStartOffsetInParent();
|
||||
|
||||
+5
-3
@@ -101,8 +101,8 @@ public class FilePathCompletionContributor extends CompletionContributor {
|
||||
if (first == null) return;
|
||||
|
||||
final FileReferenceSet set = first.getFileReferenceSet();
|
||||
String prefix = set.getPathString().replace(CompletionUtil.DUMMY_IDENTIFIER_TRIMMED, "");
|
||||
|
||||
String prefix = set.getPathString().substring(0, parameters.getOffset() - set.getElement().getTextRange().getStartOffset() - set.getStartInElement());
|
||||
|
||||
final List<String>[] pathPrefixParts = new List[] {null};
|
||||
int lastSlashIndex;
|
||||
if ((lastSlashIndex = prefix.lastIndexOf('/')) != -1) {
|
||||
@@ -110,6 +110,8 @@ public class FilePathCompletionContributor extends CompletionContributor {
|
||||
prefix = prefix.substring(lastSlashIndex + 1);
|
||||
}
|
||||
|
||||
final CompletionResultSet __result = result.withPrefixMatcher(prefix).caseInsensitive();
|
||||
|
||||
final PsiFile originalFile = parameters.getOriginalFile();
|
||||
final VirtualFile contextFile = originalFile.getVirtualFile();
|
||||
if (contextFile != null) {
|
||||
@@ -147,7 +149,7 @@ public class FilePathCompletionContributor extends CompletionContributor {
|
||||
if (virtualFile != null && virtualFile.isValid() && virtualFile != contextFile) {
|
||||
if (contextHelper.isMine(project, virtualFile)) {
|
||||
if (pathPrefixParts[0] == null || fileMatchesPathPrefix(contextHelper.getPsiFileSystemItem(project, virtualFile), pathPrefixParts[0])) {
|
||||
result.addElement(new FilePathLookupItem(file, contextHelper));
|
||||
__result.addElement(new FilePathLookupItem(file, contextHelper));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import java.util.*;
|
||||
* @author nik
|
||||
*/
|
||||
public class ModuleSettingsImpl extends ComponentManagerSettingsImpl implements ModuleSettings {
|
||||
private String myModuleName;
|
||||
private final String myModuleName;
|
||||
@NonNls private static final String MODULE_ROOT_MANAGER_COMPONENT = "NewModuleRootManager";
|
||||
|
||||
public ModuleSettingsImpl(File moduleFile, ConversionContextImpl context) throws CannotConvertException {
|
||||
|
||||
@@ -70,19 +70,21 @@ public class Bookmark {
|
||||
myHighlighter = markup.addPersistentLineHighlighter(line, HighlighterLayer.ERROR + 1, null);
|
||||
|
||||
|
||||
myHighlighter.setGutterIconRenderer(new GutterIconRenderer() {
|
||||
@NotNull
|
||||
public Icon getIcon() {
|
||||
return Bookmark.this.getIcon();
|
||||
}
|
||||
if (myHighlighter != null) {
|
||||
myHighlighter.setGutterIconRenderer(new GutterIconRenderer() {
|
||||
@NotNull
|
||||
public Icon getIcon() {
|
||||
return Bookmark.this.getIcon();
|
||||
}
|
||||
|
||||
public String getTooltipText() {
|
||||
return StringUtil.escapeXml(getNotEmptyDescription());
|
||||
}
|
||||
});
|
||||
public String getTooltipText() {
|
||||
return StringUtil.escapeXml(getNotEmptyDescription());
|
||||
}
|
||||
});
|
||||
|
||||
myHighlighter.setErrorStripeMarkColor(Color.black);
|
||||
myHighlighter.setErrorStripeTooltip(StringUtil.escapeXml(getNotEmptyDescription()));
|
||||
myHighlighter.setErrorStripeMarkColor(Color.black);
|
||||
myHighlighter.setErrorStripeTooltip(StringUtil.escapeXml(getNotEmptyDescription()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
myHighlighter = null;
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.editor.markup.*;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileTypes.*;
|
||||
import com.intellij.openapi.fileTypes.impl.AbstractFileType;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -94,6 +95,14 @@ public class PsiViewerDialog extends DialogWrapper {
|
||||
private Presentation myPresentation = new Presentation();
|
||||
private Map<String, Object> handlers = new HashMap<String, Object>();
|
||||
private DefaultActionGroup myGroup;
|
||||
private Language[] myLanguageDialects;
|
||||
private static final Comparator<Language> DIALECTS_COMPARATOR = new Comparator<Language>() {
|
||||
public int compare(final Language o1, final Language o2) {
|
||||
if (o1 == null) return o2 == null ? 0 : -1;
|
||||
if (o2 == null) return 1;
|
||||
return o1.getID().compareTo(o2.getID());
|
||||
}
|
||||
};
|
||||
|
||||
public PsiViewerDialog(Project project, boolean modal) {
|
||||
super(project, true);
|
||||
@@ -195,19 +204,6 @@ public class PsiViewerDialog extends DialogWrapper {
|
||||
}
|
||||
});
|
||||
|
||||
myDialectsComboBox.setRenderer(new DefaultListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(final JList list,
|
||||
final Object value,
|
||||
final int index,
|
||||
final boolean isSelected,
|
||||
final boolean cellHasFocus) {
|
||||
final Component result = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
if (value == null) setText("<no dialect>");
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myTreeBuilder.getTreeStructure();
|
||||
myShowWhiteSpacesBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -226,12 +222,7 @@ public class PsiViewerDialog extends DialogWrapper {
|
||||
|
||||
myGroup = new DefaultActionGroup();
|
||||
for (final Presentation popupItem : popupItems) {
|
||||
myGroup.add(new AnAction(popupItem.getText(), popupItem.getText(), popupItem.getIcon()) {
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
updatePresentation(e.getPresentation());
|
||||
updateDialectsCombo();
|
||||
}
|
||||
});
|
||||
myGroup.add(new PopupItemAction(popupItem));
|
||||
}
|
||||
|
||||
final PsiViewerSettings settings = PsiViewerSettings.getSettings();
|
||||
@@ -256,6 +247,14 @@ public class PsiViewerDialog extends DialogWrapper {
|
||||
myButtonPanel.add(typeButton.createCustomComponent(myPresentation), BorderLayout.CENTER);
|
||||
|
||||
updateDialectsCombo();
|
||||
if (myDialectsComboBox.isVisible()) {
|
||||
for (int i = 0; i < myLanguageDialects.length; i++) {
|
||||
if (settings.dialect.equals(myLanguageDialects[i].toString())) {
|
||||
myDialectsComboBox.setSelectedIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerCustomKeyboardActions();
|
||||
super.init();
|
||||
@@ -363,21 +362,19 @@ public class PsiViewerDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private void updateDialectsCombo() {
|
||||
final SortedComboBoxModel<Language> model = new SortedComboBoxModel<Language>(new Comparator<Language>() {
|
||||
public int compare(final Language o1, final Language o2) {
|
||||
if (o1 == null) return o2 == null ? 0 : -1;
|
||||
if (o2 == null) return 1;
|
||||
return o1.getID().compareTo(o2.getID());
|
||||
}
|
||||
});
|
||||
final SortedComboBoxModel<Language> model = new SortedComboBoxModel<Language>(DIALECTS_COMPARATOR);
|
||||
final Object handler = getHandler();
|
||||
if (handler instanceof LanguageFileType) {
|
||||
final Language baseLang = ((LanguageFileType)handler).getLanguage();
|
||||
model.setAll(LanguageUtil.getLanguageDialects(baseLang));
|
||||
model.add(null);
|
||||
myLanguageDialects = LanguageUtil.getLanguageDialects(baseLang);
|
||||
Arrays.sort(myLanguageDialects, DIALECTS_COMPARATOR);
|
||||
model.setAll(myLanguageDialects);
|
||||
}
|
||||
myDialectsComboBox.setModel(model);
|
||||
myDialectsComboBox.setVisible(model.getSize() > 1);
|
||||
if (!myDialectsComboBox.isVisible()) {
|
||||
myLanguageDialects = new Language[0];
|
||||
}
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
@@ -503,6 +500,8 @@ public class PsiViewerDialog extends DialogWrapper {
|
||||
settings.text = myEditor.getDocument().getText();
|
||||
settings.showTreeNodes = myShowTreeNodesCheckBox.isSelected();
|
||||
settings.showWhiteSpaces = myShowWhiteSpacesBox.isSelected();
|
||||
final Object selectedDialect = myDialectsComboBox.getSelectedItem();
|
||||
settings.dialect = myDialectsComboBox.isVisible() && selectedDialect != null ? selectedDialect.toString() : "";
|
||||
super.doCancelAction();
|
||||
}
|
||||
|
||||
@@ -644,4 +643,15 @@ public class PsiViewerDialog extends DialogWrapper {
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
}
|
||||
|
||||
private class PopupItemAction extends AnAction implements DumbAware {
|
||||
public PopupItemAction(Presentation p) {
|
||||
super(p.getText(), p.getText(), p.getIcon());
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
updatePresentation(e.getPresentation());
|
||||
updateDialectsCombo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ public class PsiViewerSettings implements PersistentStateComponent<PsiViewerSett
|
||||
public boolean showTreeNodes = true;
|
||||
public String type = "JAVA file";
|
||||
public String text = "";
|
||||
public String dialect = "";
|
||||
|
||||
public static PsiViewerSettings getSettings() {
|
||||
return ServiceManager.getService(PsiViewerSettings.class);
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ public class ProjectJdkTableImpl extends ProjectJdkTable implements PersistentSt
|
||||
@NonNls private static final String ELEMENT_JDK = "jdk";
|
||||
|
||||
private final Map<String, ProjectJdkImpl> myCachedProjectJdks = new HashMap<String, ProjectJdkImpl>();
|
||||
private MessageBus myMessageBus;
|
||||
private final MessageBus myMessageBus;
|
||||
|
||||
public ProjectJdkTableImpl() {
|
||||
myMessageBus = ApplicationManager.getApplication().getMessageBus();
|
||||
|
||||
@@ -68,7 +68,7 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library
|
||||
String name = element.getAttributeValue(NAME_ATTR);
|
||||
if (name == null) throw new InvalidDataException();
|
||||
if (level == null) throw new InvalidDataException();
|
||||
searchForLibrary(level, name);
|
||||
searchForLibrary(name, level);
|
||||
init(getRootProvider());
|
||||
addListeners();
|
||||
}
|
||||
@@ -97,12 +97,12 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library
|
||||
ProjectRootManagerImpl projectRootManager,
|
||||
VirtualFilePointerManager filePointerManager) {
|
||||
super(rootModel, projectRootManager, filePointerManager);
|
||||
searchForLibrary(level, name);
|
||||
searchForLibrary(name, level);
|
||||
init(getRootProvider());
|
||||
addListeners();
|
||||
}
|
||||
|
||||
private void searchForLibrary(@NotNull String level, @NotNull String name) {
|
||||
private void searchForLibrary(@NotNull String name, @NotNull String level) {
|
||||
if (myLibrary != null) return;
|
||||
final LibraryTable libraryTable = LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(level, getRootModel().getModule().getProject());
|
||||
final Library library = libraryTable != null ? libraryTable.getLibraryByName(name) : null;
|
||||
@@ -158,12 +158,8 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private RootProvider getRootProvider() {
|
||||
if (myLibrary != null) {
|
||||
return myLibrary.getRootProvider();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
protected RootProvider getRootProvider() {
|
||||
return myLibrary == null ? null : myLibrary.getRootProvider();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
@@ -203,12 +199,7 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library
|
||||
}
|
||||
|
||||
public String getLibraryName() {
|
||||
if (myLibrary != null) {
|
||||
return myLibrary.getName();
|
||||
}
|
||||
else {
|
||||
return myLibraryName;
|
||||
}
|
||||
return myLibrary == null ? myLibraryName : myLibrary.getName();
|
||||
}
|
||||
|
||||
private void addListeners () {
|
||||
|
||||
+3
-13
@@ -116,13 +116,8 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement
|
||||
myProjectRootManagerImpl.addJdkTableListener(this);
|
||||
}
|
||||
|
||||
private RootProvider getRootProvider() {
|
||||
if (myJdk != null) {
|
||||
return myJdk.getRootProvider();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
protected RootProvider getRootProvider() {
|
||||
return myJdk == null ? null : myJdk.getRootProvider();
|
||||
}
|
||||
|
||||
public Sdk getJdk() {
|
||||
@@ -144,12 +139,7 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement
|
||||
|
||||
|
||||
public String getPresentableName() {
|
||||
if (myJdk != null) {
|
||||
return "< " + myJdk.getName() + " >";
|
||||
}
|
||||
else {
|
||||
return "< " + getJdkName() + " >";
|
||||
}
|
||||
return "< " + (myJdk == null ? getJdkName() : myJdk.getName())+ " >";
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.intellij.openapi.roots.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
/**
|
||||
@@ -26,7 +27,7 @@ public abstract class RootModelComponentBase implements Disposable {
|
||||
private final RootModelImpl myRootModel;
|
||||
private boolean myDisposed;
|
||||
|
||||
RootModelComponentBase(RootModelImpl rootModel) {
|
||||
RootModelComponentBase(@NotNull RootModelImpl rootModel) {
|
||||
rootModel.registerOnDispose(this);
|
||||
myRootModel = rootModel;
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx {
|
||||
Disposer.dispose(this);
|
||||
}
|
||||
|
||||
private void commit(LibraryImpl fromModel) {
|
||||
private void commit(@NotNull LibraryImpl fromModel) {
|
||||
if (myLibraryTable != null) {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
}
|
||||
|
||||
+4
-7
@@ -75,7 +75,7 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor {
|
||||
private VirtualFile myLastSelectedDir = null;
|
||||
private final String myModuleName;
|
||||
private final ModulesProvider myModulesProvider;
|
||||
private ModuleConfigurationState myState;
|
||||
private final ModuleConfigurationState myState;
|
||||
|
||||
public CommonContentEntriesEditor(String moduleName, ModuleConfigurationState state) {
|
||||
super(state);
|
||||
@@ -86,15 +86,12 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor {
|
||||
public void afterRefreshFinish(boolean asynchronous) {
|
||||
final Module module = getModule();
|
||||
if (module == null || module.isDisposed() || module.getProject().isDisposed()) return;
|
||||
for (final String contentEntry : myEntryToEditorMap.keySet()) {
|
||||
final ContentEntryEditor editor = myEntryToEditorMap.get(contentEntry);
|
||||
if (editor != null) {
|
||||
editor.update();
|
||||
}
|
||||
for (final ContentEntryEditor editor : myEntryToEditorMap.values()) {
|
||||
editor.update();
|
||||
}
|
||||
}
|
||||
};
|
||||
final VirtualFileManagerEx fileManager = ((VirtualFileManagerEx)VirtualFileManager.getInstance());
|
||||
final VirtualFileManagerEx fileManager = (VirtualFileManagerEx)VirtualFileManager.getInstance();
|
||||
fileManager.addVirtualFileManagerListener(fileManagerListener);
|
||||
registerDisposable(new Disposable() {
|
||||
public void dispose() {
|
||||
|
||||
+3
-3
@@ -204,7 +204,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar {
|
||||
assert parsedNode instanceof FileElement : "Parsed to "+parsedNode+" instead of FileElement";
|
||||
|
||||
String documentText = documentWindow.getText();
|
||||
assert outChars.toString().equals(parsedNode.getText()) : exceptionContext("Before patch: doc:\n" + documentText + "\n---PSI:\n" + parsedNode.getText() + "\n---chars:\n"+outChars);
|
||||
assert outChars.toString().equals(parsedNode.getText()) : exceptionContext("Before patch: doc:\n'" + documentText + "'\n---PSI:\n'" + parsedNode.getText() + "'\n---chars:\n'"+outChars+"'");
|
||||
try {
|
||||
patchLeafs(parsedNode, escapers, place);
|
||||
}
|
||||
@@ -214,7 +214,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar {
|
||||
catch (RuntimeException e) {
|
||||
throw new RuntimeException(exceptionContext("Patch error"), e);
|
||||
}
|
||||
assert parsedNode.getText().equals(documentText) : exceptionContext("After patch: doc:\n" + documentText + "\n---PSI:\n" + parsedNode.getText() + "\n---chars:\n"+outChars);
|
||||
assert parsedNode.getText().equals(documentText) : exceptionContext("After patch: doc:\n'" + documentText + "'\n---PSI:\n'" + parsedNode.getText() + "'\n---chars:\n'"+outChars+"'");
|
||||
|
||||
virtualFile.setContent(null, documentWindow.getText(), false);
|
||||
|
||||
@@ -283,7 +283,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar {
|
||||
@NonNls
|
||||
private String exceptionContext(@NonNls String msg) {
|
||||
return msg + ".\n" +
|
||||
"Language: " +myLanguage+";\n "+
|
||||
myLanguage+";\n "+
|
||||
"Host file: "+myHostPsiFile+" in '" + myHostVirtualFile.getPresentableUrl() + "'\n" +
|
||||
"Context element "+myContextElement.getTextRange() + ": '" + myContextElement +"'; "+
|
||||
"Ranges: "+shreds;
|
||||
|
||||
+4
-5
@@ -17,13 +17,13 @@
|
||||
package com.intellij.historyIntegrTests;
|
||||
|
||||
|
||||
import static com.intellij.history.core.LocalVcsTestCase.list;
|
||||
import com.intellij.history.core.Paths;
|
||||
import com.intellij.history.core.revisions.Revision;
|
||||
import com.intellij.history.utils.RunnableAdapter;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import static com.intellij.history.core.LocalVcsTestCase.list;
|
||||
|
||||
public class ExternalChangesAndRefreshingTest extends IntegrationTestCase {
|
||||
public void testRefreshingSynchronously() throws Exception {
|
||||
doTestRefreshing(false);
|
||||
@@ -113,10 +115,7 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase {
|
||||
}
|
||||
|
||||
private void executeSomeCommand() {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
}
|
||||
}, "", null);
|
||||
CommandProcessor.getInstance().executeCommand(myProject, EmptyRunnable.getInstance(), "", null);
|
||||
}
|
||||
|
||||
public void testContentOfFileChangedDuringRefresh() throws Exception {
|
||||
|
||||
@@ -42,18 +42,25 @@ public abstract class QuickSwitchSchemeAction extends AnAction implements DumbAw
|
||||
|
||||
protected abstract void fillActions(Project project, DefaultActionGroup group, DataContext dataContext);
|
||||
|
||||
private static void showPopup(AnActionEvent e, DefaultActionGroup group) {
|
||||
private void showPopup(AnActionEvent e, DefaultActionGroup group) {
|
||||
if (group.getChildrenCount() == 0) return;
|
||||
final ListPopup popup = JBPopupFactory.getInstance()
|
||||
.createActionGroupPopup(e.getPresentation().getText(),
|
||||
.createActionGroupPopup(QuickSwitchSchemeAction.this.getPopupTitle(e),
|
||||
group,
|
||||
e.getDataContext(),
|
||||
JBPopupFactory.ActionSelectionAid.NUMBERING,
|
||||
e.getDataContext(), getAidMethod(),
|
||||
true);
|
||||
|
||||
popup.showCenteredInCurrentWindow(e.getData(PlatformDataKeys.PROJECT));
|
||||
}
|
||||
|
||||
protected JBPopupFactory.ActionSelectionAid getAidMethod() {
|
||||
return JBPopupFactory.ActionSelectionAid.NUMBERING;
|
||||
}
|
||||
|
||||
protected String getPopupTitle(AnActionEvent e) {
|
||||
return e.getPresentation().getText();
|
||||
}
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
super.update(e);
|
||||
e.getPresentation().setEnabled(e.getData(PlatformDataKeys.PROJECT) != null && isEnabled());
|
||||
|
||||
@@ -16,14 +16,28 @@
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.ide.RecentProjectsManagerBase;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class RecentProjectsGroup extends ActionGroup {
|
||||
public RecentProjectsGroup() {
|
||||
super();
|
||||
|
||||
final Presentation templatePresentation = getTemplatePresentation();
|
||||
// Let's make tile more macish
|
||||
if (SystemInfo.isMac) {
|
||||
templatePresentation.setText(ActionsBundle.message("group.reopen.mac.text"));
|
||||
} else {
|
||||
templatePresentation.setText(ActionsBundle.message("group.reopen.win.text"));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AnAction[] getChildren(@Nullable AnActionEvent e) {
|
||||
return RecentProjectsManagerBase.getInstance().getRecentProjectsActions(true);
|
||||
|
||||
+12
-3
@@ -477,13 +477,22 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
if (id != null) {
|
||||
registerAction(id, group);
|
||||
}
|
||||
// text
|
||||
Presentation presentation = group.getTemplatePresentation();
|
||||
|
||||
// text
|
||||
String text = loadTextForElement(element, bundle, id, GROUP_ELEMENT_NAME);
|
||||
presentation.setText(text);
|
||||
// don't override value which was set in API with empty value from xml descriptor
|
||||
if (!StringUtil.isEmpty(text) || presentation.getText() == null) {
|
||||
presentation.setText(text);
|
||||
}
|
||||
|
||||
// description
|
||||
String description = loadDescriptionForElement(element, bundle, id, GROUP_ELEMENT_NAME);
|
||||
presentation.setDescription(description);
|
||||
// don't override value which was set in API with empty value from xml descriptor
|
||||
if (!StringUtil.isEmpty(description) || presentation.getDescription() == null) {
|
||||
presentation.setDescription(description);
|
||||
}
|
||||
|
||||
// icon
|
||||
setIcon(element.getAttributeValue(ICON_ATTR_NAME), className, loader, presentation, pluginId);
|
||||
// popup
|
||||
|
||||
+6
-3
@@ -954,9 +954,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void saveSettings() {
|
||||
if (myDoNotSave || isUnitTestMode() || isHeadlessEnvironment()) return;
|
||||
public void _saveSettings() { // for testing purposes
|
||||
if (mySaveSettingsIsInProgress.compareAndSet(false, true)) {
|
||||
try {
|
||||
doSave();
|
||||
@@ -994,6 +992,11 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
|
||||
}
|
||||
}
|
||||
|
||||
public void saveSettings() {
|
||||
if (myDoNotSave || isUnitTestMode() || isHeadlessEnvironment()) return;
|
||||
_saveSettings();
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
if (myDoNotSave || isUnitTestMode() || isHeadlessEnvironment()) return;
|
||||
|
||||
|
||||
@@ -211,6 +211,10 @@ public class ColorProgressBar extends JComponent {
|
||||
return dimension;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return myColor;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public static void main(String[] args) {
|
||||
JFrame frame = new JFrame("ColorProgressBar Test");
|
||||
|
||||
+1
-1
@@ -182,7 +182,7 @@ public class VirtualFilePointerContainerImpl implements VirtualFilePointerContai
|
||||
result.add(file);
|
||||
}
|
||||
}
|
||||
return result.toArray(new VirtualFile[result.size()]);
|
||||
return result.isEmpty() ? VirtualFile.EMPTY_ARRAY : result.toArray(new VirtualFile[result.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -50,6 +50,10 @@ public class Win32Kernel {
|
||||
|
||||
private final WIN32_FIND_DATA myData = new WIN32_FIND_DATA();
|
||||
|
||||
void clearCache() {
|
||||
myCache.clear();
|
||||
}
|
||||
|
||||
private static class FileInfo {
|
||||
private FileInfo(WIN32_FIND_DATA data) {
|
||||
this.dwFileAttributes = data.dwFileAttributes;
|
||||
@@ -64,8 +68,6 @@ public class Win32Kernel {
|
||||
|
||||
public String[] list(String absolutePath) {
|
||||
|
||||
myCache.clear();
|
||||
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
WIN32_FIND_DATA data = myData;
|
||||
W32API.HANDLE hFind = myKernel.FindFirstFile(absolutePath.replace('/', '\\') + "\\*", data);
|
||||
@@ -92,7 +94,6 @@ public class Win32Kernel {
|
||||
}
|
||||
|
||||
public boolean exists(String path) {
|
||||
myCache.clear();
|
||||
try {
|
||||
getInfo(path);
|
||||
return true;
|
||||
@@ -108,7 +109,9 @@ public class Win32Kernel {
|
||||
}
|
||||
|
||||
public boolean isWritable(String path) throws FileNotFoundException {
|
||||
return (getInfo(path).dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
|
||||
FileInfo fileInfo = getInfo(path);
|
||||
myCache.remove(path);
|
||||
return (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
|
||||
}
|
||||
|
||||
public long getTimeStamp(String path) throws FileNotFoundException {
|
||||
@@ -118,7 +121,6 @@ public class Win32Kernel {
|
||||
private FileInfo getInfo(String path) throws FileNotFoundException {
|
||||
FileInfo info = myCache.get(path);
|
||||
if (info == null) {
|
||||
myCache.clear();
|
||||
WIN32_FIND_DATA data = myData;
|
||||
W32API.HANDLE handle = myKernel.FindFirstFile(path.replace('/', '\\'), data);
|
||||
if (handle.equals(INVALID_HANDLE_VALUE)) {
|
||||
|
||||
+3
-1
@@ -40,7 +40,9 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
|
||||
};
|
||||
|
||||
public static Win32LocalFileSystem getWin32Instance() {
|
||||
return THREAD_LOCAL.get();
|
||||
Win32LocalFileSystem fileSystem = THREAD_LOCAL.get();
|
||||
fileSystem.myKernel.clearCache();
|
||||
return fileSystem;
|
||||
}
|
||||
|
||||
private final Win32Kernel myKernel = new Win32Kernel();
|
||||
|
||||
+2
-4
@@ -21,6 +21,7 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.progress.TaskInfo;
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
|
||||
import com.intellij.openapi.ui.popup.IconButton;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.wm.impl.content.GraphicsConfig;
|
||||
import com.intellij.ui.InplaceButton;
|
||||
@@ -143,10 +144,7 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di
|
||||
}
|
||||
|
||||
private void updateRunning() {
|
||||
queueRunningUpdate(new Runnable() {
|
||||
public void run() {
|
||||
}
|
||||
});
|
||||
queueRunningUpdate(EmptyRunnable.getInstance());
|
||||
}
|
||||
|
||||
protected void updateProgress() {
|
||||
|
||||
@@ -200,7 +200,8 @@ action.OpenProject.text=_Open Project...
|
||||
action.OpenProject.description=Open an existing project
|
||||
action.OpenFile.text=Open Fi_le...
|
||||
action.OpenFile.description=Open file in editor
|
||||
group.$LRU.text=_Reopen
|
||||
group.reopen.win.text=_Reopen
|
||||
group.reopen.mac.text=Open _Recent
|
||||
group.$LRU.description=List of recently opened projects
|
||||
action.CloseProject.text=Close Pro_ject
|
||||
action.CloseProject.description=Close current project
|
||||
|
||||
@@ -41,4 +41,9 @@ sm.test.runner.magnitude.assertion.failed.title=Assertion failed
|
||||
sm.test.runner.magnitude.testerror.title=Error
|
||||
|
||||
sm.test.runner.states.suite.is.empty=Empty test suite.
|
||||
sm.test.runner.states.test.is.ignored=Test ignored.
|
||||
sm.test.runner.states.test.is.ignored=Test ignored.
|
||||
|
||||
sm.test.runner.notifications.tests.passed=Tests passed
|
||||
sm.test.runner.notifications.tests.failed=Tests failed
|
||||
sm.test.runner.notifications.tests.skipped=Tests skipped
|
||||
sm.test.runner.notifications.tests.not.run=Tests were not started
|
||||
|
||||
@@ -533,4 +533,5 @@ all.vcs.init.message.text=Initializing VCS...
|
||||
switch.to.changelist=Switch &to changelist (''{0}'')
|
||||
move.to.changelist=&Move changes to active changelist (''{0}'')
|
||||
vcs.config.track.changed.on.server=Check "changed on server" conflicts in background
|
||||
vcs.quicklist.pupup.title=VCS Quick List
|
||||
vcs.quicklist.pupup.section.local.history=Local History
|
||||
|
||||
@@ -38,4 +38,7 @@ public interface ProxyFilters {
|
||||
return ((SMTestProxy)test).getMagnitudeInfo() == TestStateInfo.Magnitude.FAILED_INDEX;
|
||||
}
|
||||
};
|
||||
|
||||
Filter ERROR_LEAF = FILTER_ERRORS.and(Filter.LEAF);
|
||||
Filter FAILURE_LEAF = FILTER_FAILURES.and(Filter.LEAF);
|
||||
}
|
||||
|
||||
+12
-4
@@ -16,6 +16,7 @@
|
||||
package com.intellij.execution.testframework.sm.runner.ui;
|
||||
|
||||
import com.intellij.execution.testframework.TestConsoleProperties;
|
||||
import com.intellij.execution.testframework.sm.SMTestsRunnerBundle;
|
||||
import com.intellij.execution.testframework.sm.runner.SMTRunnerEventsAdapter;
|
||||
import com.intellij.execution.testframework.sm.runner.SMTestProxy;
|
||||
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo;
|
||||
@@ -48,26 +49,33 @@ public class SMTRunnerNotificationsHandler extends SMTRunnerEventsAdapter {
|
||||
final MessageType type;
|
||||
|
||||
final TestStateInfo.Magnitude magnitude = testsRoot.getMagnitudeInfo();
|
||||
//noinspection EnumSwitchStatementWhichMissesCases
|
||||
switch (magnitude) {
|
||||
case SKIPPED_INDEX:
|
||||
case IGNORED_INDEX:
|
||||
msg = "Tests skipped";
|
||||
msg = SMTestsRunnerBundle.message("sm.test.runner.notifications.tests.skipped");
|
||||
type = MessageType.WARNING;
|
||||
break;
|
||||
|
||||
case NOT_RUN_INDEX:
|
||||
msg = "Tests were not started";
|
||||
msg = SMTestsRunnerBundle.message("sm.test.runner.notifications.tests.not.run");
|
||||
type = MessageType.WARNING;
|
||||
break;
|
||||
|
||||
case FAILED_INDEX:
|
||||
case ERROR_INDEX:
|
||||
msg = "Tests failed";
|
||||
msg = SMTestsRunnerBundle.message("sm.test.runner.notifications.tests.failed");
|
||||
type = MessageType.ERROR;
|
||||
break;
|
||||
case COMPLETE_INDEX:
|
||||
if (testsRoot.getChildren().size() == 0) {
|
||||
msg = SMTestsRunnerBundle.message("sm.test.runner.ui.tests.tree.presentation.labels.no.tests.were.found");
|
||||
type = MessageType.ERROR;
|
||||
break;
|
||||
}
|
||||
// else same as: PASSED_INDEX
|
||||
case PASSED_INDEX:
|
||||
msg = "Tests passed";
|
||||
msg = SMTestsRunnerBundle.message("sm.test.runner.notifications.tests.passed");
|
||||
type = MessageType.INFO;
|
||||
break;
|
||||
|
||||
|
||||
+21
-2
@@ -19,6 +19,7 @@ import com.intellij.execution.testframework.AbstractTestProxy;
|
||||
import com.intellij.execution.testframework.Filter;
|
||||
import com.intellij.execution.testframework.TestConsoleProperties;
|
||||
import com.intellij.execution.testframework.TestFrameworkRunningModel;
|
||||
import com.intellij.execution.testframework.sm.runner.ProxyFilters;
|
||||
import com.intellij.execution.testframework.ui.PrintableTestProxy;
|
||||
import com.intellij.execution.testframework.actions.ScrollToTestSourceAction;
|
||||
import com.intellij.execution.testframework.sm.runner.SMTestProxy;
|
||||
@@ -28,6 +29,8 @@ import com.intellij.openapi.application.ModalityState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Roman Chernyatchik
|
||||
*/
|
||||
@@ -52,8 +55,24 @@ public class SMTRunnerUIActionsHandler implements TestResultsViewer.EventsListen
|
||||
// select first defect at the end (my be TRACK_RUNNING_TEST was enabled and affects on the fly selection)
|
||||
final SMTestProxy testsRootNode = sender.getTestsRootNode();
|
||||
if (TestConsoleProperties.SELECT_FIRST_DEFECT.value(myConsoleProperties)) {
|
||||
final AbstractTestProxy firstDefect =
|
||||
Filter.DEFECTIVE_LEAF.detectIn(testsRootNode.getAllTests());
|
||||
final AbstractTestProxy firstDefect;
|
||||
|
||||
// defects priority:
|
||||
// ERROR -> FAILURE -> GENERAL DEFECTIVE NODE
|
||||
final List<SMTestProxy> allTests = testsRootNode.getAllTests();
|
||||
final AbstractTestProxy firstError = ProxyFilters.ERROR_LEAF.detectIn(allTests);
|
||||
if (firstError != null) {
|
||||
firstDefect = firstError;
|
||||
} else {
|
||||
final AbstractTestProxy firstFailure = ProxyFilters.FAILURE_LEAF.detectIn(allTests);
|
||||
if (firstFailure != null) {
|
||||
firstDefect = firstFailure;
|
||||
} else {
|
||||
firstDefect = null;
|
||||
}
|
||||
}
|
||||
|
||||
// select if detected
|
||||
if (firstDefect != null) {
|
||||
sender.selectAndNotify(firstDefect);
|
||||
}
|
||||
|
||||
+11
-3
@@ -216,6 +216,10 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra
|
||||
}
|
||||
updateStatusLabel();
|
||||
|
||||
if (myTestsRootNode.getChildren().size() == 0) {
|
||||
// no tests found
|
||||
myStatusLine.setStatusColor(ColorProgressBar.RED);
|
||||
}
|
||||
|
||||
myAnimator.stopMovie();
|
||||
myTreeBuilder.updateFromRoot();
|
||||
@@ -292,7 +296,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra
|
||||
}
|
||||
|
||||
public void setFilter(final Filter filter) {
|
||||
// is usded by Test Runner actions, e.g. hide passed, etc
|
||||
// is used by Test Runner actions, e.g. hide passed, etc
|
||||
final SMTRunnerTreeStructure treeStructure = myTreeBuilder.getRTestUnitTreeStructure();
|
||||
treeStructure.setFilter(filter);
|
||||
myTreeBuilder.updateFromRoot();
|
||||
@@ -316,7 +320,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra
|
||||
}
|
||||
|
||||
/**
|
||||
* Manual test proxy selectio in tests tree. E.g. do select root node on
|
||||
* Manual test proxy selection in tests tree. E.g. do select root node on
|
||||
* testing started or do select current node if TRACK_RUNNING_TEST is enabled
|
||||
*
|
||||
*
|
||||
@@ -337,7 +341,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra
|
||||
addTestsTreeSelectionListener(new TreeSelectionListener() {
|
||||
public void valueChanged(final TreeSelectionEvent e) {
|
||||
//We should fire event only if it was generated by this component,
|
||||
//e.g. it is focused. Otherwise it is side effect of selecing proxy in
|
||||
//e.g. it is focused. Otherwise it is side effect of selecting proxy in
|
||||
//try by other component
|
||||
//if (myTreeView.isFocusOwner()) {
|
||||
@Nullable final PrintableTestProxy selectedProxy = (PrintableTestProxy)getTreeView().getSelectedTest();
|
||||
@@ -374,6 +378,10 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra
|
||||
return myTestsFailuresCount;
|
||||
}
|
||||
|
||||
protected Color getTestsStatusColor() {
|
||||
return myStatusLine.getStatusColor();
|
||||
}
|
||||
|
||||
protected int getTestsTotal() {
|
||||
return myTestsTotal;
|
||||
}
|
||||
|
||||
+109
@@ -171,6 +171,115 @@ public class SMTRunnerUIActionsHandlerTest extends BaseSMTRunnerTestCase {
|
||||
}
|
||||
|
||||
|
||||
public void testSelectFirstDefect_Priority_Error() {
|
||||
// Priority: error -> failure
|
||||
TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true);
|
||||
mySuite.setStarted();
|
||||
|
||||
final SMTestProxy testsSuite = createSuiteProxy("my suite", mySuite);
|
||||
testsSuite.setStarted();
|
||||
|
||||
// pending test
|
||||
final SMTestProxy testPending = createTestProxy("testPending", testsSuite);
|
||||
testPending.setStarted();
|
||||
myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending);
|
||||
testPending.setTestIgnored("", "");
|
||||
|
||||
//failed test
|
||||
final SMTestProxy testFailed = createTestProxy("testFailed", testsSuite);
|
||||
testFailed.setStarted();
|
||||
myUIActionsHandler.onTestNodeAdded(myResultsViewer, testFailed);
|
||||
testFailed.setTestFailed("", "", false);
|
||||
|
||||
//error test
|
||||
final SMTestProxy testError = createTestProxy("testError", testsSuite);
|
||||
testError.setStarted();
|
||||
myUIActionsHandler.onTestNodeAdded(myResultsViewer, testError);
|
||||
testError.setTestFailed("", "", true);
|
||||
|
||||
// Second error test just to check that first failed will be selected
|
||||
final SMTestProxy testError2 = createTestProxy("testError2", testsSuite);
|
||||
testError2.setStarted();
|
||||
myUIActionsHandler.onTestNodeAdded(myResultsViewer, testError2);
|
||||
testError2.setTestFailed("", "", true);
|
||||
|
||||
// finish suite
|
||||
testsSuite.setFinished();
|
||||
assertNull(mySelectedTestProxy);
|
||||
|
||||
//testing finished
|
||||
mySuite.setFinished();
|
||||
assertNull(mySelectedTestProxy);
|
||||
|
||||
myUIActionsHandler.onTestingFinished(myResultsViewer);
|
||||
assertEquals(testError, mySelectedTestProxy);
|
||||
}
|
||||
|
||||
public void testSelectFirstDefect_Priority_Failure() {
|
||||
// Priority: error -> failure
|
||||
TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true);
|
||||
mySuite.setStarted();
|
||||
|
||||
final SMTestProxy testsSuite = createSuiteProxy("my suite", mySuite);
|
||||
testsSuite.setStarted();
|
||||
|
||||
// pending test
|
||||
final SMTestProxy testPending = createTestProxy("testPending", testsSuite);
|
||||
testPending.setStarted();
|
||||
myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending);
|
||||
testPending.setTestIgnored("", "");
|
||||
|
||||
//failed test
|
||||
final SMTestProxy testFailed = createTestProxy("testFailed", testsSuite);
|
||||
testFailed.setStarted();
|
||||
myUIActionsHandler.onTestNodeAdded(myResultsViewer, testFailed);
|
||||
testFailed.setTestFailed("", "", false);
|
||||
|
||||
// Second failed test just to check that first failed will be selected
|
||||
final SMTestProxy testFailed2 = createTestProxy("testFailed2", testsSuite);
|
||||
testFailed2.setStarted();
|
||||
myUIActionsHandler.onTestNodeAdded(myResultsViewer, testFailed2);
|
||||
testFailed2.setTestFailed("", "", false);
|
||||
|
||||
// finish suite
|
||||
testsSuite.setFinished();
|
||||
assertNull(mySelectedTestProxy);
|
||||
|
||||
//testing finished
|
||||
mySuite.setFinished();
|
||||
assertNull(mySelectedTestProxy);
|
||||
|
||||
myUIActionsHandler.onTestingFinished(myResultsViewer);
|
||||
assertEquals(testFailed, mySelectedTestProxy);
|
||||
}
|
||||
|
||||
public void testSelectFirstDefect_Priority_Pending() {
|
||||
// Priority: error -> failure
|
||||
TestConsoleProperties.SELECT_FIRST_DEFECT.set(myProperties, true);
|
||||
mySuite.setStarted();
|
||||
|
||||
final SMTestProxy testsSuite = createSuiteProxy("my suite", mySuite);
|
||||
testsSuite.setStarted();
|
||||
|
||||
// pending test
|
||||
final SMTestProxy testPending = createTestProxy("testPending", testsSuite);
|
||||
testPending.setStarted();
|
||||
myUIActionsHandler.onTestNodeAdded(myResultsViewer, testPending);
|
||||
testPending.setTestIgnored("", "");
|
||||
|
||||
// finish suite
|
||||
testsSuite.setFinished();
|
||||
assertNull(mySelectedTestProxy);
|
||||
|
||||
//testing finished
|
||||
mySuite.setFinished();
|
||||
assertNull(mySelectedTestProxy);
|
||||
|
||||
myUIActionsHandler.onTestingFinished(myResultsViewer);
|
||||
// pending tests shouldn't be considered as errors/failures
|
||||
assertNull(mySelectedTestProxy);
|
||||
}
|
||||
|
||||
public void testTrackRunningTest() {
|
||||
TestConsoleProperties.TRACK_RUNNING_TEST.set(myProperties, true);
|
||||
mySuite.setStarted();
|
||||
|
||||
+21
-1
@@ -21,6 +21,7 @@ import com.intellij.execution.testframework.sm.Marker;
|
||||
import com.intellij.execution.testframework.sm.runner.BaseSMTRunnerTestCase;
|
||||
import com.intellij.execution.testframework.sm.runner.GeneralToSMTRunnerEventsConvertor;
|
||||
import com.intellij.execution.testframework.sm.runner.SMTestProxy;
|
||||
import com.intellij.openapi.progress.util.ColorProgressBar;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -338,6 +339,26 @@ public class SMTestRunnerResultsFormTest extends BaseSMTRunnerTestCase {
|
||||
|
||||
myResultsViewer.onCustomProgressTestFailed();
|
||||
assertEquals(1, myResultsViewer.getTestsFailuresCount());
|
||||
|
||||
assertEquals(ColorProgressBar.RED, myResultsViewer.getTestsStatusColor());
|
||||
}
|
||||
|
||||
public void testCustomProgress_Terminated() {
|
||||
myResultsViewer.onTestingStarted(myTestsRootNode);
|
||||
|
||||
final SMTestProxy test1 = createTestProxy("some_test1", myTestsRootNode);
|
||||
myResultsViewer.onTestStarted(test1);
|
||||
|
||||
myResultsViewer.onTestingFinished(myTestsRootNode);
|
||||
|
||||
assertEquals(ColorProgressBar.GREEN, myResultsViewer.getTestsStatusColor());
|
||||
}
|
||||
|
||||
public void testCustomProgress_NotRun() {
|
||||
myResultsViewer.onTestingStarted(myTestsRootNode);
|
||||
myResultsViewer.onTestingFinished(myTestsRootNode);
|
||||
|
||||
assertEquals(ColorProgressBar.RED, myResultsViewer.getTestsStatusColor());
|
||||
}
|
||||
|
||||
public void testCustomProgress_UnSetCount() {
|
||||
@@ -482,5 +503,4 @@ public class SMTestRunnerResultsFormTest extends BaseSMTRunnerTestCase {
|
||||
myResultsViewer.onTestStarted(createTestProxy("some_test1", myTestsRootNode));
|
||||
assertEquals(4, myResultsViewer.getTestsCurrentCount());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,6 +41,10 @@ public class TestStatusLine extends JPanel {
|
||||
myProgressBar.setColor(color);
|
||||
}
|
||||
|
||||
public Color getStatusColor() {
|
||||
return myProgressBar.getColor();
|
||||
}
|
||||
|
||||
public void setFraction(double v) {
|
||||
myProgressBar.setFraction(v);
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,8 +17,8 @@ package com.intellij.openapi.progress;
|
||||
|
||||
public class ProcessCanceledException extends RuntimeException {
|
||||
public ProcessCanceledException() {
|
||||
int i = 0;
|
||||
}
|
||||
|
||||
public ProcessCanceledException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
@@ -36,7 +35,7 @@ public class EventDispatcher <T extends EventListener>{
|
||||
|
||||
private final T myMulticaster;
|
||||
|
||||
private final CopyOnWriteArrayList<T> myListeners = ContainerUtil.createEmptyCOWList();
|
||||
private final List<T> myListeners = ContainerUtil.createEmptyCOWList();
|
||||
|
||||
public static <T extends EventListener> EventDispatcher<T> create(Class<T> listenerClass) {
|
||||
return new EventDispatcher<T>(listenerClass);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.util.concurrency;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
|
||||
@@ -62,18 +63,16 @@ public class Semaphore {
|
||||
sync.acquireSharedInterruptibly(1);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
LOG.debug(e);
|
||||
throw new RuntimeException(e);
|
||||
throw new ProcessCanceledException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean waitFor(final long timeout) {
|
||||
public boolean waitFor(final long timeout) {
|
||||
try {
|
||||
return sync.tryAcquireSharedNanos(1, TimeUnit.MILLISECONDS.toNanos(timeout));
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
LOG.debug(e);
|
||||
throw new RuntimeException(e);
|
||||
throw new ProcessCanceledException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.intellij.util.containers;
|
||||
import java.util.AbstractList;
|
||||
|
||||
/**
|
||||
* Immmutable list in functional style
|
||||
* Immutable list in functional style
|
||||
*
|
||||
* @author nik
|
||||
*/
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
package com.intellij.util.io;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
@@ -102,7 +103,7 @@ public class URLUtil {
|
||||
while (i < len) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '%') {
|
||||
TIntArrayList bytes = new TIntArrayList();
|
||||
List<Integer> bytes = new ArrayList<Integer>();
|
||||
while (i + 2 < len && s.charAt(i) == '%') {
|
||||
final int d1 = decode(s.charAt(i + 1));
|
||||
final int d2 = decode(s.charAt(i + 2));
|
||||
@@ -117,7 +118,7 @@ public class URLUtil {
|
||||
if (!bytes.isEmpty()) {
|
||||
final byte[] bytesArray = new byte[bytes.size()];
|
||||
for (int j = 0; j < bytes.size(); j++) {
|
||||
bytesArray[j] = (byte)bytes.get(j);
|
||||
bytesArray[j] = (byte)bytes.get(j).intValue();
|
||||
}
|
||||
try {
|
||||
decoded.append(new String(bytesArray, "UTF-8"));
|
||||
|
||||
@@ -189,6 +189,10 @@ public class VcsQuickListPopupAction extends QuickSwitchSchemeAction implements
|
||||
toGroup.add(separator);
|
||||
}
|
||||
|
||||
protected String getPopupTitle(AnActionEvent e) {
|
||||
return VcsBundle.message("vcs.quicklist.pupup.title");
|
||||
}
|
||||
|
||||
public enum SupportedVCS {
|
||||
VCS,
|
||||
NOT_IN_VCS
|
||||
|
||||
+2
@@ -17,6 +17,7 @@ package org.intellij.plugins.intelliLang.inject;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.injected.editor.EditorWindow;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
@@ -67,6 +68,7 @@ public class InjectLanguageAction implements IntentionAction {
|
||||
|
||||
@Nullable
|
||||
protected static PsiLanguageInjectionHost findInjectionHost(Editor editor, PsiFile file) {
|
||||
if (editor instanceof EditorWindow) return null;
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
final PsiLanguageInjectionHost host = PsiTreeUtil.getParentOfType(file.findElementAt(offset), PsiLanguageInjectionHost.class, false);
|
||||
if (host == null) return null;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.plugins.groovy.compiler;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.ModuleCompilerUtil;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.impl.FileSetCompileScope;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
@@ -290,42 +289,45 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
return new ModuleChunk((CompileContextEx)context, new Chunk<Module>(module), Collections.<Module, List<VirtualFile>>emptyMap());
|
||||
}
|
||||
|
||||
public void compile(final CompileContext compileContext, final VirtualFile[] virtualFiles, OutputSink sink) {
|
||||
Map<Module, List<VirtualFile>> mapModulesToVirtualFiles = CompilerUtil.buildModuleToFilesMap(compileContext, virtualFiles);
|
||||
final List<Chunk<Module>> chunks =
|
||||
ModuleCompilerUtil.getSortedModuleChunks(myProject, new ArrayList<Module>(mapModulesToVirtualFiles.keySet()));
|
||||
for (final Chunk<Module> chunk : chunks) {
|
||||
for (final Module module : chunk.getNodes()) {
|
||||
final List<VirtualFile> moduleFiles = mapModulesToVirtualFiles.get(module);
|
||||
if (moduleFiles == null) {
|
||||
continue;
|
||||
}
|
||||
public void compile(final CompileContext compileContext, Chunk<Module> moduleChunk, final VirtualFile[] virtualFiles, OutputSink sink) {
|
||||
Map<Module, List<VirtualFile>> mapModulesToVirtualFiles;
|
||||
if (moduleChunk.getNodes().size() == 1) {
|
||||
mapModulesToVirtualFiles = Collections.singletonMap(moduleChunk.getNodes().iterator().next(), Arrays.asList(virtualFiles));
|
||||
}
|
||||
else {
|
||||
mapModulesToVirtualFiles = CompilerUtil.buildModuleToFilesMap(compileContext, virtualFiles);
|
||||
}
|
||||
for (final Module module : moduleChunk.getNodes()) {
|
||||
final List<VirtualFile> moduleFiles = mapModulesToVirtualFiles.get(module);
|
||||
if (moduleFiles == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final ModuleFileIndex index = ModuleRootManager.getInstance(module).getFileIndex();
|
||||
final List<VirtualFile> toCompile = new ArrayList<VirtualFile>();
|
||||
final List<VirtualFile> toCompileTests = new ArrayList<VirtualFile>();
|
||||
final CompilerConfiguration configuration = CompilerConfiguration.getInstance(myProject);
|
||||
final ModuleFileIndex index = ModuleRootManager.getInstance(module).getFileIndex();
|
||||
final List<VirtualFile> toCompile = new ArrayList<VirtualFile>();
|
||||
final List<VirtualFile> toCompileTests = new ArrayList<VirtualFile>();
|
||||
final CompilerConfiguration configuration = CompilerConfiguration.getInstance(myProject);
|
||||
|
||||
if (module.getModuleType() instanceof JavaModuleType) {
|
||||
for (final VirtualFile file : moduleFiles) {
|
||||
final boolean shouldCompile = !configuration.isResourceFile(file) &&
|
||||
(file.getFileType() == GroovyFileType.GROOVY_FILE_TYPE ||
|
||||
file.getFileType() == StdFileTypes.JAVA);
|
||||
if (shouldCompile) {
|
||||
(index.isInTestSourceContent(file) ? toCompileTests : toCompile).add(file);
|
||||
}
|
||||
if (module.getModuleType() instanceof JavaModuleType) {
|
||||
for (final VirtualFile file : moduleFiles) {
|
||||
final boolean shouldCompile = !configuration.isResourceFile(file) &&
|
||||
(file.getFileType() == GroovyFileType.GROOVY_FILE_TYPE ||
|
||||
file.getFileType() == StdFileTypes.JAVA);
|
||||
if (shouldCompile) {
|
||||
(index.isInTestSourceContent(file) ? toCompileTests : toCompile).add(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (!toCompile.isEmpty()) {
|
||||
compileFiles(compileContext, module, toCompile, sink, false);
|
||||
}
|
||||
if (!toCompileTests.isEmpty()) {
|
||||
compileFiles(compileContext, module, toCompileTests, sink, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!toCompile.isEmpty()) {
|
||||
compileFiles(compileContext, module, toCompile, sink, false);
|
||||
}
|
||||
if (!toCompileTests.isEmpty()) {
|
||||
compileFiles(compileContext, module, toCompileTests, sink, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected abstract void compileFiles(CompileContext compileContext, Module module,
|
||||
|
||||
+3
-2
@@ -32,6 +32,7 @@ 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.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.compiler.GroovyCompilerBase;
|
||||
@@ -53,7 +54,7 @@ public class GroovycStubGenerator extends GroovyCompilerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compile(CompileContext compileContext, VirtualFile[] virtualFiles, OutputSink sink) {
|
||||
public void compile(CompileContext compileContext, Chunk<Module> moduleChunk, VirtualFile[] virtualFiles, OutputSink sink) {
|
||||
final CompileScope scope = compileContext.getCompileScope();
|
||||
if (scope.getFiles(StdFileTypes.JAVA, true).length == 0) {
|
||||
return;
|
||||
@@ -75,7 +76,7 @@ public class GroovycStubGenerator extends GroovyCompilerBase {
|
||||
return;
|
||||
}
|
||||
|
||||
super.compile(compileContext, total.toArray(new VirtualFile[total.size()]), sink);
|
||||
super.compile(compileContext, moduleChunk, total.toArray(new VirtualFile[total.size()]), sink);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -297,7 +297,7 @@ public final class Form2ByteCodeCompiler implements ClassInstrumentingCompiler {
|
||||
final ArrayList<MyInstrumentationItem> list = module2itemsList.get(module);
|
||||
|
||||
for (final MyInstrumentationItem item : list) {
|
||||
context.getProgressIndicator().setFraction((double)++formsProcessed / (double)items.length);
|
||||
//context.getProgressIndicator().setFraction((double)++formsProcessed / (double)items.length);
|
||||
|
||||
final VirtualFile formFile = item.getFormFile();
|
||||
context.getProgressIndicator().setText2(formFile.getPresentableUrl());
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<body style="font-family: Verdana; font-size: 13;" LEFTMARGIN="25" TOPMARGIN="25"><table cellpadding="15" width="98%" border="0"><tr><td>
|
||||
|
||||
You don't need to guess which index.html file you are looking at...
|
||||
|
||||
<p>
|
||||
Make editor tabs and lines in navigation lists stand out using the <font style="font-family: Verdana; font-weight:bold;" color="#3366cc">File Colors</font> page of the project settings.
|
||||
</p>
|
||||
|
||||
<p><img hspace="20" src="images/coloredFiles.gif"></p>
|
||||
|
||||
</td></tr></table></body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<body style="font-family: Verdana; font-size: 13;" LEFTMARGIN="25" TOPMARGIN="25">
|
||||
<table cellpadding="15" width="98%" border="0"><tr><td>
|
||||
|
||||
<p>
|
||||
If you press &shortcut:$Copy; then the whole line at caret will be copied to Clipboard.
|
||||
</p>
|
||||
|
||||
</td></tr></table></body>
|
||||
</html>
|
||||
@@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<body style="font-family: Verdana; font-size: 13;" LEFTMARGIN="25" TOPMARGIN="25">
|
||||
<table cellpadding="15" width="98%" border="0">
|
||||
<tr>
|
||||
<td>By pressing &shortcut:RunConfiguration; you can access the Run/Debug dropdown on the main toolbar,
|
||||
without the need to use your mouse.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<body style="font-family: Verdana; font-size: 13;" LEFTMARGIN="25" TOPMARGIN="25"><table cellpadding="15" width="98%" border="0"><tr><td>
|
||||
|
||||
Keep your source code typo-free with the help of the built-in <font style="font-family: Verdana; font-weight:bold;" size="3" color="#3366cc">Spellchecker</font>.
|
||||
|
||||
<p>All texts, including comments, textual strings and literals, are inspected against the pre-defined dictionaries.
|
||||
All typos are highlighted, which leaves you with the task of choosing the correct word, accepting the current spelling, or disabling inspection.
|
||||
Use &shortcut:ShowIntentionActions; to see the list of available actions.
|
||||
</p>
|
||||
|
||||
</td></tr></table></body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<body style="font-family: Verdana; font-size: 13;" LEFTMARGIN="25" TOPMARGIN="25"><table cellpadding="15" width="98%" border="0"><tr><td>
|
||||
|
||||
<p>If you lack words in the pre-defined dictionaries, you can create your own ones. A custom dictionary is a mere
|
||||
textual file with *.dic extension, with each word starting from a new line. </p>
|
||||
<p>All you have to do is to point to the directories where your dictionaries are stored, in the
|
||||
<font style="font-family: Verdana; font-weight:bold;" color="#3366cc">Spelling</font> of the Settings dialog.
|
||||
</p>
|
||||
</td></tr></table></body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<body style="font-family: Verdana; font-size: 13;" LEFTMARGIN="25" TOPMARGIN="25"><table cellpadding="15" width="98%" border="0"><tr><td>
|
||||
|
||||
All your most indispensable VCS commands are just one-click away...
|
||||
<p>
|
||||
Choose <font style="font-family: Verdana; font-weight:bold;" color="#3366cc">Version Control | VCS Quick List</font>
|
||||
on the main menu, and get a popup with the VCS commands that are relevant to the current context:
|
||||
</p>
|
||||
|
||||
<p><img hspace="20" src="images/vcsQuickList.gif"></p>
|
||||
|
||||
</td></tr></table></body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user