mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
Generated
+2
-2
@@ -3,15 +3,14 @@
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/InspectionGadgets/InspectionGadgetsPlugin.iml" filepath="$PROJECT_DIR$/plugins/InspectionGadgets/InspectionGadgetsPlugin.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang.iml" group="plugins/IntelliLang" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-java.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-java.iml" group="plugins/IntelliLang" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-javaee.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-javaee.iml" group="plugins/IntelliLang" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-xml.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-xml.iml" group="plugins/IntelliLang" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLangJava.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLangJava.iml" group="plugins/IntelliLang" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/IntentionPowerPak/IntentionPowerPackPlugin.iml" filepath="$PROJECT_DIR$/plugins/IntentionPowerPak/IntentionPowerPackPlugin.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" filepath="$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/annotations/annotations.iml" filepath="$PROJECT_DIR$/platform/annotations/annotations.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/ant/ant.iml" filepath="$PROJECT_DIR$/plugins/ant/ant.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/relaxng/relaxng.iml" filepath="$PROJECT_DIR$/plugins/relaxng/relaxng.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/boot/boot.iml" filepath="$PROJECT_DIR$/platform/boot/boot.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" filepath="$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/build/build.iml" filepath="$PROJECT_DIR$/build/build.iml" />
|
||||
@@ -68,6 +67,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/platform-resources/platform-resources.iml" filepath="$PROJECT_DIR$/platform/platform-resources/platform-resources.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/platform-resources-en/platform-resources-en.iml" filepath="$PROJECT_DIR$/platform/platform-resources-en/platform-resources-en.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/properties/properties.iml" filepath="$PROJECT_DIR$/plugins/properties/properties.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/relaxng/relaxng.iml" filepath="$PROJECT_DIR$/plugins/relaxng/relaxng.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/resources/resources.iml" filepath="$PROJECT_DIR$/resources/resources.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/resources-en/resources-en.iml" filepath="$PROJECT_DIR$/resources-en/resources-en.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/smRunner/smRunner.iml" filepath="$PROJECT_DIR$/platform/smRunner/smRunner.iml" group="platform" />
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="IDEA" type="Application" factoryName="Application">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<extension name="coverage" enabled="false" sample_coverage="true" runner="idea" merge="false" />
|
||||
<extension name="snapshooter" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value=" -ea -Xbootclasspath/p:../out/classes/production/boot -Xmx192m -Didea.is.internal=true -XX:MaxPermSize=150m " />
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../../../lib/dev/compilerapi.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
|
||||
+4
-1
@@ -13,14 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.compiler.impl.javaCompiler;
|
||||
package com.intellij.compiler;
|
||||
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Aug 19, 2008
|
||||
*/
|
||||
public interface DependencyProcessor {
|
||||
ExtensionPointName<DependencyProcessor> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.makeDependencyProcessor");
|
||||
|
||||
void processDependencies(CompileContext context, int classQualifiedName);
|
||||
}
|
||||
@@ -77,15 +77,13 @@ import com.intellij.psi.PsiCompiledElement;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.Chunk;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.OrderedSet;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -957,70 +955,149 @@ public class CompileDriver {
|
||||
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);
|
||||
int round = 0;
|
||||
final Set<VirtualFile> filesToRecompile = new HashSet<VirtualFile>();
|
||||
final Set<VirtualFile> allDependent = new HashSet<VirtualFile>();
|
||||
Collection<VirtualFile> dependentFiles = Collections.emptyList();
|
||||
final Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> dependencyFilter = new DependentClassesCumulativeFilter();
|
||||
|
||||
do {
|
||||
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);
|
||||
}
|
||||
|
||||
DumbService.getInstance(myProject).waitForSmartMode();
|
||||
|
||||
if (round == 0) {
|
||||
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);
|
||||
}
|
||||
});
|
||||
recalculateChunkToFilesMap(context, sortedChunks, snapshot, chunkMap);
|
||||
chunkFiles = chunkMap.get(currentChunk);
|
||||
total = snapshot.length * translatorsLength;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
|
||||
return getGenerationOutputDir(_compiler, module, true);
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
_context = context;
|
||||
}
|
||||
final boolean compiledSomething =
|
||||
compileSources(_context, currentChunk, compiler, chunkFiles, round == 0? forceCompile : true, isRebuild, trackDependencies, onlyCheckStatus, sink);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
DumbService.getInstance(myProject).waitForSmartMode();
|
||||
final boolean hasUnprocessedTraverseRoots = context.getDependencyCache().hasUnprocessedTraverseRoots();
|
||||
if (!isRebuild && (didSomething || hasUnprocessedTraverseRoots)) {
|
||||
final Set<VirtualFile> compiledWithSuccess;
|
||||
final Set<VirtualFile> compiledWithErrors = CacheUtils.getFilesCompiledWithErrors(context);
|
||||
if (compiledWithErrors.isEmpty()) {
|
||||
compiledWithSuccess = sink.getCompiledSources();
|
||||
}
|
||||
else {
|
||||
compiledWithSuccess = new HashSet<VirtualFile>();
|
||||
compiledWithSuccess.addAll(sink.getCompiledSources());
|
||||
compiledWithSuccess.removeAll(compiledWithErrors);
|
||||
}
|
||||
filesToRecompile.removeAll(compiledWithSuccess);
|
||||
filesToRecompile.addAll(compiledWithErrors);
|
||||
|
||||
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);
|
||||
dependentFiles = CacheUtils.findDependentFiles(context, compiledWithSuccess, dependencyFilter);
|
||||
|
||||
if (ourDebugMode) {
|
||||
if (!dependentFiles.isEmpty()) {
|
||||
for (VirtualFile dependentFile : dependentFiles) {
|
||||
System.out.println("FOUND TO RECOMPILE: " + dependentFile.getPresentableUrl());
|
||||
}
|
||||
}
|
||||
chunkMap.put(moduleChunk, files);
|
||||
else {
|
||||
System.out.println("NO FILES TO RECOMPILE");
|
||||
}
|
||||
}
|
||||
total = snapshot.length * translatorsLength;
|
||||
chunkFiles = chunkMap.get(currentChunk);
|
||||
}
|
||||
|
||||
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 (!dependentFiles.isEmpty()) {
|
||||
filesToRecompile.addAll(dependentFiles);
|
||||
allDependent.addAll(dependentFiles);
|
||||
if (context.getProgressIndicator().isCanceled() || context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
|
||||
return getGenerationOutputDir(_compiler, module, true);
|
||||
final List<VirtualFile> filesInScope = getFilesInScope(context, currentChunk, dependentFiles);
|
||||
if (filesInScope.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
_context = context;
|
||||
}
|
||||
final boolean compiledSomething =
|
||||
compileSources(_context, currentChunk, compiler, chunkFiles, forceCompile, isRebuild, trackDependencies, onlyCheckStatus, sink);
|
||||
|
||||
processed += chunkFiles.size();
|
||||
_context.getProgressIndicator().setFraction(((double)processed) / total);
|
||||
|
||||
if (compiledSomething) {
|
||||
generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(compiler));
|
||||
context.getDependencyCache().clearTraverseRoots();
|
||||
chunkFiles = filesInScope;
|
||||
total += chunkFiles.size() * translators.length;
|
||||
}
|
||||
|
||||
didSomething |= (hasUnprocessedTraverseRoots != context.getDependencyCache().hasUnprocessedTraverseRoots());
|
||||
}
|
||||
|
||||
if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
|
||||
throw new ExitException(ExitStatus.ERRORS);
|
||||
}
|
||||
|
||||
didSomething |= compiledSomething;
|
||||
round++;
|
||||
}
|
||||
while (!dependentFiles.isEmpty() && context.getMessageCount(CompilerMessageCategory.ERROR) == 0);
|
||||
|
||||
if (CompilerConfiguration.MAKE_ENABLED) {
|
||||
if (!context.getProgressIndicator().isCanceled()) {
|
||||
// when cancelled pretend nothing was compiled and next compile will compile everything from the scratch
|
||||
final ProgressIndicator indicator = context.getProgressIndicator();
|
||||
final DependencyCache cache = context.getDependencyCache();
|
||||
|
||||
indicator.pushState();
|
||||
indicator.setText(CompilerBundle.message("progress.updating.caches"));
|
||||
indicator.setText2("");
|
||||
|
||||
cache.update();
|
||||
|
||||
indicator.setText(CompilerBundle.message("progress.saving.caches"));
|
||||
cache.resetState();
|
||||
|
||||
indicator.popState();
|
||||
}
|
||||
}
|
||||
|
||||
if (context.getMessageCount(CompilerMessageCategory.ERROR) != 0) {
|
||||
filesToRecompile.addAll(allDependent);
|
||||
}
|
||||
if (filesToRecompile.size() > 0) {
|
||||
sink.add(null, Collections.<TranslatingCompiler.OutputItem>emptyList(), VfsUtil.toVirtualFileArray(filesToRecompile));
|
||||
}
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
LOG.info(e);
|
||||
context.requestRebuildNextTime(e.getMessage());
|
||||
}
|
||||
finally {
|
||||
if (context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
@@ -1034,7 +1111,7 @@ public class CompileDriver {
|
||||
ProgressManager.getInstance().executeNonCancelableSection(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final Collection<VirtualFile> deps = CacheUtils.findDependentFiles(context, Collections.<VirtualFile>emptySet(), null, null);
|
||||
final Collection<VirtualFile> deps = CacheUtils.findDependentFiles(context, Collections.<VirtualFile>emptySet(), null);
|
||||
if (deps.size() > 0) {
|
||||
TranslatingCompilerFilesMonitor.getInstance().update(context, null, Collections.<TranslatingCompiler.OutputItem>emptyList(),
|
||||
VfsUtil.toVirtualFileArray(deps));
|
||||
@@ -1059,6 +1136,37 @@ public class CompileDriver {
|
||||
return didSomething;
|
||||
}
|
||||
|
||||
private static List<VirtualFile> getFilesInScope(final CompileContextEx context, final Chunk<Module> chunk, final Collection<VirtualFile> files) {
|
||||
final List<VirtualFile> filesInScope = new ArrayList<VirtualFile>(files.size());
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
for (VirtualFile file : files) {
|
||||
if (context.getCompileScope().belongs(file.getUrl())) {
|
||||
final Module module = context.getModuleByFile(file);
|
||||
if (chunk.getNodes().contains(module)) {
|
||||
filesInScope.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return filesInScope;
|
||||
}
|
||||
|
||||
private static void recalculateChunkToFilesMap(CompileContextEx context, List<Chunk<Module>> allChunks, VirtualFile[] snapshot, Map<Chunk<Module>, Collection<VirtualFile>> chunkMap) {
|
||||
final Map<Module, List<VirtualFile>> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(context, snapshot);
|
||||
for (Chunk<Module> moduleChunk : allChunks) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private interface FileProcessingCompilerAdapterFactory {
|
||||
FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler);
|
||||
}
|
||||
@@ -1167,11 +1275,14 @@ public class CompileDriver {
|
||||
final ArrayList<Trinity<File, String, Boolean>> toDelete = new ArrayList<Trinity<File, String, Boolean>>();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
TranslatingCompilerFilesMonitor.getInstance()
|
||||
.collectFiles(context, (TranslatingCompiler)compiler, Arrays.<VirtualFile>asList(allSources).iterator(), true
|
||||
/*pass true to make sure that every source in scope file is processed*/, false
|
||||
/*important! should pass false to enable collection of files to delete*/,
|
||||
new ArrayList<VirtualFile>(), toDelete);
|
||||
TranslatingCompilerFilesMonitor.getInstance().collectFiles(
|
||||
context,
|
||||
(TranslatingCompiler)compiler, Arrays.<VirtualFile>asList(allSources).iterator(),
|
||||
true /*pass true to make sure that every source in scope file is processed*/,
|
||||
false /*important! should pass false to enable collection of files to delete*/,
|
||||
new ArrayList<VirtualFile>(),
|
||||
toDelete
|
||||
);
|
||||
}
|
||||
});
|
||||
for (Trinity<File, String, Boolean> trinity : toDelete) {
|
||||
@@ -1532,7 +1643,6 @@ public class CompileDriver {
|
||||
context.getProgressIndicator().pushState();
|
||||
|
||||
final boolean[] wereFilesDeleted = new boolean[]{false};
|
||||
boolean traverseRootsProcessed = false;
|
||||
try {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
@@ -1589,16 +1699,14 @@ public class CompileDriver {
|
||||
}
|
||||
}
|
||||
|
||||
final boolean hadUnprocessedTraverseRoots = context.getDependencyCache().hasUnprocessedTraverseRoots();
|
||||
if ((wereFilesDeleted[0] || hadUnprocessedTraverseRoots || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
if ((wereFilesDeleted[0] || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
compiler.compile(context, moduleChunk, VfsUtil.toVirtualFileArray(toCompile), sink);
|
||||
traverseRootsProcessed = hadUnprocessedTraverseRoots != context.getDependencyCache().hasUnprocessedTraverseRoots();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
context.getProgressIndicator().popState();
|
||||
}
|
||||
return !toCompile.isEmpty() || traverseRootsProcessed || wereFilesDeleted[0];
|
||||
return !toCompile.isEmpty() || wereFilesDeleted[0];
|
||||
}
|
||||
|
||||
private static boolean syncOutputDir(final CompileContextEx context, final Collection<Trinity<File, String, Boolean>> toDelete) throws CacheCorruptedException {
|
||||
@@ -2277,6 +2385,7 @@ public class CompileDriver {
|
||||
private final CompileContextEx myContext;
|
||||
private final TranslatingCompiler[] myCompilers;
|
||||
private int myCurrentCompilerIdx;
|
||||
private final Set<VirtualFile> myCompiledSources = new HashSet<VirtualFile>();
|
||||
//private LinkedBlockingQueue<Future> myFutures = new LinkedBlockingQueue<Future>();
|
||||
|
||||
private TranslatorsOutputSink(CompileContextEx context, TranslatingCompiler[] compilers) {
|
||||
@@ -2288,7 +2397,17 @@ public class CompileDriver {
|
||||
myCurrentCompilerIdx = index;
|
||||
}
|
||||
|
||||
public Set<VirtualFile> getCompiledSources() {
|
||||
return Collections.unmodifiableSet(myCompiledSources);
|
||||
}
|
||||
|
||||
public void add(final String outputRoot, final Collection<TranslatingCompiler.OutputItem> items, final VirtualFile[] filesToRecompile) {
|
||||
for (TranslatingCompiler.OutputItem item : items) {
|
||||
final VirtualFile file = item.getSourceFile();
|
||||
if (file != null) {
|
||||
myCompiledSources.add(file);
|
||||
}
|
||||
}
|
||||
final TranslatingCompiler compiler = myCompilers[myCurrentCompilerIdx];
|
||||
if (compiler instanceof IntermediateOutputCompiler) {
|
||||
final LocalFileSystem lfs = LocalFileSystem.getInstance();
|
||||
@@ -2368,7 +2487,7 @@ public class CompileDriver {
|
||||
}
|
||||
}
|
||||
|
||||
private void addItemToMap(Map<String, Collection<TranslatingCompiler.OutputItem>> map, String outputDir, TranslatingCompiler.OutputItem item) {
|
||||
private static void addItemToMap(Map<String, Collection<TranslatingCompiler.OutputItem>> map, String outputDir, TranslatingCompiler.OutputItem item) {
|
||||
Collection<TranslatingCompiler.OutputItem> collection = map.get(outputDir);
|
||||
if (collection == null) {
|
||||
collection = new ArrayList<TranslatingCompiler.OutputItem>();
|
||||
@@ -2392,4 +2511,21 @@ public class CompileDriver {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class DependentClassesCumulativeFilter implements Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> {
|
||||
|
||||
private final TIntHashSet myProcessedNames = new TIntHashSet();
|
||||
private final Set<VirtualFile> myProcessedFiles = new HashSet<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());
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-5
@@ -1212,9 +1212,22 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
if (srcFile != null) {
|
||||
final SourceFileInfo srcInfo = loadSourceInfo(srcFile);
|
||||
if (srcInfo != null) {
|
||||
final boolean srcWillBeDeleted = VfsUtil.isAncestor(eventFile, srcFile, false);
|
||||
for (int projectId : srcInfo.getProjectIds().toArray()) {
|
||||
if (srcInfo.isAssociated(projectId, filePath)) {
|
||||
addSourceForRecompilation(projectId, srcFile, srcInfo);
|
||||
if (srcWillBeDeleted) {
|
||||
if (LOG.isDebugEnabled() || ourDebugMode) {
|
||||
final String message = "Unschedule recompilation because of deletion " + srcFile.getPresentableUrl();
|
||||
LOG.debug(message);
|
||||
if (ourDebugMode) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
removeSourceForRecompilation(projectId, Math.abs(getFileId(srcFile)));
|
||||
}
|
||||
else {
|
||||
addSourceForRecompilation(projectId, srcFile, srcInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1226,6 +1239,8 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
final TIntHashSet projects = srcInfo.getProjectIds();
|
||||
if (!projects.isEmpty()) {
|
||||
final ScheduleOutputsForDeletionProc deletionProc = new ScheduleOutputsForDeletionProc(file.getUrl());
|
||||
deletionProc.setRootBeingDeleted(eventFile);
|
||||
final int sourceFileId = Math.abs(getFileId(file));
|
||||
for (int projectId : projects.toArray()) {
|
||||
// mark associated outputs for deletion
|
||||
srcInfo.processOutputPaths(projectId, deletionProc);
|
||||
@@ -1236,7 +1251,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
removeSourceForRecompilation(projectId, Math.abs(getFileId(file)));
|
||||
removeSourceForRecompilation(projectId, sourceFileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1381,18 +1396,29 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
|
||||
private class ScheduleOutputsForDeletionProc implements Proc {
|
||||
private final String mySrcUrl;
|
||||
private final LocalFileSystem myFileSystem;
|
||||
@Nullable
|
||||
private VirtualFile myRootBeingDeleted;
|
||||
|
||||
private ScheduleOutputsForDeletionProc(final String srcUrl) {
|
||||
mySrcUrl = srcUrl;
|
||||
myFileSystem = LocalFileSystem.getInstance();
|
||||
}
|
||||
|
||||
public void setRootBeingDeleted(@Nullable VirtualFile rootBeingDeleted) {
|
||||
myRootBeingDeleted = rootBeingDeleted;
|
||||
}
|
||||
|
||||
public boolean execute(final int projectId, String outputPath) {
|
||||
final VirtualFile outFile = myFileSystem.findFileByPath(outputPath);
|
||||
if (outFile != null) { // not deleted yet
|
||||
final OutputFileInfo outputInfo = loadOutputInfo(outFile);
|
||||
final String classname = outputInfo != null? outputInfo.getClassName() : null;
|
||||
markOutputPathForDeletion(projectId, outputPath, classname, mySrcUrl);
|
||||
if (myRootBeingDeleted != null && VfsUtil.isAncestor(myRootBeingDeleted, outFile, false)) {
|
||||
unmarkOutputPathForDeletion(outputPath);
|
||||
}
|
||||
else {
|
||||
final OutputFileInfo outputInfo = loadOutputInfo(outFile);
|
||||
final String classname = outputInfo != null? outputInfo.getClassName() : null;
|
||||
markOutputPathForDeletion(projectId, outputPath, classname, mySrcUrl);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,4 @@ public interface BackendCompiler {
|
||||
|
||||
void compileFinished();
|
||||
|
||||
@Nullable
|
||||
DependencyProcessor getDependencyProcessor();
|
||||
}
|
||||
|
||||
+27
-144
@@ -26,7 +26,10 @@ import com.intellij.compiler.*;
|
||||
import com.intellij.compiler.classParsing.AnnotationConstantValue;
|
||||
import com.intellij.compiler.classParsing.MethodInfo;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.make.*;
|
||||
import com.intellij.compiler.make.Cache;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.compiler.make.DependencyCache;
|
||||
import com.intellij.compiler.make.MakeUtil;
|
||||
import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter;
|
||||
import com.intellij.ide.util.projectWizard.JavaModuleBuilder;
|
||||
import com.intellij.openapi.application.Application;
|
||||
@@ -38,7 +41,6 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.module.JavaModuleType;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleType;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -52,10 +54,8 @@ 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 gnu.trove.THashMap;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -74,20 +74,18 @@ public class BackendCompilerWrapper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.BackendCompilerWrapper");
|
||||
|
||||
private final BackendCompiler myCompiler;
|
||||
private final Set<VirtualFile> mySuccesfullyCompiledJavaFiles; // VirtualFile
|
||||
|
||||
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>();
|
||||
private final ProjectFileIndex myProjectFileIndex;
|
||||
@NonNls private static final String PACKAGE_ANNOTATION_FILE_NAME = "package-info.java";
|
||||
private static final FileObject myStopThreadToken = new FileObject(new File(""), new byte[0]);
|
||||
public final Map<String, Set<CompiledClass>> myFileNameToSourceMap= new THashMap<String, Set<CompiledClass>>();
|
||||
|
||||
private final Set<VirtualFile> myProcessedPackageInfos = new HashSet<VirtualFile>();
|
||||
|
||||
public BackendCompilerWrapper(Chunk<Module> chunk, @NotNull final Project project,
|
||||
@NotNull List<VirtualFile> filesToCompile,
|
||||
@@ -98,44 +96,19 @@ public class BackendCompilerWrapper {
|
||||
myCompiler = compiler;
|
||||
myCompileContext = compileContext;
|
||||
myFilesToCompile = filesToCompile;
|
||||
myFilesToRecompile = new HashSet<VirtualFile>(filesToCompile);
|
||||
mySink = sink;
|
||||
myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
mySuccesfullyCompiledJavaFiles = new HashSet<VirtualFile>(filesToCompile.size());
|
||||
}
|
||||
|
||||
public void compile() throws CompilerException, CacheCorruptedException {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
final Set<VirtualFile> allDependent = new HashSet<VirtualFile>();
|
||||
COMPILE:
|
||||
try {
|
||||
if (!myFilesToCompile.isEmpty()) {
|
||||
if (application.isUnitTestMode()) {
|
||||
saveTestData();
|
||||
}
|
||||
|
||||
compileModules(buildModuleToFilesMap(myFilesToCompile));
|
||||
}
|
||||
|
||||
Collection<VirtualFile> dependentFiles;
|
||||
do {
|
||||
dependentFiles = CacheUtils.findDependentFiles(myCompileContext, mySuccesfullyCompiledJavaFiles, myCompiler.getDependencyProcessor(), DEPENDENCY_FILTER);
|
||||
|
||||
if (!dependentFiles.isEmpty()) {
|
||||
myFilesToRecompile.addAll(dependentFiles);
|
||||
allDependent.addAll(dependentFiles);
|
||||
if (myCompileContext.getProgressIndicator().isCanceled() || myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
|
||||
break COMPILE;
|
||||
}
|
||||
final List<VirtualFile> filesInScope = getFilesInScope(dependentFiles);
|
||||
if (filesInScope.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
myCompileContext.getDependencyCache().clearTraverseRoots();
|
||||
compileModules(buildModuleToFilesMap(filesInScope));
|
||||
}
|
||||
}
|
||||
while (!dependentFiles.isEmpty() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0);
|
||||
}
|
||||
catch (SecurityException e) {
|
||||
throw new CompilerException(CompilerBundle.message("error.compiler.process.not.started", e.getMessage()), e);
|
||||
@@ -153,34 +126,22 @@ public class BackendCompilerWrapper {
|
||||
myModuleToTempDirMap.clear();
|
||||
}
|
||||
|
||||
// do not update caches if cancelled because there is a chance that they will be incomplete
|
||||
if (CompilerConfiguration.MAKE_ENABLED) {
|
||||
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.pushState();
|
||||
indicator.setText(CompilerBundle.message("progress.updating.caches"));
|
||||
indicator.setText2("");
|
||||
|
||||
cache.update();
|
||||
|
||||
indicator.setText(CompilerBundle.message("progress.saving.caches"));
|
||||
cache.resetState();
|
||||
|
||||
indicator.popState();
|
||||
if (!myFilesToCompile.isEmpty() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
// package-info.java hack
|
||||
final List<TranslatingCompiler.OutputItem> outputs = new ArrayList<TranslatingCompiler.OutputItem>();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
for (final VirtualFile file : myFilesToCompile) {
|
||||
if (PACKAGE_ANNOTATION_FILE_NAME.equals(file.getName()) && !myProcessedPackageInfos.contains(file)) {
|
||||
outputs.add(new OutputItemImpl(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!outputs.isEmpty()) {
|
||||
mySink.add(null, outputs, VirtualFile.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
myFilesToRecompile.removeAll(mySuccesfullyCompiledJavaFiles);
|
||||
if (myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) != 0) {
|
||||
myFilesToRecompile.addAll(allDependent);
|
||||
}
|
||||
final List<TranslatingCompiler.OutputItem> outputs = processPackageInfoFiles();
|
||||
if (myFilesToRecompile.size() > 0 || outputs.size() > 0) {
|
||||
mySink.add(null, outputs, VfsUtil.toVirtualFileArray(myFilesToRecompile));
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Module, List<VirtualFile>> buildModuleToFilesMap(final List<VirtualFile> filesToCompile) {
|
||||
@@ -190,51 +151,6 @@ public class BackendCompilerWrapper {
|
||||
return CompilerUtil.buildModuleToFilesMap(myCompileContext, filesToCompile);
|
||||
}
|
||||
|
||||
// package-info.java hack
|
||||
private List<TranslatingCompiler.OutputItem> processPackageInfoFiles() {
|
||||
if (myFilesToRecompile.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<TranslatingCompiler.OutputItem> outputs = new ArrayList<TranslatingCompiler.OutputItem>();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final List<VirtualFile> packageInfoFiles = new ArrayList<VirtualFile>(myFilesToRecompile.size());
|
||||
for (final VirtualFile file : myFilesToRecompile) {
|
||||
if (PACKAGE_ANNOTATION_FILE_NAME.equals(file.getName())) {
|
||||
packageInfoFiles.add(file);
|
||||
}
|
||||
}
|
||||
if (!packageInfoFiles.isEmpty()) {
|
||||
final Set<VirtualFile> badFiles = getFilesCompiledWithErrors();
|
||||
for (final VirtualFile packageInfoFile : packageInfoFiles) {
|
||||
if (!badFiles.contains(packageInfoFile)) {
|
||||
outputs.add(new OutputItemImpl(packageInfoFile));
|
||||
myFilesToRecompile.remove(packageInfoFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return outputs;
|
||||
}
|
||||
|
||||
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 file : files) {
|
||||
if (myCompileContext.getCompileScope().belongs(file.getUrl())) {
|
||||
final Module module = myCompileContext.getModuleByFile(file);
|
||||
if (myChunk.getNodes().contains(module)) {
|
||||
filesInScope.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return filesInScope;
|
||||
}
|
||||
|
||||
private void compileModules(final Map<Module, List<VirtualFile>> moduleToFilesMap) throws CompilerException {
|
||||
myProcessedFilesCount = 0;
|
||||
try {
|
||||
@@ -347,21 +263,6 @@ 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());
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
private class SynchedCompilerParsing extends CompilerParsingThread {
|
||||
@@ -599,8 +500,7 @@ public class BackendCompilerWrapper {
|
||||
}
|
||||
|
||||
private void compileFinished(int exitValue, final ModuleChunk chunk, final String outputDir) {
|
||||
if (exitValue != 0 && !myCompileContext.getProgressIndicator().isCanceled() &&
|
||||
myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
if (exitValue != 0 && !myCompileContext.getProgressIndicator().isCanceled() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
|
||||
myCompileContext.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("error.compiler.internal.error", exitValue), null, -1, -1);
|
||||
}
|
||||
|
||||
@@ -610,7 +510,6 @@ public class BackendCompilerWrapper {
|
||||
try {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final Set<VirtualFile> compiledWithErrors = getFilesCompiledWithErrors();
|
||||
final FileTypeManager typeManager = FileTypeManager.getInstance();
|
||||
final String outputDirPath = outputDir.replace(File.separatorChar, '/');
|
||||
try {
|
||||
@@ -620,7 +519,7 @@ public class BackendCompilerWrapper {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Building output items for " + root.getPresentableUrl() + "; output dir = " + outputDirPath + "; packagePrefix = \"" + packagePrefix + "\"");
|
||||
}
|
||||
buildOutputItemsList(outputDirPath, module, root, typeManager, compiledWithErrors, root, packagePrefix, toRefresh, results);
|
||||
buildOutputItemsList(outputDirPath, module, root, typeManager, root, packagePrefix, toRefresh, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -644,24 +543,8 @@ public class BackendCompilerWrapper {
|
||||
myFileNameToSourceMap.clear(); // clear the map before the next use
|
||||
}
|
||||
|
||||
private Set<VirtualFile> getFilesCompiledWithErrors() {
|
||||
CompilerMessage[] messages = myCompileContext.getMessages(CompilerMessageCategory.ERROR);
|
||||
Set<VirtualFile> compiledWithErrors = Collections.emptySet();
|
||||
if (messages.length > 0) {
|
||||
compiledWithErrors = new HashSet<VirtualFile>(messages.length);
|
||||
for (CompilerMessage message : messages) {
|
||||
final VirtualFile file = message.getVirtualFile();
|
||||
if (file != null) {
|
||||
compiledWithErrors.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return compiledWithErrors;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -671,7 +554,7 @@ public class BackendCompilerWrapper {
|
||||
try {
|
||||
assert child.isValid();
|
||||
if (!child.isDirectory() && myCompiler.getCompilableFileTypes().contains(typeManager.getFileTypeByFile(child))) {
|
||||
updateOutputItemsList(outputDir, child, compiledWithErrors, sourceRoot, packagePrefix, filesToRefresh, results);
|
||||
updateOutputItemsList(outputDir, child, sourceRoot, packagePrefix, filesToRefresh, results);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -720,7 +603,7 @@ public class BackendCompilerWrapper {
|
||||
paths.add(new CompiledClass(classQName, relativePathToSource, pathToClass));
|
||||
}
|
||||
|
||||
private void updateOutputItemsList(final String outputDir, VirtualFile srcFile, Set<VirtualFile> compiledWithErrors,
|
||||
private void updateOutputItemsList(final String outputDir, VirtualFile srcFile,
|
||||
VirtualFile sourceRoot,
|
||||
final String packagePrefix, final List<File> filesToRefresh,
|
||||
Map<String, Collection<TranslatingCompiler.OutputItem>> results) throws CacheCorruptedException {
|
||||
@@ -745,6 +628,9 @@ public class BackendCompilerWrapper {
|
||||
results.put(realLocation.getFirst(), outputs);
|
||||
}
|
||||
outputs.add(new OutputItemImpl(realLocation.getSecond(), srcFile));
|
||||
if (PACKAGE_ANNOTATION_FILE_NAME.equals(srcFile.getName())) {
|
||||
myProcessedPackageInfos.add(srcFile);
|
||||
}
|
||||
if (CompilerConfiguration.MAKE_ENABLED) {
|
||||
newCache.setPath(cc.qName, realLocation.getSecond());
|
||||
}
|
||||
@@ -752,9 +638,6 @@ public class BackendCompilerWrapper {
|
||||
LOG.debug("Added output item: [outputDir; outputPath; sourceFile] = [" + realLocation.getFirst() + "; " +
|
||||
realLocation.getSecond() + "; " + srcFile.getPresentableUrl() + "]");
|
||||
}
|
||||
if (!compiledWithErrors.contains(srcFile)) {
|
||||
mySuccesfullyCompiledJavaFiles.add(srcFile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myCompileContext.addMessage(CompilerMessageCategory.ERROR, "Failed to copy from temporary location to output directory: " + outputPath + " (see idea.log for details)", null, -1, -1);
|
||||
@@ -773,7 +656,7 @@ public class BackendCompilerWrapper {
|
||||
* @param packagePrefix
|
||||
* @return A 'package'-path to a given src file relative to a specified root. "/" slashes must be used
|
||||
*/
|
||||
protected String calcPackagePath(VirtualFile srcFile, VirtualFile sourceRoot, String packagePrefix) {
|
||||
protected static String calcPackagePath(VirtualFile srcFile, VirtualFile sourceRoot, String packagePrefix) {
|
||||
final String prefix = packagePrefix != null && packagePrefix.length() > 0 ? packagePrefix.replace('.', '/') + "/" : "";
|
||||
return prefix + VfsUtil.getRelativePath(srcFile, sourceRoot, '/');
|
||||
}
|
||||
|
||||
@@ -41,10 +41,6 @@ public abstract class ExternalCompiler implements BackendCompiler {
|
||||
return COMPILABLE_TYPES;
|
||||
}
|
||||
|
||||
public DependencyProcessor getDependencyProcessor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Process launchProcess(@NotNull final ModuleChunk chunk, @NotNull final String outputDir, @NotNull final CompileContext compileContext) throws IOException {
|
||||
final String[] commands = createStartupCommand(chunk, compileContext, outputDir);
|
||||
|
||||
-5
@@ -17,7 +17,6 @@ package com.intellij.compiler.impl.javaCompiler.api;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.DependencyProcessor;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacConfigurable;
|
||||
@@ -56,10 +55,6 @@ public class CompilerAPICompiler implements BackendCompiler {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public DependencyProcessor getDependencyProcessor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean checkCompiler(final CompileScope scope) {
|
||||
return true;
|
||||
}
|
||||
|
||||
-5
@@ -17,7 +17,6 @@ package com.intellij.compiler.impl.javaCompiler.eclipse;
|
||||
|
||||
import com.intellij.compiler.OutputParser;
|
||||
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
|
||||
import com.intellij.compiler.impl.javaCompiler.DependencyProcessor;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.compiler.impl.javaCompiler.javac.JavacSettings;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -58,10 +57,6 @@ public class EclipseEmbeddedCompiler implements BackendCompiler {
|
||||
myEclipseCompilerDriver = new EclipseCompilerDriver();
|
||||
}
|
||||
|
||||
public DependencyProcessor getDependencyProcessor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean checkCompiler(final CompileScope scope) {
|
||||
return myEclipseCompilerDriver != null && myEclipseExternalCompiler.checkCompiler(scope);
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ 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.javaCompiler.DependencyProcessor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.compiler.CompilerMessage;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -31,6 +32,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
@@ -126,9 +128,11 @@ 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 {
|
||||
public static Collection<VirtualFile> findDependentFiles(
|
||||
final CompileContextEx context,
|
||||
final Set<VirtualFile> succesfullyCompiledJavaFiles,
|
||||
final @Nullable Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> filter) throws CacheCorruptedException {
|
||||
|
||||
if (!CompilerConfiguration.MAKE_ENABLED) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -137,7 +141,7 @@ public class CacheUtils {
|
||||
final DependencyCache dependencyCache = context.getDependencyCache();
|
||||
|
||||
final Pair<int[], Set<VirtualFile>> deps =
|
||||
dependencyCache.findDependentClasses(context, context.getProject(), succesfullyCompiledJavaFiles, additionalDependencyProcessor);
|
||||
dependencyCache.findDependentClasses(context, context.getProject(), succesfullyCompiledJavaFiles);
|
||||
final Pair<int[], Set<VirtualFile>> filteredDeps = filter != null? filter.fun(deps) : deps;
|
||||
|
||||
final Set<VirtualFile> dependentFiles = new HashSet<VirtualFile>();
|
||||
@@ -187,4 +191,20 @@ public class CacheUtils {
|
||||
|
||||
return dependentFiles;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<VirtualFile> getFilesCompiledWithErrors(final CompileContextEx context) {
|
||||
CompilerMessage[] messages = context.getMessages(CompilerMessageCategory.ERROR);
|
||||
Set<VirtualFile> compiledWithErrors = Collections.emptySet();
|
||||
if (messages.length > 0) {
|
||||
compiledWithErrors = new HashSet<VirtualFile>(messages.length);
|
||||
for (CompilerMessage message : messages) {
|
||||
final VirtualFile file = message.getVirtualFile();
|
||||
if (file != null) {
|
||||
compiledWithErrors.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return compiledWithErrors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
*/
|
||||
package com.intellij.compiler.make;
|
||||
|
||||
import com.intellij.compiler.DependencyProcessor;
|
||||
import com.intellij.compiler.SymbolTable;
|
||||
import com.intellij.compiler.classParsing.*;
|
||||
import com.intellij.compiler.impl.javaCompiler.DependencyProcessor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -37,7 +37,6 @@ import com.intellij.util.cls.ClsUtil;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -390,15 +389,14 @@ public class DependencyCache {
|
||||
/**
|
||||
* @return qualified names of the classes that should be additionally recompiled
|
||||
*/
|
||||
public Pair<int[], Set<VirtualFile>> findDependentClasses(CompileContext context, Project project, Set<VirtualFile> successfullyCompiled, @Nullable final DependencyProcessor additionalProcessor)
|
||||
throws CacheCorruptedException {
|
||||
public Pair<int[], Set<VirtualFile>> findDependentClasses(CompileContext context, Project project, Set<VirtualFile> successfullyCompiled)
|
||||
throws CacheCorruptedException {
|
||||
|
||||
markDependencies(context, project, successfullyCompiled, additionalProcessor);
|
||||
markDependencies(context, project, successfullyCompiled);
|
||||
return new Pair<int[], Set<VirtualFile>>(myMarkedInfos.toArray(), Collections.unmodifiableSet(myMarkedFiles));
|
||||
}
|
||||
|
||||
private void markDependencies(CompileContext context, Project project, final Set<VirtualFile> successfullyCompiled,
|
||||
@Nullable final DependencyProcessor additionalProcessor) throws CacheCorruptedException {
|
||||
private void markDependencies(CompileContext context, Project project, final Set<VirtualFile> successfullyCompiled) throws CacheCorruptedException {
|
||||
try {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("====================Marking dependent files=====================");
|
||||
@@ -427,7 +425,7 @@ public class DependencyCache {
|
||||
).run();
|
||||
}
|
||||
changedRetentionPolicyDependencyProcessor.checkAnnotationRetentionPolicyChanges(qName);
|
||||
if (additionalProcessor != null) {
|
||||
for (DependencyProcessor additionalProcessor : DependencyProcessor.EXTENSION_POINT_NAME.getExtensions()) {
|
||||
additionalProcessor.processDependencies(context, qName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class JavaRefactoringSupportProvider extends DefaultRefactoringSupportPro
|
||||
return new JavaPushDownHandler();
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getExtractModuleHandler() {
|
||||
public RefactoringActionHandler getExtractInterfaceHandler() {
|
||||
return new ExtractInterfaceHandler();
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,13 @@ public interface TemplateBuilder {
|
||||
*/
|
||||
void replaceRange(TextRange rangeWithinElement, String replacementText);
|
||||
|
||||
/**
|
||||
* Creates a replacement box for the specified text range within the container element.
|
||||
* @param rangeWithinElement range within the container element.
|
||||
* @param expression the replacement expression.
|
||||
*/
|
||||
public void replaceRange(TextRange rangeWithinElement, Expression expression);
|
||||
|
||||
/**
|
||||
* Shows the live template and initiates editing process.
|
||||
*/
|
||||
|
||||
+4
@@ -59,6 +59,10 @@ public class DefaultRefactoringSupportProvider implements RefactoringSupportProv
|
||||
return null;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getExtractInterfaceHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getExtractModuleHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,12 @@ public interface RefactoringSupportProvider {
|
||||
*/
|
||||
@Nullable RefactoringActionHandler getPushDownHandler();
|
||||
|
||||
/**
|
||||
* @return handler for extracting members to an interface in this language
|
||||
* @see com.intellij.refactoring.RefactoringActionHandler
|
||||
*/
|
||||
@Nullable RefactoringActionHandler getExtractInterfaceHandler();
|
||||
|
||||
/**
|
||||
* @return handler for extracting members to some module in this language
|
||||
* @see com.intellij.refactoring.RefactoringActionHandler
|
||||
|
||||
@@ -32,8 +32,8 @@ public interface NameSuggestionProvider {
|
||||
ExtensionPointName<NameSuggestionProvider> EP_NAME = ExtensionPointName.create("com.intellij.nameSuggestionProvider");
|
||||
|
||||
@Nullable
|
||||
SuggestedNameInfo getSuggestedNames(PsiElement element, PsiElement nameSuggestionContext, Set<String> result);
|
||||
SuggestedNameInfo getSuggestedNames(PsiElement element, @Nullable PsiElement nameSuggestionContext, Set<String> result);
|
||||
|
||||
@Nullable
|
||||
Collection<LookupElement> completeName(PsiElement element, final PsiElement nameSuggestionContext, final String prefix);
|
||||
Collection<LookupElement> completeName(PsiElement element, @Nullable final PsiElement nameSuggestionContext, final String prefix);
|
||||
}
|
||||
|
||||
@@ -123,6 +123,12 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||
myElements.add(key);
|
||||
}
|
||||
|
||||
public void replaceRange(TextRange rangeWithinElement, Expression expression) {
|
||||
final RangeMarker key = myDocument.createRangeMarker(rangeWithinElement);
|
||||
myExpressions.put(key, expression);
|
||||
myElements.add(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds end variable after the specified element
|
||||
*/
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.actions.EditorActionUtil;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.event.*;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
|
||||
@@ -109,8 +110,10 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
|
||||
myEditorDocument = editorFactory.createDocument("");
|
||||
setLanguage(language);
|
||||
myConsoleEditor = (EditorEx)editorFactory.createEditor(myEditorDocument, myProject);
|
||||
myConsoleEditor.setBackgroundColor(myConsoleEditor.getColorsScheme().getColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY));
|
||||
myCurrentEditor = myConsoleEditor;
|
||||
myHistoryViewer = (EditorEx)editorFactory.createViewer(((EditorFactoryImpl)editorFactory).createDocument(true), myProject);
|
||||
myHistoryViewer.setBackgroundColor(myHistoryViewer.getColorsScheme().getColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY));
|
||||
myPanel.add(myHistoryViewer.getComponent(), BorderLayout.NORTH);
|
||||
myPanel.add(myConsoleEditor.getComponent(), BorderLayout.CENTER);
|
||||
setupComponents();
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.impl.ModuleImpl;
|
||||
import com.intellij.openapi.module.impl.scopes.JdkScope;
|
||||
import com.intellij.openapi.module.impl.scopes.LibraryRuntimeClasspathScope;
|
||||
import com.intellij.openapi.project.DumbAwareRunnable;
|
||||
import com.intellij.openapi.project.DumbServiceImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectEx;
|
||||
@@ -619,11 +618,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
return; // in test mode suppress addition to a queue unless project is properly initialized
|
||||
}
|
||||
}
|
||||
myStartupManager.runWhenProjectIsInitialized(new DumbAwareRunnable() {
|
||||
public void run() {
|
||||
DumbServiceImpl.getInstance(myProject).queueCacheUpdate(myRefreshCacheUpdaters);
|
||||
}
|
||||
});
|
||||
DumbServiceImpl.getInstance(myProject).queueCacheUpdate(myRefreshCacheUpdaters);
|
||||
}
|
||||
|
||||
private void addRootsToWatch() {
|
||||
|
||||
@@ -19,8 +19,11 @@ package com.intellij.psi.impl;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.CachedValue;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
|
||||
@@ -28,9 +28,12 @@ import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.ParameterizedCachedValueProvider;
|
||||
import com.intellij.psi.util.ParameterizedCachedValue;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.*;
|
||||
|
||||
public abstract class PsiParameterizedCachedValue<T,P> extends PsiCachedValue<T> implements ParameterizedCachedValue<T,P> {
|
||||
|
||||
private final ParameterizedCachedValueProvider<T,P> myProvider;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ExtractInterfaceAction extends ExtractSuperActionBase {
|
||||
|
||||
public ExtractInterfaceAction() {
|
||||
setInjectedContext(true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) {
|
||||
return supportProvider.getExtractInterfaceHandler();
|
||||
}
|
||||
|
||||
}
|
||||
+8
-8
@@ -13,19 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.refactoring.extractInterface;
|
||||
|
||||
import com.intellij.refactoring.actions.BaseExtractModuleAction;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
|
||||
/**
|
||||
* @author Dennis.Ushakov
|
||||
*/
|
||||
public class ExtractInterfaceAction extends BaseExtractModuleAction {
|
||||
public class ExtractModuleAction extends ExtractSuperActionBase {
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledOnLanguage(Language language) {
|
||||
return language instanceof JavaLanguage;
|
||||
protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) {
|
||||
return supportProvider.getExtractModuleHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,8 +25,10 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class ExtractSuperActionBase extends BasePlatformRefactoringAction {
|
||||
|
||||
public abstract class BaseExtractModuleAction extends BaseRefactoringAction {
|
||||
public boolean isAvailableInEditorOnly() {
|
||||
return false;
|
||||
}
|
||||
@@ -34,27 +36,25 @@ public abstract class BaseExtractModuleAction extends BaseRefactoringAction {
|
||||
public boolean isEnabledOnElements(PsiElement[] elements) {
|
||||
if (elements.length > 0) {
|
||||
final Language language = elements[0].getLanguage();
|
||||
final RefactoringActionHandler handler = getRefactoringSupport(language).getExtractModuleHandler();
|
||||
return isEnabledOnLanguage(language) && handler instanceof ElementsHandler && ((ElementsHandler)handler).isEnabledOnElements(elements);
|
||||
final RefactoringActionHandler handler = getRefactoringHandler(LanguageRefactoringSupport.INSTANCE.forLanguage(language));
|
||||
return handler instanceof ElementsHandler && ((ElementsHandler)handler).isEnabledOnElements(elements);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected RefactoringSupportProvider getRefactoringSupport(Language language) {
|
||||
return LanguageRefactoringSupport.INSTANCE.forLanguage(language);
|
||||
}
|
||||
|
||||
|
||||
public RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
|
||||
if (file == null) return null;
|
||||
final RefactoringSupportProvider supportProvider = getRefactoringSupport(file.getViewProvider().getBaseLanguage());
|
||||
return supportProvider != null ? supportProvider.getExtractModuleHandler() : null;
|
||||
final RefactoringSupportProvider supportProvider =
|
||||
LanguageRefactoringSupport.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage());
|
||||
return supportProvider != null ? getRefactoringHandler(supportProvider) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider);
|
||||
|
||||
protected boolean isAvailableForLanguage(final Language language) {
|
||||
return isEnabledOnLanguage(language) && getRefactoringSupport(language).getExtractModuleHandler() != null;
|
||||
return getRefactoringHandler(LanguageRefactoringSupport.INSTANCE.forLanguage(language)) != null;
|
||||
}
|
||||
|
||||
protected abstract boolean isEnabledOnLanguage(final Language language);
|
||||
}
|
||||
+4
-30
@@ -16,38 +16,12 @@
|
||||
|
||||
package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
|
||||
public class ExtractSuperclassAction extends BasePlatformRefactoringAction {
|
||||
public boolean isAvailableInEditorOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isEnabledOnElements(PsiElement[] elements) {
|
||||
if (elements.length > 0) {
|
||||
final Language language = elements[0].getLanguage();
|
||||
final RefactoringActionHandler handler = LanguageRefactoringSupport.INSTANCE.forLanguage(language).getExtractModuleHandler();
|
||||
return handler instanceof ElementsHandler && ((ElementsHandler)handler).isEnabledOnElements(elements);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
|
||||
if (file == null) return null;
|
||||
final RefactoringSupportProvider supportProvider = LanguageRefactoringSupport.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage());
|
||||
return supportProvider != null ? supportProvider.getExtractSuperClassHandler() : null;
|
||||
}
|
||||
|
||||
protected boolean isAvailableForLanguage(final Language language) {
|
||||
return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getExtractSuperClassHandler() != null;
|
||||
public class ExtractSuperclassAction extends ExtractSuperActionBase {
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) {
|
||||
return supportProvider.getExtractSuperClassHandler();
|
||||
}
|
||||
}
|
||||
@@ -51,17 +51,17 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
|
||||
if (startupManager != null) {
|
||||
startupManager.registerPreStartupActivity(new Runnable() {
|
||||
public void run() {
|
||||
final RefreshCacheUpdater refreshUpdater = new RefreshCacheUpdater();
|
||||
final UnindexedFilesUpdater rootsChangeUpdater = new UnindexedFilesUpdater(project, index);
|
||||
final RefreshCacheUpdater changedFilesUpdater = new RefreshCacheUpdater();
|
||||
final UnindexedFilesUpdater unindexedFilesUpdater = new UnindexedFilesUpdater(project, index);
|
||||
|
||||
startupManager.registerCacheUpdater(rootsChangeUpdater);
|
||||
rootManager.registerRootsChangeUpdater(rootsChangeUpdater);
|
||||
rootManager.registerRefreshUpdater(refreshUpdater);
|
||||
startupManager.registerCacheUpdater(unindexedFilesUpdater);
|
||||
rootManager.registerRootsChangeUpdater(unindexedFilesUpdater);
|
||||
rootManager.registerRefreshUpdater(changedFilesUpdater);
|
||||
myIndex.registerIndexableSet(FileBasedIndexProjectHandler.this, project);
|
||||
projectManager.addProjectManagerListener(project, new ProjectManagerAdapter() {
|
||||
public void projectClosing(Project project) {
|
||||
rootManager.unregisterRefreshUpdater(refreshUpdater);
|
||||
rootManager.unregisterRootsChangeUpdater(rootsChangeUpdater);
|
||||
rootManager.unregisterRefreshUpdater(changedFilesUpdater);
|
||||
rootManager.unregisterRootsChangeUpdater(unindexedFilesUpdater);
|
||||
myIndex.removeIndexableSet(FileBasedIndexProjectHandler.this);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.io.OutputStream;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -45,14 +46,16 @@ public abstract class ProcessHandler extends UserDataHolderBase {
|
||||
|
||||
private final Semaphore myWaitSemaphore;
|
||||
private final ProcessListener myEventMulticaster;
|
||||
private final TasksRunner myAfterStartNotifiedRunner;
|
||||
|
||||
protected ProcessHandler() {
|
||||
myEventMulticaster = createEventMulticaster();
|
||||
myWaitSemaphore = new Semaphore();
|
||||
myWaitSemaphore.down();
|
||||
addProcessListener(myAfterStartNotifiedRunner = new TasksRunner());
|
||||
}
|
||||
|
||||
public synchronized void startNotify() {
|
||||
public void startNotify() {
|
||||
if(myState.compareAndSet(STATE_INITIAL, STATE_RUNNING)) {
|
||||
myEventMulticaster.startNotified(new ProcessEvent(this));
|
||||
}
|
||||
@@ -86,7 +89,7 @@ public abstract class ProcessHandler extends UserDataHolderBase {
|
||||
}
|
||||
|
||||
public void destroyProcess() {
|
||||
afterStartNotified(new Runnable() {
|
||||
myAfterStartNotifiedRunner.execute(new Runnable() {
|
||||
public void run() {
|
||||
if (myState.compareAndSet(STATE_RUNNING, STATE_TERMINATING)) {
|
||||
fireProcessWillTerminate(true);
|
||||
@@ -97,7 +100,7 @@ public abstract class ProcessHandler extends UserDataHolderBase {
|
||||
}
|
||||
|
||||
public void detachProcess() {
|
||||
afterStartNotified(new Runnable() {
|
||||
myAfterStartNotifiedRunner.execute(new Runnable() {
|
||||
public void run() {
|
||||
if (myState.compareAndSet(STATE_RUNNING, STATE_TERMINATING)) {
|
||||
fireProcessWillTerminate(false);
|
||||
@@ -132,7 +135,7 @@ public abstract class ProcessHandler extends UserDataHolderBase {
|
||||
}
|
||||
|
||||
private void notifyTerminated(final int exitCode, final boolean willBeDestroyed) {
|
||||
afterStartNotified(new Runnable() {
|
||||
myAfterStartNotifiedRunner.execute(new Runnable() {
|
||||
public void run() {
|
||||
LOG.assertTrue(isStartNotified(), "Start notify is not called");
|
||||
|
||||
@@ -173,20 +176,6 @@ public abstract class ProcessHandler extends UserDataHolderBase {
|
||||
myEventMulticaster.processWillTerminate(new ProcessEvent(this), willBeDestroyed);
|
||||
}
|
||||
|
||||
private synchronized void afterStartNotified(final Runnable runnable) {
|
||||
if (isStartNotified()) {
|
||||
runnable.run();
|
||||
}
|
||||
else {
|
||||
addProcessListener(new ProcessAdapter() {
|
||||
public void startNotified(ProcessEvent event) {
|
||||
removeProcessListener(this);
|
||||
runnable.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStartNotified() {
|
||||
return myState.get() > STATE_INITIAL;
|
||||
}
|
||||
@@ -207,4 +196,40 @@ public abstract class ProcessHandler extends UserDataHolderBase {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final class TasksRunner extends ProcessAdapter {
|
||||
private final List<Runnable> myPendingTasks = new ArrayList<Runnable>();
|
||||
|
||||
public void startNotified(ProcessEvent event) {
|
||||
removeProcessListener(this);
|
||||
// at this point it is guaranteed that nothing will be added to myPendingTasks
|
||||
runPendingTasks();
|
||||
}
|
||||
|
||||
public void execute(Runnable task) {
|
||||
if (isStartNotified()) {
|
||||
task.run();
|
||||
}
|
||||
else {
|
||||
synchronized (myPendingTasks) {
|
||||
myPendingTasks.add(task);
|
||||
}
|
||||
if (isStartNotified()) {
|
||||
runPendingTasks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runPendingTasks() {
|
||||
final Runnable[] tasks;
|
||||
synchronized (myPendingTasks) {
|
||||
tasks = myPendingTasks.toArray(new Runnable[myPendingTasks.size()]);
|
||||
myPendingTasks.clear();
|
||||
}
|
||||
for (Runnable task : tasks) {
|
||||
task.run();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+34
-23
@@ -268,16 +268,19 @@ public class EditorActionUtil {
|
||||
private static void moveCaretToStartOfSoftWrappedLine(Editor editor, VisualPosition currentVisual) {
|
||||
CaretModel caretModel = editor.getCaretModel();
|
||||
int line = currentVisual.line;
|
||||
int column = 0;
|
||||
|
||||
if (currentVisual.column == 0) {
|
||||
// We use default column value as '1' below in assumption that we work with soft-wrapped line and don't want to put cursor
|
||||
// before 'after soft wrap' drawing.
|
||||
int column = 1;
|
||||
|
||||
if (currentVisual.column <= 1) {
|
||||
line--;
|
||||
int nonSpaceColumn = findFirstNonSpaceColumnOnTheLine(editor, line);
|
||||
column = nonSpaceColumn >= 0 ? nonSpaceColumn : 0;
|
||||
column = nonSpaceColumn >= 1 ? nonSpaceColumn : 1;
|
||||
}
|
||||
else {
|
||||
int nonSpaceColumn = findFirstNonSpaceColumnOnTheLine(editor, currentVisual.line);
|
||||
if (nonSpaceColumn > 0 /* current visual line is not empty */ && nonSpaceColumn < currentVisual.column) {
|
||||
if (nonSpaceColumn > 1 /* current visual line is not empty */ && nonSpaceColumn < currentVisual.column) {
|
||||
column = nonSpaceColumn;
|
||||
}
|
||||
}
|
||||
@@ -364,18 +367,13 @@ public class EditorActionUtil {
|
||||
// There are soft wrap-introduced visual lines after the target one
|
||||
return -1;
|
||||
}
|
||||
|
||||
end = findFirstNonSpaceOffsetInRange(document.getCharsSequence(), softWrap.getStart(), logLineEndOffset);
|
||||
if (end >= 0) {
|
||||
// Width of soft wrap virtual text that is located at the target visual line.
|
||||
int result = EditorUtil.calcColumnNumber(editor, softWrapText, j, softWrapTextLength);
|
||||
result++; // For column reserved for 'after soft wrap' sign.
|
||||
result += EditorUtil.calcColumnNumber(editor, document.getCharsSequence(), softWrap.getStart(), end);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
int end = findFirstNonSpaceOffsetInRange(document.getCharsSequence(), softWrap.getStart(), logLineEndOffset);
|
||||
if (end >= 0) {
|
||||
return EditorUtil.calcColumnNumber(editor, document.getCharsSequence(), softWrap.getStart(), end);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -415,6 +413,7 @@ public class EditorActionUtil {
|
||||
LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection()
|
||||
? selectionModel.getBlockStart()
|
||||
: caretModel.getLogicalPosition();
|
||||
SoftWrapModel softWrapModel = editor.getSoftWrapModel();
|
||||
|
||||
int lineNumber = editor.getCaretModel().getLogicalPosition().line;
|
||||
if (lineNumber >= document.getLineCount()) {
|
||||
@@ -434,7 +433,7 @@ public class EditorActionUtil {
|
||||
LogicalPosition logical = editor.visualToLogicalPosition(visualEndOfLineWithCaret);
|
||||
int offset = editor.logicalPositionToOffset(logical);
|
||||
if (offset < editor.getDocument().getTextLength()) {
|
||||
SoftWrapModel softWrapModel = editor.getSoftWrapModel();
|
||||
|
||||
TextChange softWrap = softWrapModel.getSoftWrap(offset);
|
||||
if (softWrap == null) {
|
||||
// Same offset may correspond to positions on different visual lines in case of soft wraps presence
|
||||
@@ -442,21 +441,33 @@ public class EditorActionUtil {
|
||||
// Hence, we check for soft wraps presence at two offsets.
|
||||
softWrap = softWrapModel.getSoftWrap(offset + 1);
|
||||
}
|
||||
int line = currentVisualCaret.line;
|
||||
int column = currentVisualCaret.column;
|
||||
if (softWrap != null) {
|
||||
int line = currentVisualCaret.line + 1;
|
||||
int column = EditorUtil.getLastVisualLineColumnNumber(editor, line);
|
||||
visualEndOfLineWithCaret = new VisualPosition(line, column);
|
||||
line++;
|
||||
column = EditorUtil.getLastVisualLineColumnNumber(editor, line);
|
||||
}
|
||||
// There is a possible case that the last visual line of particular logical line contains only white spaces. We want to move
|
||||
// caret just after 'after soft wrap' drawing then.
|
||||
else if (line == editor.offsetToVisualPosition(document.getLineEndOffset(lineNumber)).line) {
|
||||
column = 1;
|
||||
}
|
||||
visualEndOfLineWithCaret = new VisualPosition(line, column);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int offset;
|
||||
int newOffset;
|
||||
LogicalPosition logLineEnd = editor.visualToLogicalPosition(visualEndOfLineWithCaret);
|
||||
int offset = editor.logicalPositionToOffset(logLineEnd);
|
||||
offset = editor.logicalPositionToOffset(logLineEnd);
|
||||
lineNumber = logLineEnd.line;
|
||||
int newOffset = offset;
|
||||
newOffset = offset;
|
||||
|
||||
CharSequence text = document.getCharsSequence();
|
||||
for (int i = newOffset - 1; i >= document.getLineStartOffset(lineNumber); i--) {
|
||||
if (softWrapModel.getSoftWrap(i) != null) {
|
||||
break;
|
||||
}
|
||||
if (text.charAt(i) != ' ' && text.charAt(i) != '\t') {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
|
||||
import com.intellij.openapi.editor.impl.FontInfo;
|
||||
import com.intellij.openapi.editor.impl.IterationState;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -158,17 +157,42 @@ public class EditorUtil {
|
||||
}
|
||||
|
||||
public static int calcOffset(Editor editor, CharSequence text, int start, int end, int columnNumber, int tabSize) {
|
||||
// If all tabs here goes before any other chars in the line we may use an optimization here.
|
||||
boolean useOptimization = true;
|
||||
final int maxScanIndex = Math.min(start + columnNumber + 1, end);
|
||||
if (editor == null) {
|
||||
return calcSoftWrapUnawareOffset(text, start, maxScanIndex, columnNumber, tabSize);
|
||||
}
|
||||
|
||||
int column = 0;
|
||||
int tabAnchor = 0;
|
||||
SoftWrapModel softWrapModel = editor.getSoftWrapModel();
|
||||
for (int i = start; i < maxScanIndex; i++) {
|
||||
TextChange softWrap = softWrapModel.getSoftWrap(i);
|
||||
if (softWrap != null) {
|
||||
tabAnchor = softWrapModel.getSoftWrapIndentWidthInColumns(softWrap);
|
||||
}
|
||||
if (column >= columnNumber) {
|
||||
return i;
|
||||
}
|
||||
int diff = textWidthInColumns(editor, text, i, i + 1, tabAnchor);
|
||||
if (column + diff > columnNumber) {
|
||||
// We want to return offset that points to the tabulation symbol if it's represented in multiple columns and target visual
|
||||
// column points inside it.
|
||||
return i;
|
||||
}
|
||||
column += diff;
|
||||
tabAnchor += diff;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
private static int calcSoftWrapUnawareOffset(CharSequence text, int start, int end, int columnNumber, int tabSize) {
|
||||
boolean hasNonTabs = false;
|
||||
boolean hasTabs = false;
|
||||
final int maxScanIndex = Math.min(start + columnNumber + 1, end);
|
||||
|
||||
for (int i = start; i < maxScanIndex; i++) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (text.charAt(i) == '\t') {
|
||||
hasTabs = true;
|
||||
if (hasNonTabs) {
|
||||
useOptimization = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -176,52 +200,18 @@ public class EditorUtil {
|
||||
}
|
||||
}
|
||||
|
||||
if (editor == null || useOptimization) {
|
||||
if (!hasTabs) return Math.min(start + columnNumber, end);
|
||||
if (!hasTabs) return Math.min(start + columnNumber, end);
|
||||
|
||||
int shift = 0;
|
||||
int offset = start;
|
||||
for (; offset < end && offset + shift < start + columnNumber; offset++) {
|
||||
if (text.charAt(offset) == '\t') {
|
||||
shift += getTabLength(offset + shift - start, tabSize) - 1;
|
||||
}
|
||||
}
|
||||
if (offset + shift > start + columnNumber) {
|
||||
offset--;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
EditorEx editorImpl = (EditorEx)editor;
|
||||
int shift = 0;
|
||||
int offset = start;
|
||||
IterationState state = new IterationState(editorImpl, offset, false);
|
||||
int fontType = state.getMergedAttributes().getFontType();
|
||||
int column = 0;
|
||||
int x = 0;
|
||||
int spaceSize = getSpaceWidth(fontType, editorImpl);
|
||||
while (column < columnNumber) {
|
||||
if (offset >= state.getEndOffset()) {
|
||||
state.advance();
|
||||
|
||||
fontType = state.getMergedAttributes().getFontType();
|
||||
}
|
||||
|
||||
char c = offset < end ? text.charAt(offset++) : ' ';
|
||||
if (c == '\t') {
|
||||
int prevX = x;
|
||||
x = nextTabStop(x, editorImpl);
|
||||
column += (x - prevX) / spaceSize;
|
||||
}
|
||||
else {
|
||||
x += charWidth(c, fontType, editorImpl);
|
||||
column++;
|
||||
for (; offset < end && offset + shift < start + columnNumber; offset++) {
|
||||
if (text.charAt(offset) == '\t') {
|
||||
shift += getTabLength(offset + shift - start, tabSize) - 1;
|
||||
}
|
||||
}
|
||||
if (column == columnNumber && offset < end && text.charAt(offset) == '\t' && (nextTabStop(x, editorImpl) - x) / spaceSize == 0) {
|
||||
offset++;
|
||||
if (offset + shift > start + columnNumber) {
|
||||
offset--;
|
||||
}
|
||||
if (column > columnNumber) offset--;
|
||||
|
||||
return offset;
|
||||
}
|
||||
@@ -239,15 +229,21 @@ public class EditorUtil {
|
||||
|
||||
public static int calcColumnNumber(Editor editor, CharSequence text, int start, int offset, int tabSize) {
|
||||
boolean useOptimization = true;
|
||||
if (editor != null) {
|
||||
TextChange softWrap = editor.getSoftWrapModel().getSoftWrap(start);
|
||||
useOptimization = softWrap == null;
|
||||
}
|
||||
boolean hasNonTabs = false;
|
||||
for (int i = start; i < offset; i++) {
|
||||
if (text.charAt(i) == '\t') {
|
||||
if (hasNonTabs) {
|
||||
useOptimization = false;
|
||||
break;
|
||||
if (useOptimization) {
|
||||
for (int i = start; i < offset; i++) {
|
||||
if (text.charAt(i) == '\t') {
|
||||
if (hasNonTabs) {
|
||||
useOptimization = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
hasNonTabs = true;
|
||||
}
|
||||
} else {
|
||||
hasNonTabs = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,9 +311,6 @@ public class EditorUtil {
|
||||
* @return number of visual columns required to represent tabulation symbols that starts at the given column
|
||||
*/
|
||||
public static int tabWidthInColumns(@NotNull Editor editor, int visualColumn) {
|
||||
if (!editor.getSettings().isWhitespacesShown()) {
|
||||
return 1;
|
||||
}
|
||||
int tabSize = getTabSize(editor);
|
||||
int tabsNumber = visualColumn / tabSize;
|
||||
return (tabsNumber + 1) * tabSize - visualColumn;
|
||||
@@ -365,12 +358,7 @@ public class EditorUtil {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (editor.getSettings().isWhitespacesShown()) {
|
||||
result += nextTabStop(x + result, editor) - result - x;
|
||||
}
|
||||
else {
|
||||
result += getSpaceWidth(fontType, editor);
|
||||
}
|
||||
result += nextTabStop(x + result, editor) - result - x;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -179,34 +179,43 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener {
|
||||
if (newColumnNumber < 0) newColumnNumber = 0;
|
||||
if (newLineNumber < 0) newLineNumber = 0;
|
||||
|
||||
VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber);
|
||||
int lastColumnNumber = newColumnNumber;
|
||||
if (!editorSettings.isCaretInsideTabs()) {
|
||||
if (!editorSettings.isCaretInsideTabs() && !myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) {
|
||||
LogicalPosition log = myEditor.visualToLogicalPosition(new VisualPosition(newLineNumber, newColumnNumber));
|
||||
int offset = myEditor.logicalPositionToOffset(log);
|
||||
CharSequence text = myEditor.getDocument().getCharsSequence();
|
||||
if (offset >= 0 && offset < myEditor.getDocument().getTextLength()) {
|
||||
if (text.charAt(offset) == '\t') {
|
||||
if (text.charAt(offset) == '\t' && (columnShift <= 0 || offset == myOffset)) {
|
||||
if (columnShift <= 0) {
|
||||
newColumnNumber = myEditor.offsetToVisualPosition(offset).column;
|
||||
}
|
||||
else {
|
||||
if (myEditor.offsetToVisualPosition(offset).column < newColumnNumber) {
|
||||
TextChange softWrap = myEditor.getSoftWrapModel().getSoftWrap(offset + 1);
|
||||
// There is a possible case that tabulation symbol is the last document symbol represented on a visual line before
|
||||
// soft wrap. We can't just use column from 'offset + 1' because it would point on a next visual line.
|
||||
if (softWrap == null) {
|
||||
newColumnNumber = myEditor.offsetToVisualPosition(offset + 1).column;
|
||||
}
|
||||
else {
|
||||
newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber);
|
||||
pos = new VisualPosition(newLineNumber, newColumnNumber);
|
||||
if (columnShift != 0 && lineShift == 0 && myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) {
|
||||
LogicalPosition logical = myEditor.visualToLogicalPosition(pos);
|
||||
int offsetToUse = myEditor.logicalPositionToOffset(logical);
|
||||
if (columnShift < 0) {
|
||||
offsetToUse--;
|
||||
|
||||
int softWrapOffset = myEditor.logicalPositionToOffset(logical);
|
||||
if (columnShift >= 0) {
|
||||
moveToOffset(softWrapOffset);
|
||||
}
|
||||
else {
|
||||
int line = myEditor.offsetToVisualPosition(softWrapOffset - 1).line;
|
||||
moveToVisualPosition(new VisualPosition(line, EditorUtil.getLastVisualLineColumnNumber(myEditor, line)));
|
||||
}
|
||||
moveToOffset(offsetToUse);
|
||||
}
|
||||
else {
|
||||
moveToVisualPosition(pos);
|
||||
|
||||
@@ -839,8 +839,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
int spaceSize = EditorUtil.getSpaceWidth(fontType, this);
|
||||
|
||||
int x = 0;
|
||||
int charWidth;
|
||||
outer:
|
||||
while (true) {
|
||||
charWidth = -1;
|
||||
if (offset >= textLength) {
|
||||
break;
|
||||
}
|
||||
@@ -879,12 +881,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
continue;
|
||||
}
|
||||
prevX = x;
|
||||
int diff = charToVisibleWidth(c, fontType, x);
|
||||
if (diff == 0) {
|
||||
charWidth = charToVisibleWidth(c, fontType, x);
|
||||
if (charWidth == 0) {
|
||||
break outer;
|
||||
}
|
||||
|
||||
x += diff;
|
||||
x += charWidth;
|
||||
if (x >= px) {
|
||||
break outer;
|
||||
}
|
||||
@@ -894,7 +896,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
|
||||
// Process 'after soft wrap' sign.
|
||||
prevX = x;
|
||||
x += mySoftWrapModel.getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP);
|
||||
charWidth = mySoftWrapModel.getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP);
|
||||
x += charWidth;
|
||||
if (x >= px) {
|
||||
break outer;
|
||||
}
|
||||
@@ -903,11 +906,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
|
||||
prevX = x;
|
||||
c = text.charAt(offset);
|
||||
int diff = charToVisibleWidth(c, fontType, x);
|
||||
if (diff == 0) {
|
||||
charWidth = charToVisibleWidth(c, fontType, x);
|
||||
if (charWidth == 0) {
|
||||
break;
|
||||
} else {
|
||||
x += diff;
|
||||
x += charWidth;
|
||||
}
|
||||
|
||||
if (x >= px) {
|
||||
@@ -919,17 +922,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
}
|
||||
|
||||
int charWidth = EditorUtil.charWidth(c, fontType, this);
|
||||
if (charWidth < 0) {
|
||||
charWidth = EditorUtil.charWidth(c, fontType, this);
|
||||
}
|
||||
|
||||
if (x >= px && c == '\t') {
|
||||
if (mySettings.isCaretInsideTabs()) {
|
||||
column += (px - prevX) / spaceSize;
|
||||
if ((px - prevX) % spaceSize > spaceSize / 2) column++;
|
||||
}
|
||||
else {
|
||||
if ((x - px) * 2 < x - prevX) {
|
||||
column += (x - prevX) / spaceSize;
|
||||
}
|
||||
else if ((x - px) * 2 < x - prevX) {
|
||||
column += columnsNumber(c, x, prevX, spaceSize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -977,7 +980,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (c != '\t') {
|
||||
return 1;
|
||||
}
|
||||
return (x - prevX) / spaceSize;
|
||||
int result = (x - prevX) / spaceSize;
|
||||
if ((x - prevX) % spaceSize > 0) {
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1080,12 +1087,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
}
|
||||
|
||||
int x = getTabbedTextWidth(lineStartOffset, column);
|
||||
return new Point(x + reserved, y);
|
||||
int x = getTabbedTextWidth(lineStartOffset, column, reserved);
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
private int getTabbedTextWidth(int startOffset, int length) {
|
||||
int x = 0;
|
||||
private int getTabbedTextWidth(int startOffset, int length, int xOffset) {
|
||||
int x = xOffset;
|
||||
if (startOffset == 0 && myPrefixText != null) {
|
||||
for (char c : myPrefixText) {
|
||||
x += EditorUtil.charWidth(c, myPrefixAttributes.getFontType(), this);
|
||||
@@ -1128,7 +1135,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (c == '\t') {
|
||||
int prevX = x;
|
||||
x = EditorUtil.nextTabStop(x, this);
|
||||
column += (x - prevX) / spaceSize;
|
||||
int columnDiff = (x - prevX) / spaceSize;
|
||||
if ((x - prevX) % spaceSize > 0) {
|
||||
// There is a possible case that tabulation symbol takes more than one visual column to represent and it's shown at
|
||||
// soft-wrapped line. Soft wrap sign width may be not divisible by space size, hence, part of tabulation symbol represented
|
||||
// as a separate visual column may take less space than space width.
|
||||
columnDiff++;
|
||||
}
|
||||
column += columnDiff;
|
||||
}
|
||||
else {
|
||||
x += EditorUtil.charWidth(c, fontType, this);
|
||||
@@ -4843,11 +4857,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
fontType = state.getMergedAttributes().getFontType();
|
||||
}
|
||||
|
||||
TextChange softWrap = getSoftWrapModel().getSoftWrap(i);
|
||||
if (softWrap != null) {
|
||||
column++; // For 'after soft wrap' drawing.
|
||||
x = getSoftWrapModel().getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP);
|
||||
}
|
||||
|
||||
char c = text.charAt(i);
|
||||
if (c == '\t') {
|
||||
int prevX = x;
|
||||
x = EditorUtil.nextTabStop(x, this);
|
||||
column += (x - prevX) / spaceSize;
|
||||
column += columnsNumber(c, x, prevX, spaceSize);
|
||||
//column += Math.max(1, (x - prevX) / spaceSize);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -253,12 +253,23 @@ public class SoftWrapModelImpl implements SoftWrapModelEx {
|
||||
// We consider visual positions that point after the last symbol before soft wrap and the first symbol after soft wrap to not
|
||||
// belong to soft wrap-introduced virtual space.
|
||||
VisualPosition visualAfterSoftWrap = myEditor.offsetToVisualPosition(offset);
|
||||
if (visualAfterSoftWrap.equals(visual)) {
|
||||
if (visualAfterSoftWrap.line == visual.line && visualAfterSoftWrap.column <= visual.column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VisualPosition visualBeforeSoftWrap = myEditor.offsetToVisualPosition(offset - 1);
|
||||
return visual.line > visualBeforeSoftWrap.line || visual.column > visualBeforeSoftWrap.column + 1;
|
||||
int columnOffset = 0;
|
||||
LogicalPosition logLineStart = myEditor.visualToLogicalPosition(new VisualPosition(visualBeforeSoftWrap.line, 0));
|
||||
if (logLineStart.softWrapLinesOnCurrentLogicalLine > 0) {
|
||||
int offsetLineStart = myEditor.logicalPositionToOffset(logLineStart);
|
||||
softWrap = getSoftWrap(offsetLineStart);
|
||||
if (softWrap != null) {
|
||||
columnOffset = getSoftWrapIndentWidthInColumns(softWrap);
|
||||
}
|
||||
}
|
||||
int width = EditorUtil.textWidthInColumns(myEditor, myEditor.getDocument().getCharsSequence(), offset - 1, offset, columnOffset);
|
||||
int softWrapStartColumn = visualBeforeSoftWrap.column + width;
|
||||
return visual.line > visualBeforeSoftWrap.line || visual.column > softWrapStartColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+20
-2
@@ -269,7 +269,17 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
// Try to find target offset that is not greater than preferred position.
|
||||
for (int i = preferred; i > min; i--) {
|
||||
char c = text[i];
|
||||
if ((i < preferred) && (SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c) || WHITE_SPACES.contains(c))) {
|
||||
|
||||
if (i < preferred && WHITE_SPACES.contains(c)) {
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
// Don't wrap on the non-id symbol preceded by another non-id symbol. E.g. consider that we have a statement
|
||||
// like 'foo(int... args)'. We don't want to wrap on the second or third dots then.
|
||||
if (i > min + 1 && !isIdSymbol(c) && !isIdSymbol(text[i - 1])) {
|
||||
continue;
|
||||
}
|
||||
if ((i < preferred) && SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c)) {
|
||||
return i + 1;
|
||||
}
|
||||
if (SPECIAL_SYMBOLS_TO_WRAP_BEFORE.contains(c) || WHITE_SPACES.contains(c)) {
|
||||
@@ -286,7 +296,15 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
// Try to find target offset that is greater than preferred position.
|
||||
for (int i = preferred + 1; i < max; i++) {
|
||||
char c = text[i];
|
||||
if (SPECIAL_SYMBOLS_TO_WRAP_BEFORE.contains(c) || WHITE_SPACES.contains(c)) {
|
||||
if (WHITE_SPACES.contains(c)) {
|
||||
return i;
|
||||
}
|
||||
// Don't wrap on the non-id symbol preceded by another non-id symbol. E.g. consider that we have a statement
|
||||
// like 'foo(int... args)'. We don't want to wrap on the second or third dots then.
|
||||
if (i < max - 1 && !isIdSymbol(c) && !isIdSymbol(text[i + 1]) && !isIdSymbol(text[i - 1])) {
|
||||
continue;
|
||||
}
|
||||
if (SPECIAL_SYMBOLS_TO_WRAP_BEFORE.contains(c)) {
|
||||
return i;
|
||||
}
|
||||
if (SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c) && i < max - 1) {
|
||||
|
||||
+3
-1
@@ -114,7 +114,9 @@ public class SoftWrapDataMapper {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
context.onSoftWrapSymbol('a'); // Emulate 'after soft wrap' sign
|
||||
// Emulate 'after soft wrap' sign
|
||||
//int afterSoftWrapColumns = myEditor.getSoftWrapModel().get
|
||||
context.onSoftWrapSymbol('a');
|
||||
}
|
||||
|
||||
// Process document symbol.
|
||||
|
||||
@@ -35,11 +35,12 @@ import java.lang.ref.Reference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public abstract class CachedValueBase<T> {
|
||||
protected static final Object NULL = new Object();
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.CachedValueImpl");
|
||||
|
||||
private final MyTimedReference<T> myData = new MyTimedReference<T>();
|
||||
@@ -66,7 +67,7 @@ public abstract class CachedValueBase<T> {
|
||||
}
|
||||
|
||||
protected void setValue(final T value, final CachedValueProvider.Result<T> result) {
|
||||
myData.setData(computeData(value == null ? (T) NULL : value, getDependencies(result)));
|
||||
myData.setData(computeData(value == null ? (T)NULL : value, getDependencies(result)));
|
||||
if (result != null) {
|
||||
myData.setIsLocked(result.isLockValue());
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public abstract class CachedValueImpl<T> extends CachedValueBase<T> implements C
|
||||
try {
|
||||
value = getUpToDateOrNull();
|
||||
if (value != null) {
|
||||
return value == NULL ? null : value;
|
||||
return value == ObjectUtils.NULL ? null : value;
|
||||
}
|
||||
} finally {
|
||||
r.unlock();
|
||||
@@ -58,7 +58,7 @@ public abstract class CachedValueImpl<T> extends CachedValueBase<T> implements C
|
||||
try {
|
||||
value = getUpToDateOrNull();
|
||||
if (value != null) {
|
||||
return value == NULL ? null : value;
|
||||
return value == ObjectUtils.NULL ? null : value;
|
||||
}
|
||||
|
||||
CachedValueProvider.Result<T> result = myProvider.compute();
|
||||
|
||||
@@ -30,6 +30,8 @@ import com.intellij.psi.util.ParameterizedCachedValueProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.*;
|
||||
|
||||
public abstract class ParameterizedCachedValueImpl<T,P> extends CachedValueBase<T> implements ParameterizedCachedValue<T,P> {
|
||||
|
||||
private final ParameterizedCachedValueProvider<T,P> myProvider;
|
||||
|
||||
@@ -508,6 +508,8 @@ action.IntroduceParameter.text=Introduce _Parameter...
|
||||
action.IntroduceParameter.description=Turn the selected expression into method parameter
|
||||
action.ExtractInterface.text=Extract _Interface...
|
||||
action.ExtractInterface.description=Extract interface from the selected class
|
||||
action.ExtractModule.text=Extract _Module...
|
||||
action.ExtractModule.description=Extract module from the selected class
|
||||
action.ExtractSuperclass.text=Extract S_uperclass...
|
||||
action.ExtractSuperclass.description=Extract superclass from the selected class
|
||||
action.TurnRefsToSuper.text=Use Interface _Where Possible...
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<group id="AddAllToFavorites" class="com.intellij.ide.favoritesTreeView.actions.AddAllToFavoritesActionGroup" popup="true"/>
|
||||
<action id="AddNewFavoritesList" class="com.intellij.ide.favoritesTreeView.actions.AddNewFavoritesListAction"/>
|
||||
<group id="SendToFavoritesGroup" class="com.intellij.ide.favoritesTreeView.actions.SendToFavoritesGroup" popup="true"/>
|
||||
|
||||
|
||||
<action id="RunConfiguration" class="com.intellij.execution.actions.RunConfigurationAction"/>
|
||||
<action id="ChooseRunConfiguration" class="com.intellij.execution.actions.ChooseRunConfigurationAction" text="Run..." icon="/general/toolWindowRun.png"/>
|
||||
<action id="ChooseDebugConfiguration" class="com.intellij.execution.actions.ChooseDebugConfigurationAction" text="Debug..." icon="/general/debug.png"/>
|
||||
@@ -285,6 +285,8 @@
|
||||
<action id="MemberPushDown" class="com.intellij.refactoring.actions.PushDownAction"/>
|
||||
<separator/>
|
||||
<action id="ExtractInclude" class="com.intellij.refactoring.actions.ExtractIncludeAction"/>
|
||||
<action id="ExtractInterface" class="com.intellij.refactoring.actions.ExtractInterfaceAction"/>
|
||||
<action id="ExtractModule" class="com.intellij.refactoring.actions.ExtractModuleAction"/>
|
||||
<action id="ExtractSuperclass" class="com.intellij.refactoring.actions.ExtractSuperclassAction"/>
|
||||
<add-to-group group-id="MainMenu" anchor="after" relative-to-action="CodeMenu"/>
|
||||
</group>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -23,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author peter
|
||||
*/
|
||||
public class NullableLazyKey<T,H extends UserDataHolder> extends Key<T>{
|
||||
private static final Object NULL = new Object();
|
||||
private final NullableFunction<H,T> myFunction;
|
||||
|
||||
private NullableLazyKey(@NonNls String name, final NullableFunction<H, T> function) {
|
||||
@@ -36,9 +36,9 @@ public class NullableLazyKey<T,H extends UserDataHolder> extends Key<T>{
|
||||
T data = h.getUserData(this);
|
||||
if (data == null) {
|
||||
data = myFunction.fun(h);
|
||||
h.putUserData(this, data == null ? (T)NULL : data);
|
||||
h.putUserData(this, data == null ? (T)ObjectUtils.NULL : data);
|
||||
}
|
||||
return data == NULL ? null : data;
|
||||
return data == ObjectUtils.NULL ? null : data;
|
||||
}
|
||||
|
||||
public static <T,H extends UserDataHolder> NullableLazyKey<T,H> create(@NonNls String name, final NullableFunction<H, T> function) {
|
||||
|
||||
@@ -25,6 +25,8 @@ public class ObjectUtils {
|
||||
private ObjectUtils() {
|
||||
}
|
||||
|
||||
public static final Object NULL = new Object();
|
||||
|
||||
@NotNull
|
||||
public static <T> T assertNotNull(@Nullable final T t) {
|
||||
return _assertNotNull(t);
|
||||
|
||||
@@ -21,11 +21,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.NULL;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class FactoryMap<K,V> implements Map<K, V> {
|
||||
static final Object NULL = new Object();
|
||||
protected Map<K,V> myMap;
|
||||
|
||||
protected Map<K, V> createMap() {
|
||||
|
||||
@@ -25,8 +25,17 @@ import java.util.*;
|
||||
*/
|
||||
public class MultiMap<K, V> {
|
||||
|
||||
public static final MultiMap EMPTY = new MultiMap() {
|
||||
@Override
|
||||
protected Map createMap() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
};
|
||||
|
||||
private final Map<K, Collection<V>> myMap;
|
||||
|
||||
private Collection<V> values;
|
||||
|
||||
public MultiMap() {
|
||||
myMap = createMap();
|
||||
}
|
||||
@@ -117,11 +126,64 @@ public class MultiMap<K, V> {
|
||||
}
|
||||
|
||||
public Collection<? extends V> values() {
|
||||
ArrayList<V> result = new ArrayList<V>();
|
||||
for (Collection<V> vs : myMap.values()) {
|
||||
result.addAll(vs);
|
||||
if (values == null) {
|
||||
values = new AbstractCollection<V>() {
|
||||
@Override
|
||||
public Iterator<V> iterator() {
|
||||
return new Iterator<V>() {
|
||||
|
||||
private Iterator<Collection<V>> mapIterator = myMap.values().iterator();
|
||||
|
||||
private Iterator<V> itr = EmptyIterator.getInstance();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
do {
|
||||
if (itr.hasNext()) return true;
|
||||
if (!mapIterator.hasNext()) return false;
|
||||
itr = mapIterator.next().iterator();
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V next() {
|
||||
do {
|
||||
if (itr.hasNext()) return itr.next();
|
||||
if (!mapIterator.hasNext()) throw new NoSuchElementException();
|
||||
itr = mapIterator.next().iterator();
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
int res = 0;
|
||||
for (Collection<V> vs : myMap.values()) {
|
||||
res += vs.size();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Don't remove this method!!!
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
for (Collection<V> vs : myMap.values()) {
|
||||
if (vs.contains(o)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
return result;
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
@@ -131,4 +193,8 @@ public class MultiMap<K, V> {
|
||||
public Collection<V> remove(K key) {
|
||||
return myMap.remove(key);
|
||||
}
|
||||
|
||||
public static <K, V> MultiMap<K, V> emptyInstance() {
|
||||
return EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.intellij.util.containers;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.NULL;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -32,15 +34,15 @@ public abstract class SoftFactoryMap<T,V> {
|
||||
if (reference != null) {
|
||||
final V v = reference.get();
|
||||
if (v != null) {
|
||||
return v == FactoryMap.NULL ? null : v;
|
||||
return v == NULL ? null : v;
|
||||
}
|
||||
}
|
||||
|
||||
final V value = create(key);
|
||||
SoftReference<V> valueRef = new SoftReference<V>(value == null ? (V)FactoryMap.NULL : value);
|
||||
SoftReference<V> valueRef = new SoftReference<V>(value == null ? (V)NULL : value);
|
||||
SoftReference<V> prevRef = myMap.putIfAbsent(key, valueRef);
|
||||
V prev = prevRef == null ? null : prevRef.get();
|
||||
return prev == null || prev == FactoryMap.NULL? value : prev;
|
||||
return prev == null || prev == NULL ? value : prev;
|
||||
}
|
||||
|
||||
public final boolean containsKey(T key) {
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.intellij.util.containers;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.NULL;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -31,15 +33,15 @@ public abstract class WeakFactoryMap<T,V> {
|
||||
if (reference != null) {
|
||||
final V v = reference.get();
|
||||
if (v != null) {
|
||||
return v == FactoryMap.NULL ? null : v;
|
||||
return v == NULL ? null : v;
|
||||
}
|
||||
}
|
||||
|
||||
final V value = create(key);
|
||||
WeakReference<V> valueRef = new WeakReference<V>(value == null ? (V)FactoryMap.NULL : value);
|
||||
WeakReference<V> valueRef = new WeakReference<V>(value == null ? (V)NULL : value);
|
||||
WeakReference<V> prevRef = myMap.putIfAbsent(key, valueRef);
|
||||
V prev = prevRef == null ? null : prevRef.get();
|
||||
return prev == null || prev == FactoryMap.NULL? value : prev;
|
||||
return prev == null || prev == NULL ? value : prev;
|
||||
}
|
||||
|
||||
public final boolean containsKey(T key) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<orderEntry type="module" module-name="RegExpSupport" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
<orderEntry type="module" module-name="java-impl" />
|
||||
<orderEntry type="module" module-name="IntelliLangJava" />
|
||||
<orderEntry type="module" module-name="IntelliLang" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="IntelliLangJava" />
|
||||
<orderEntry type="module" module-name="IntelliLang" />
|
||||
<orderEntry type="module" module-name="lang-api" />
|
||||
<orderEntry type="module" module-name="jsp-spi" />
|
||||
</component>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" type="PLUGIN_MODULE" version="4">
|
||||
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/src/META-INF/plugin.xml" />
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/classes/production" />
|
||||
<output-test url="file://$MODULE_DIR$/build/classes/test" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="annotations" />
|
||||
<orderEntry type="module" module-name="regexp-lang" />
|
||||
<orderEntry type="module" module-name="xpath-view" />
|
||||
</component>
|
||||
<component name="RetroweaverPlugin">
|
||||
<setting name="active" value="false" />
|
||||
<setting name="verbose" value="false" />
|
||||
<setting name="verifyrefs" value="false" />
|
||||
<setting name="targetJDK" value="" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
<setting name="state" value="1" />
|
||||
</Base>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -530,7 +530,7 @@
|
||||
<component name="ProjectFileVersion" converted="true" />
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/IntelliLang.iml" filepath="$PROJECT_DIR$/IntelliLang.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/IntelliLang-standalone.iml" filepath="$PROJECT_DIR$/IntelliLang-standalone.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../../RegExpSupport/Trunk/regexp-lang.iml" filepath="$PROJECT_DIR$/../../RegExpSupport/Trunk/regexp-lang.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../../XPathView/Trunk/xpath-lang/xpath-lang-java.iml" filepath="$PROJECT_DIR$/../../XPathView/Trunk/xpath-lang/xpath-lang-java.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../../XPathView/Trunk/xpath-view/xpath-view.iml" filepath="$PROJECT_DIR$/../../XPathView/Trunk/xpath-view/xpath-view.iml" />
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<orderEntry type="module" module-name="xpath" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
<orderEntry type="library" name="Jaxen" level="project" />
|
||||
<orderEntry type="module" module-name="IntelliLangJava" />
|
||||
<orderEntry type="module" module-name="IntelliLang" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" type="PLUGIN_MODULE" version="4">
|
||||
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/src/META-INF/plugin.xml" />
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/classes/production" />
|
||||
<output-test url="file://$MODULE_DIR$/build/classes/test" />
|
||||
<module relativePaths="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="annotations" />
|
||||
<orderEntry type="module" module-name="regexp-lang" />
|
||||
<orderEntry type="module" module-name="xpath-view" />
|
||||
</component>
|
||||
<component name="RetroweaverPlugin">
|
||||
<setting name="active" value="false" />
|
||||
<setting name="verbose" value="false" />
|
||||
<setting name="verifyrefs" value="false" />
|
||||
<setting name="targetJDK" value="" />
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="RegExpSupport" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
<orderEntry type="library" name="Jaxen" level="project" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="RegExpSupport" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
<orderEntry type="library" name="Jaxen" level="project" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
<setting name="state" value="1" />
|
||||
</Base>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../lib/trilead-ssh2-build213.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$MODULE_DIR$/../trilead-ssh2-build213/src" />
|
||||
</SOURCES>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="var" path="variable/test.jar" sourcepath="variable/test.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/$ROOT$/jars/test.jar!/" />
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin" />
|
||||
</classpath>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component>
|
||||
<exclude-output />
|
||||
<contentEntry url="file://$MODULE_DIR$" />
|
||||
<lib name="test.jar" scope="COMPILE">
|
||||
<srcroot url="jar://$variable$/test.jar!/" />
|
||||
</lib>
|
||||
</component>
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="var" path="variable/test.jar" sourcepath="variable/test.jar" />
|
||||
<classpathentry kind="output" path="bin" />
|
||||
</classpath>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ws-internals</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
Binary file not shown.
+6
@@ -128,6 +128,12 @@ public class EclipseLibrariesModificationsTest extends EclipseVarsTest {
|
||||
new String[]{});
|
||||
}
|
||||
|
||||
public void testVarAddJavadoc() throws Exception {
|
||||
doTestExisting(new String[]{"/variableidea/test.jar!/"},
|
||||
new String[]{"/variableidea/test.jar!/"},
|
||||
new String[]{"/jars/test.jar!/"});
|
||||
}
|
||||
|
||||
public void testVarAddVarSource() throws Exception {
|
||||
doTestExisting(new String[]{"/variableidea/test.jar!/"},
|
||||
new String[]{"/variableidea/test.jar!/", "/srcvariableidea/test.jar!/"},
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</orderEntry>
|
||||
<orderEntry type="module" module-name="java-impl" />
|
||||
<orderEntry type="module" module-name="copyright" />
|
||||
<orderEntry type="module" module-name="IntelliLangJava" />
|
||||
<orderEntry type="module" module-name="IntelliLang" />
|
||||
<orderEntry type="module" module-name="ant" />
|
||||
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
|
||||
</component>
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.compiler.impl.FileSetCompileScope;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.compiler.make.DependencyCache;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.configurations.JavaParameters;
|
||||
@@ -34,6 +36,8 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.JdkUtil;
|
||||
@@ -58,6 +62,7 @@ import com.intellij.util.Chunk;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.PathsList;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.cls.ClsFormatException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -207,6 +212,33 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
}
|
||||
addStubsToCompileScope(outputPaths, compileContext, module);
|
||||
outputItems = Collections.emptyList();
|
||||
} else {
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.setText("Updating caches...");
|
||||
}
|
||||
|
||||
final DependencyCache dependencyCache = ((CompileContextEx)compileContext).getDependencyCache();
|
||||
for (OutputItem outputItem : outputItems) {
|
||||
if (indicator != null) {
|
||||
indicator.setText2(outputItem.getSourceFile().getName());
|
||||
}
|
||||
|
||||
final String path = outputItem.getOutputPath();
|
||||
final File classFile = new File(path);
|
||||
try {
|
||||
dependencyCache.reparseClassFile(classFile, FileUtil.loadFileBytes(classFile));
|
||||
}
|
||||
catch (ClsFormatException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (CacheCorruptedException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sink.add(outputDir.getPath(), outputItems, VfsUtil.toVirtualFileArray(toRecompile));
|
||||
|
||||
+14
-5
@@ -35,6 +35,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
@@ -88,11 +89,19 @@ public class GroovyConstructorUsagesSearchHelper {
|
||||
@Override
|
||||
public boolean processInReadAction(PsiReference ref) {
|
||||
final PsiElement element = ref.getElement();
|
||||
if (element instanceof GrCodeReferenceElement && element.getParent() instanceof GrNewExpression) {
|
||||
final GrNewExpression newExpression = (GrNewExpression)element.getParent();
|
||||
final PsiMethod resolvedConstructor = newExpression.resolveConstructor();
|
||||
final PsiManager manager = constructor.getManager();
|
||||
if (manager.areElementsEquivalent(resolvedConstructor, constructor) && !consumer.process(ref)) return false;
|
||||
if (element instanceof GrCodeReferenceElement) {
|
||||
GrNewExpression newExpression = null;
|
||||
if (element.getParent() instanceof GrNewExpression) {
|
||||
newExpression = (GrNewExpression)element.getParent();
|
||||
}
|
||||
else if (element.getParent() instanceof GrAnonymousClassDefinition) {
|
||||
newExpression = (GrNewExpression)element.getParent().getParent();
|
||||
}
|
||||
if (newExpression != null) {
|
||||
final PsiMethod resolvedConstructor = newExpression.resolveConstructor();
|
||||
final PsiManager manager = constructor.getManager();
|
||||
if (manager.areElementsEquivalent(resolvedConstructor, constructor) && !consumer.process(ref)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class GppTypeConverter extends GrTypeConverter {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hasDefaultConstructor(lType)) {
|
||||
if (!isMethodCallConversion(context) && hasDefaultConstructor(lType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ public class GrMapType extends GrLiteralClassType {
|
||||
}
|
||||
|
||||
public String getInternalCanonicalText() {
|
||||
if (myStringEntries.size() == 0) return "[:]";
|
||||
|
||||
List<String> components = new ArrayList<String>();
|
||||
for (String s : myStringEntries.keySet()) {
|
||||
components.add("'" + s + "':" + getInternalCanonicalText(myStringEntries.get(s)));
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
import com.intellij.psi.statistics.JavaStatisticsManager;
|
||||
import com.intellij.refactoring.rename.NameSuggestionProvider;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -34,8 +34,8 @@ import java.util.Set;
|
||||
*/
|
||||
public class GroovyNameSuggestionProvider implements NameSuggestionProvider {
|
||||
@Override
|
||||
public SuggestedNameInfo getSuggestedNames(final PsiElement element, PsiElement nameSuggestionContext, Set<String> result) {
|
||||
if (!(element instanceof GroovyPsiElement)) return null;
|
||||
public SuggestedNameInfo getSuggestedNames(final PsiElement element, @Nullable PsiElement nameSuggestionContext, Set<String> result) {
|
||||
if (nameSuggestionContext == null) nameSuggestionContext = element;
|
||||
if (element instanceof GrVariable) {
|
||||
final PsiType type = ((GrVariable)element).getTypeGroovy();
|
||||
if (type != null) {
|
||||
@@ -56,7 +56,7 @@ public class GroovyNameSuggestionProvider implements NameSuggestionProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<LookupElement> completeName(PsiElement element, PsiElement nameSuggestionContext, String prefix) {
|
||||
public Collection<LookupElement> completeName(PsiElement element, @Nullable PsiElement nameSuggestionContext, String prefix) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -27,8 +27,8 @@ import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
@@ -110,8 +110,8 @@ public class GrMethodCallUsageInfo extends UsageInfo implements PossiblyIncorrec
|
||||
return ((GrReferenceExpression)expression).advancedResolve();
|
||||
}
|
||||
}
|
||||
else if (parent instanceof GrConstructorInvocation) {
|
||||
return ((GrConstructorInvocation)parent).resolveConstructorGenerics();
|
||||
else if (parent instanceof GrConstructorCall) {
|
||||
return ((GrConstructorCall)parent).resolveConstructorGenerics();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -59,7 +59,7 @@ class Foo implements SomeTrait {
|
||||
assertEmpty(make());
|
||||
}
|
||||
|
||||
public void _testRecompileDependentGroovyClasses() throws Exception {
|
||||
public void testRecompileDependentGroovyClasses() throws Exception {
|
||||
def a = myFixture.addFileToProject("A.gpp", """
|
||||
class A {
|
||||
void foo() {
|
||||
@@ -85,7 +85,7 @@ class A {
|
||||
assertOutput "b", "239"
|
||||
}
|
||||
|
||||
public void _testRecompileDependentJavaClasses() throws Exception {
|
||||
public void testRecompileDependentJavaClasses() throws Exception {
|
||||
def a = myFixture.addFileToProject("A.gpp", """
|
||||
class A {
|
||||
void foo() {
|
||||
@@ -93,15 +93,15 @@ class A {
|
||||
}
|
||||
}
|
||||
""")
|
||||
myFixture.addFileToProject("B.gpp", """
|
||||
myFixture.addFileToProject("B.java", """
|
||||
public class B {
|
||||
public static void main() {
|
||||
public static void main(String[] args) {
|
||||
new A().foo();
|
||||
}
|
||||
}
|
||||
""")
|
||||
assertEmpty make()
|
||||
assertOutput "b", "239"
|
||||
assertOutput "B", "239"
|
||||
|
||||
VfsUtil.saveText a.virtualFile, """
|
||||
class A {
|
||||
@@ -112,7 +112,7 @@ class A {
|
||||
"""
|
||||
|
||||
assertEmpty make()
|
||||
assertOutput "b", "239"
|
||||
assertOutput "B", "239"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest(LocalInspectionTool... tools) throws Exception {
|
||||
private void doTest(LocalInspectionTool... tools) {
|
||||
myFixture.enableInspections(tools);
|
||||
myFixture.testHighlighting(true, false, false, getTestName(false) + ".groovy");
|
||||
}
|
||||
@@ -280,4 +280,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase {
|
||||
}
|
||||
|
||||
public void testNumberDuplicatesInMaps() throws Exception {doTest();}
|
||||
|
||||
public void testMapNotAcceptedAsStringParameter() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -152,7 +152,7 @@ public class FindUsagesTest extends LightGroovyTestCase {
|
||||
assertEquals(1, query.findAll().size());
|
||||
}
|
||||
|
||||
private void doTestImpl(String filePath, int expectedUsagesCount) throws Throwable {
|
||||
private void doTestImpl(String filePath, int expectedUsagesCount) {
|
||||
myFixture.configureByFile(filePath);
|
||||
assertUsageCount(expectedUsagesCount);
|
||||
}
|
||||
@@ -197,7 +197,11 @@ public class FindUsagesTest extends LightGroovyTestCase {
|
||||
assertEquals(2, ReferencesSearch.search(file.getTopStatements()[0]).findAll().size());
|
||||
}
|
||||
|
||||
private void doSuperMethodTest(String... firstParameterTypes) throws Exception {
|
||||
public void testConstructorUsageInAnonymousClass() {
|
||||
doTestImpl("A.groovy", 1);
|
||||
}
|
||||
|
||||
private void doSuperMethodTest(String... firstParameterTypes) {
|
||||
myFixture.configureByFile(getTestName(false) + ".groovy");
|
||||
final GroovyFile file = (GroovyFile)myFixture.getFile();
|
||||
final GrTypeDefinition psiClass = (GrTypeDefinition)file.getClasses()[0];
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class Foo {
|
||||
|
||||
def Foo(int a) {
|
||||
}
|
||||
def F<caret>oo(){}
|
||||
}
|
||||
|
||||
def z = new Foo() {}
|
||||
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
void method(String m) {}
|
||||
|
||||
{
|
||||
method<warning descr="'method' in 'A' cannot be applied to '([:])'">([:])</warning>
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
void method(Map m, Closure e ) {}
|
||||
void method(String m) {}
|
||||
|
||||
{
|
||||
meth<ref>od([:])
|
||||
}
|
||||
|
||||
}
|
||||
@@ -154,7 +154,12 @@ public class FormReferenceProvider extends PsiReferenceProvider {
|
||||
classReference = referencesByString[referencesByString.length - 1];
|
||||
}
|
||||
|
||||
processReferences(rootTag, classReference, file, processor);
|
||||
final PsiReference finalClassReference = classReference;
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
processReferences(rootTag, finalClassReference, file, processor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static TextRange getValueRange(final XmlAttribute classToBind) {
|
||||
|
||||
@@ -72,6 +72,9 @@
|
||||
<extensionPoint name="compiler.additionalCompileScopeProvider"
|
||||
interface="com.intellij.compiler.impl.AdditionalCompileScopeProvider"/>
|
||||
|
||||
<extensionPoint name="compiler.makeDependencyProcessor"
|
||||
interface="com.intellij.compiler.DependencyProcessor"/>
|
||||
|
||||
<extensionPoint name="debugger.codeFragmentFactory"
|
||||
interface="com.intellij.debugger.engine.evaluation.CodeFragmentFactory"/>
|
||||
|
||||
|
||||
@@ -161,10 +161,6 @@
|
||||
<add-to-group group-id="RefactoringMenu" anchor="before" relative-to-action="IntroduceVariable"/>
|
||||
</group>
|
||||
|
||||
<action id="ExtractInterface" class="com.intellij.refactoring.extractInterface.ExtractInterfaceAction">
|
||||
<add-to-group group-id="RefactoringMenu" anchor="before" relative-to-action="ExtractSuperclass"/>
|
||||
</action>
|
||||
|
||||
<group id="RefactoringMenu4">
|
||||
<action id="TurnRefsToSuper" class="com.intellij.refactoring.actions.TurnRefsToSuperAction"/>
|
||||
<action id="InheritanceToDelegation" class="com.intellij.refactoring.actions.InheritanceToDelegationAction"/>
|
||||
|
||||
Reference in New Issue
Block a user