Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Kirill Kalishev
2009-11-13 20:17:33 +03:00
104 changed files with 1151 additions and 726 deletions
@@ -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());
}
}
}
}
@@ -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();
}
@@ -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 {
@@ -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();
}
@@ -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("/")) {
@@ -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;
}
}
@@ -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);
}
}
@@ -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,
@@ -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);
}
@@ -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;
}
@@ -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() {
@@ -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,
@@ -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();
@@ -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"));
@@ -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);
@@ -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();
}
@@ -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());
}
}
}
@@ -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;
}
}
}
@@ -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:
@@ -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++) {
@@ -0,0 +1,6 @@
class Test {
Test() {
System.out.println("Super");
System.out.println("Test");
}
}
@@ -0,0 +1,5 @@
class Super {
Super() {
System.out.println("Super");
}
}
@@ -0,0 +1,5 @@
class Test extends Super{
Test() {
System.out.println("Test");
}
}
@@ -1,5 +1,6 @@
class Test {
Test(String s){super(s);}
Test(String s){
}
void foo() {
Test s = new Test("");
@@ -0,0 +1,6 @@
class Test {
Test() {
System.out.println("");
}
}
@@ -0,0 +1,5 @@
class Super {
Super() {
System.out.println("");
}
}
@@ -0,0 +1,3 @@
class Test extends Super{
}
@@ -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() {
@@ -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();
}
}
@@ -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();
@@ -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);
@@ -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 () {
@@ -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();
}
@@ -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() {
@@ -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;
@@ -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);
@@ -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
@@ -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");
@@ -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)) {
@@ -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();
@@ -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);
}
@@ -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;
@@ -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);
}
@@ -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;
}
@@ -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,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);
}
@@ -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
@@ -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,
@@ -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());
+13
View File
@@ -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>
+12
View File
@@ -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>
+13
View File
@@ -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