diff --git a/.idea/modules.xml b/.idea/modules.xml
index 52a0244f3249..553b6854a1ac 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -41,6 +41,7 @@
+
@@ -107,6 +108,7 @@
+
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index 75b46b1aa8ef..1985a382aaa9 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
includeTargets << new File("${guessHome(this)}/build/scripts/utils.gant")
@@ -100,7 +115,11 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir
dir("rt") {
fileset(dir: "${home}/lib/rt", includesfile: "${home}/lib/rt/required_for_dist.txt")
}
- jar("util.jar") { module("util") }
+
+ jar("util.jar") {
+ module("util")
+ module("util-rt")
+ }
jar("openapi.jar") {
openapiModules.each { module it}
@@ -231,6 +250,9 @@ public def layoutCommunityPlugins(String home) {
}
layoutPlugin("git4idea") {
+ jar("git4idea-rt.jar") {
+ module("git4idea-rt")
+ }
fileset(dir: "$home/plugins/git4idea/lib") {
include(name: "trilead-ssh2.jar")
}
@@ -468,6 +490,7 @@ def reorder(String home, String targetDirectory) {
classpath {
pathelement(location: util.output)
pathelement(location: "$home/lib/jna.jar")
+ pathelement(location: "$home/lib/trove4j.jar")
}
}
}
@@ -476,6 +499,7 @@ def reorder(String home, String targetDirectory) {
def layout_core(String home, String target) {
layout(target) {
jar("intellij-core.jar") {
+ module("util-rt")
module("util")
module("core-api")
module("core-impl")
diff --git a/build/update.xml b/build/update.xml
index 4bdc3584b15c..5372bd479360 100644
--- a/build/update.xml
+++ b/build/update.xml
@@ -49,8 +49,10 @@
+
+
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index 0d7a54633fec..54efeb29a62a 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -154,23 +154,25 @@ public class CompileDriver {
myGenerationCompilerModuleToOutputDirMap = new HashMap, Pair>();
- final LocalFileSystem lfs = LocalFileSystem.getInstance();
- final IntermediateOutputCompiler[] generatingCompilers = CompilerManager.getInstance(myProject).getCompilers(IntermediateOutputCompiler.class, myCompilerFilter);
- final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
- final CompilerConfiguration config = CompilerConfiguration.getInstance(project);
- for (Module module : allModules) {
- for (IntermediateOutputCompiler compiler : generatingCompilers) {
- final VirtualFile productionOutput = lookupVFile(lfs, CompilerPaths.getGenerationOutputPath(compiler, module, false));
- final VirtualFile testOutput = lookupVFile(lfs, CompilerPaths.getGenerationOutputPath(compiler, module, true));
- final Pair pair = new Pair(compiler, module);
- final Pair outputs = new Pair(productionOutput, testOutput);
- myGenerationCompilerModuleToOutputDirMap.put(pair, outputs);
- }
- if (config.isAnnotationProcessorsEnabled()) {
- if (config.isAnnotationProcessingEnabled(module)) {
- final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
- if (path != null) {
- lookupVFile(lfs, path); // ensure the file is created and added to VFS
+ if (!useCompileServer()) {
+ final LocalFileSystem lfs = LocalFileSystem.getInstance();
+ final IntermediateOutputCompiler[] generatingCompilers = CompilerManager.getInstance(myProject).getCompilers(IntermediateOutputCompiler.class, myCompilerFilter);
+ final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
+ final CompilerConfiguration config = CompilerConfiguration.getInstance(project);
+ for (Module module : allModules) {
+ for (IntermediateOutputCompiler compiler : generatingCompilers) {
+ final VirtualFile productionOutput = lookupVFile(lfs, CompilerPaths.getGenerationOutputPath(compiler, module, false));
+ final VirtualFile testOutput = lookupVFile(lfs, CompilerPaths.getGenerationOutputPath(compiler, module, true));
+ final Pair pair = new Pair(compiler, module);
+ final Pair outputs = new Pair(productionOutput, testOutput);
+ myGenerationCompilerModuleToOutputDirMap.put(pair, outputs);
+ }
+ if (config.isAnnotationProcessorsEnabled()) {
+ if (config.isAnnotationProcessingEnabled(module)) {
+ final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
+ if (path != null) {
+ lookupVFile(lfs, path); // ensure the file is created and added to VFS
+ }
}
}
}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
index e93a68fed095..f719d740ee5f 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -305,7 +305,7 @@ public class ArtifactsCompilerInstance extends GenericCompilerInstance createPathsHashSet() {
- return new THashSet(FileUtil.T_HASHING_STRATEGY);
+ return new THashSet(FileUtil.PATH_HASHING_STRATEGY);
}
@Override
diff --git a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteWindow.java b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteWindow.java
index f14a38242e12..18a485dc18e3 100644
--- a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteWindow.java
+++ b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteWindow.java
@@ -55,9 +55,11 @@ public class PaletteWindow extends JPanel implements DataProvider {
private PaletteGroupHeader myLastFocusedGroup;
@NonNls private static final String ourHelpID = "guiDesigner.uiTour.palette";
+ private PaletteManager myPaletteManager;
public PaletteWindow(Project project) {
myProject = project;
+ myPaletteManager = PaletteManager.getInstance(myProject);
myProviders = Extensions.getExtensions(PaletteItemProvider.EP_NAME, project);
for(PaletteItemProvider provider: myProviders) {
provider.addListener(myPropertyChangeListener);
@@ -180,7 +182,7 @@ public class PaletteWindow extends JPanel implements DataProvider {
group.getComponentList().clearSelection();
}
ListSelectionEvent event = new ListSelectionEvent(this, -1, -1, false);
- PaletteManager.getInstance(myProject).notifySelectionChanged(event);
+ myPaletteManager.notifySelectionChanged(event);
}
@Nullable public PaletteItem getActiveItem() {
@@ -252,7 +254,7 @@ public class PaletteWindow extends JPanel implements DataProvider {
break;
}
}
- PaletteManager.getInstance(myProject).notifySelectionChanged(e);
+ myPaletteManager.notifySelectionChanged(e);
}
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectStructureElementRenderer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectStructureElementRenderer.java
index 06bb5ec7731b..54037ea58236 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectStructureElementRenderer.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectStructureElementRenderer.java
@@ -53,8 +53,7 @@ class ProjectStructureElementRenderer extends ColoredTreeCellRenderer {
setToolTipText(null);
setFont(UIUtil.getTreeFont());
- SimpleTextAttributes textAttributes =
- selected && hasFocus ? SimpleTextAttributes.SELECTED_SIMPLE_CELL_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES;
+ SimpleTextAttributes textAttributes = SimpleTextAttributes.REGULAR_ATTRIBUTES;
if (node.isDisplayInBold()) {
textAttributes = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
}
@@ -74,6 +73,13 @@ class ProjectStructureElementRenderer extends ColoredTreeCellRenderer {
textAttributes = textAttributes.derive(style, foreground, null, waveColor);
setToolTipText(problemsHolder.composeTooltipMessage());
}
+
+ append(displayName, textAttributes);
+ String description = projectStructureElement.getDescription();
+ if (description != null) {
+ append(" (" + description + ")", SimpleTextAttributes.GRAY_ATTRIBUTES, false);
+ }
+ return;
}
}
append(displayName, textAttributes);
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureElement.java
index f9e866962e79..fed82781265d 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureElement.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureElement.java
@@ -18,6 +18,11 @@ public abstract class ProjectStructureElement {
public abstract String getPresentableName();
+ @Nullable
+ public String getDescription() {
+ return null;
+ }
+
public abstract String getTypeName();
public abstract String getId();
diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
index 6299468b345b..331db279750b 100644
--- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
+++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
@@ -16,10 +16,11 @@
package com.intellij.util.descriptors.impl;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.vfs.*;
-import com.intellij.openapi.Disposable;
import com.intellij.util.EventDispatcher;
import com.intellij.util.descriptors.*;
import org.jetbrains.annotations.Nullable;
@@ -135,6 +136,7 @@ public class ConfigFileContainerImpl implements ConfigFileContainer {
}
for (ConfigFileInfo configuration : newDescriptors) {
final ConfigFileImpl configFile = new ConfigFileImpl(this, configuration);
+ Disposer.register(this, configFile);
myConfigFiles.put(metaData, configFile);
added.add(configFile);
}
@@ -142,6 +144,7 @@ public class ConfigFileContainerImpl implements ConfigFileContainer {
for (ConfigFile descriptor : toDelete) {
myConfigFiles.remove(descriptor.getMetaData(), descriptor);
+ Disposer.dispose(descriptor);
}
myCachedConfigFiles = null;
diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java
index fcee66b35973..a64cc6c8a313 100644
--- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java
+++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java
@@ -1,4 +1,3 @@
-
package com.intellij.util.descriptors.impl;
import com.intellij.openapi.project.Project;
@@ -22,43 +21,38 @@ import org.jetbrains.annotations.Nullable;
*/
public class ConfigFileImpl implements ConfigFile {
@NotNull private ConfigFileInfo myInfo;
- private VirtualFilePointer myFilePointer;
- private PsiFile myPsiFile;
+ private final VirtualFilePointer myFilePointer;
+ private volatile PsiFile myPsiFile;
private final ConfigFileContainerImpl myContainer;
private final Project myProject;
private long myModificationCount;
- private final Object myPsiFileLock = new Object();
- private final VirtualFilePointerListener myListener = new VirtualFilePointerListener() {
- public void beforeValidityChanged(final VirtualFilePointer[] pointers) {
- }
-
- public void validityChanged(final VirtualFilePointer[] pointers) {
- synchronized (myPsiFileLock) {
- myPsiFile = null;
- }
- onChange();
- }
- };
public ConfigFileImpl(@NotNull final ConfigFileContainerImpl container, @NotNull final ConfigFileInfo configuration) {
myContainer = container;
myInfo = configuration;
- setUrl(configuration.getUrl());
+ final VirtualFilePointerManager pointerManager = VirtualFilePointerManager.getInstance();
+ myFilePointer = pointerManager.create(configuration.getUrl(), this, new VirtualFilePointerListener() {
+ @Override
+ public void beforeValidityChanged(final VirtualFilePointer[] pointers) {
+ }
+
+ @Override
+ public void validityChanged(final VirtualFilePointer[] pointers) {
+ myPsiFile = null;
+ onChange();
+ }
+ });
+ onChange();
Disposer.register(container, this);
myProject = myContainer.getProject();
}
- private void setUrl(String url) {
- final VirtualFilePointerManager pointerManager = VirtualFilePointerManager.getInstance();
- myFilePointer = pointerManager.create(url, this, myListener);
- onChange();
- }
-
private void onChange() {
myModificationCount++;
myContainer.fireDescriptorChanged(this);
}
+ @Override
public String getUrl() {
return myFilePointer.getUrl();
}
@@ -67,17 +61,16 @@ public class ConfigFileImpl implements ConfigFile {
myInfo = info;
}
+ @Override
@Nullable
public VirtualFile getVirtualFile() {
return myFilePointer.getFile();
}
+ @Override
@Nullable
public PsiFile getPsiFile() {
- PsiFile psiFile;
- synchronized (myPsiFileLock) {
- psiFile = myPsiFile;
- }
+ PsiFile psiFile = myPsiFile;
if (psiFile != null && psiFile.isValid()) {
return psiFile;
@@ -88,27 +81,29 @@ public class ConfigFileImpl implements ConfigFile {
psiFile = PsiManager.getInstance(myProject).findFile(virtualFile);
- synchronized (myPsiFileLock) {
- myPsiFile = psiFile;
- }
+ myPsiFile = psiFile;
return psiFile;
}
+ @Override
@Nullable
public XmlFile getXmlFile() {
final PsiFile file = getPsiFile();
return file instanceof XmlFile ? (XmlFile)file : null;
}
+ @Override
public void dispose() {
}
+ @Override
@NotNull
public ConfigFileInfo getInfo() {
return myInfo;
}
+ @Override
public boolean isValid() {
final PsiFile psiFile = getPsiFile();
if (psiFile == null || !psiFile.isValid()) {
@@ -122,12 +117,14 @@ public class ConfigFileImpl implements ConfigFile {
}
+ @Override
@NotNull
public ConfigFileMetaData getMetaData() {
return myInfo.getMetaData();
}
+ @Override
public long getModificationCount() {
return myModificationCount;
}
diff --git a/java/java-impl/src/com/intellij/application/options/CodeStyleImportsPanel.java b/java/java-impl/src/com/intellij/application/options/CodeStyleImportsPanel.java
index 083ff43a44db..8a042c1a6ae0 100644
--- a/java/java-impl/src/com/intellij/application/options/CodeStyleImportsPanel.java
+++ b/java/java-impl/src/com/intellij/application/options/CodeStyleImportsPanel.java
@@ -29,6 +29,8 @@ import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
@@ -291,6 +293,7 @@ public class CodeStyleImportsPanel extends JPanel {
PackageEntry entry = new PackageEntry(false,"", true);
myImportLayoutList.insertEntryAt(entry, selected);
refreshTableModel(selected, myImportLayoutTable);
+ updateButtons();
}
private static void refreshTableModel(int selectedRow, JBTable table) {
@@ -323,6 +326,7 @@ public class CodeStyleImportsPanel extends JPanel {
AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
model.fireTableRowsInserted(selected, selected);
myImportLayoutTable.setRowSelectionInterval(selected, selected);
+ updateButtons();
}
private void removeEntryFromImportLayouts() {
@@ -343,6 +347,7 @@ public class CodeStyleImportsPanel extends JPanel {
if(selected >= 0) {
myImportLayoutTable.setRowSelectionInterval(selected, selected);
}
+ updateButtons();
}
private void removeEntryFromPackages() {
@@ -358,6 +363,7 @@ public class CodeStyleImportsPanel extends JPanel {
if(selected >= 0) {
myPackageTable.setRowSelectionInterval(selected, selected);
}
+ updateButtons();
}
private void moveRowUp() {
@@ -374,6 +380,7 @@ public class CodeStyleImportsPanel extends JPanel {
AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
model.fireTableRowsUpdated(selected-1, selected);
myImportLayoutTable.setRowSelectionInterval(selected-1, selected-1);
+ updateButtons();
}
private void moveRowDown() {
@@ -390,6 +397,7 @@ public class CodeStyleImportsPanel extends JPanel {
AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
model.fireTableRowsUpdated(selected, selected+1);
myImportLayoutTable.setRowSelectionInterval(selected+1, selected+1);
+ updateButtons();
}
private JBTable createTableForPackageEntries(final PackageEntryTable packageTable) {
@@ -473,6 +481,12 @@ public class CodeStyleImportsPanel extends JPanel {
final JBTable result = new JBTable(dataModel);
result.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
resizeColumns(packageTable, result);
+ result.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ updateButtons();
+ }
+ });
TableCellEditor editor = result.getDefaultEditor(String.class);
if (editor instanceof DefaultCellEditor) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
index 1cb0667bd7e8..669905ed006e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
@@ -112,9 +112,11 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
PsiType type = JavaCompletionUtil.getLookupElementType(base);
if (type != null && !PsiType.VOID.equals(type)) {
PsiReferenceExpression ref = ReferenceExpressionCompletionContributor.createMockReference(position, type, base);
- for (final LookupElement item : JavaSmartCompletionContributor.completeReference(position, ref, filter, true, true, parameters,
- result.getPrefixMatcher())) {
- qualifiedCollector.addElement(new JavaChainLookupElement(base, item));
+ if (ref != null) {
+ for (final LookupElement item : JavaSmartCompletionContributor.completeReference(position, ref, filter, true, true, parameters,
+ result.getPrefixMatcher())) {
+ qualifiedCollector.addElement(new JavaChainLookupElement(base, item));
+ }
}
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java
index 5033f6a629cd..e1f28cd2b85a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java
@@ -25,8 +25,8 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.patterns.PsiMethodPattern;
+import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -46,7 +46,10 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
@@ -57,7 +60,7 @@ import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
public class ReferenceExpressionCompletionContributor {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.ReferenceExpressionCompletionContributor");
private static final PsiMethodPattern OBJECT_METHOD_PATTERN = psiMethod().withName(
- PsiJavaPatterns.string().oneOf("hashCode", "equals", "finalize", "wait", "notify", "notifyAll", "getClass", "clone", "toString")).
+ StandardPatterns.string().oneOf("hashCode", "equals", "finalize", "wait", "notify", "notifyAll", "getClass", "clone", "toString")).
definedInClass(CommonClassNames.JAVA_LANG_OBJECT);
private static final PrefixMatcher TRUE_MATCHER = new PrefixMatcher("") {
@Override
@@ -83,9 +86,9 @@ public class ReferenceExpressionCompletionContributor {
}
if (psiElement().inside(
- PsiJavaPatterns.or(
- psiElement(PsiAnnotationParameterList.class),
- psiElement(PsiSwitchLabelStatement.class))
+ StandardPatterns.or(
+ psiElement(PsiAnnotationParameterList.class),
+ psiElement(PsiSwitchLabelStatement.class))
).accepts(element)) {
return new ElementExtractorFilter(new AndFilter(
new ClassFilter(PsiField.class),
@@ -426,27 +429,37 @@ public class ReferenceExpressionCompletionContributor {
PsiType qualifierType,
final PsiType expectedType, JavaSmartCompletionParameters parameters) throws IncorrectOperationException {
final PsiReferenceExpression mockRef = createMockReference(place, qualifierType, qualifierItem);
+ if (mockRef == null) {
+ return;
+ }
final ElementFilter filter = getReferenceFilter(place, true);
for (final LookupElement item : completeFinalReference(place, mockRef, filter, parameters)) {
- if (shoudChain(place, qualifierType, expectedType, item)) {
+ if (shouldChain(place, qualifierType, expectedType, item)) {
result.consume(new JavaChainLookupElement(qualifierItem, item));
}
}
}
+ @Nullable
public static PsiReferenceExpression createMockReference(final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) {
PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject());
if (qualifierItem.getObject() instanceof PsiClass) {
- return (PsiReferenceExpression)factory
- .createExpressionFromText(((PsiClass)qualifierItem.getObject()).getQualifiedName() + ".xxx", place);
+ try {
+ return (PsiReferenceExpression)factory
+ .createExpressionFromText(((PsiClass)qualifierItem.getObject()).getQualifiedName() + ".xxx", place);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.info(e);
+ return null;
+ }
}
return (PsiReferenceExpression) factory.createExpressionFromText("xxx.xxx", JavaCompletionUtil
.createContextWithXxxVariable(place, qualifierType));
}
- private static boolean shoudChain(PsiElement element, PsiType qualifierType, PsiType expectedType, LookupElement item) {
+ private static boolean shouldChain(PsiElement element, PsiType qualifierType, PsiType expectedType, LookupElement item) {
if (item.getObject() instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)item.getObject();
if (psiMethod().withName("toArray").withParameterCount(1)
diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java
index ba8fffebe15c..5ab99de764ed 100644
--- a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java
+++ b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java
@@ -20,6 +20,7 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.jsp.jspXml.JspDirective;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.xml.XmlFile;
+import org.jetbrains.annotations.NotNull;
public class JavaCodeBlockModificationListener implements PsiTreeChangePreprocessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.JavaCodeBlockModificationListener");
@@ -31,7 +32,7 @@ public class JavaCodeBlockModificationListener implements PsiTreeChangePreproces
}
@Override
- public void treeChanged(final PsiTreeChangeEventImpl event) {
+ public void treeChanged(@NotNull final PsiTreeChangeEventImpl event) {
switch (event.getCode()) {
case BEFORE_CHILDREN_CHANGE:
case BEFORE_PROPERTY_CHANGE:
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
index 31a4851df62c..d4dcd96dd43f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
@@ -272,7 +272,7 @@ public class PsiImplUtil {
return new PsiImmediateClassType(classClass, substitutor);
}
- public static PsiAnnotation findAnnotation(@NotNull PsiAnnotationOwner modifierList, @NotNull String qualifiedName) {
+ @Nullable public static PsiAnnotation findAnnotation(@NotNull PsiAnnotationOwner modifierList, @NotNull String qualifiedName) {
final String shortName = StringUtil.getShortName(qualifiedName);
PsiAnnotation[] annotations = modifierList.getAnnotations();
for (PsiAnnotation annotation : annotations) {
@@ -368,7 +368,7 @@ public class PsiImplUtil {
}
else if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
PsiClass topClass = PsiUtil.getTopLevelClass(member);
- return topClass != null ? new LocalSearchScope(topClass) : new LocalSearchScope(file);
+ return topClass != null ? new LocalSearchScope(topClass) : file != null ? new LocalSearchScope(file) : maximalUseScope;
}
else {
if (file instanceof PsiJavaFile) {
@@ -388,7 +388,7 @@ public class PsiImplUtil {
return getServerPageFile(element) != null;
}
- public static ServerPageFile getServerPageFile(final PsiElement element) {
+ @Nullable public static ServerPageFile getServerPageFile(final PsiElement element) {
final PsiFile psiFile = PsiUtilCore.getTemplateLanguageFile(element);
return psiFile instanceof ServerPageFile ? (ServerPageFile)psiFile : null;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
index d44097d038d4..962d7cb9256a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
@@ -144,7 +144,7 @@ public class PsiScopesUtil {
public static boolean resolveAndWalk(PsiScopeProcessor processor,
PsiJavaCodeReferenceElement ref,
- PsiElement maxScope,
+ @Nullable PsiElement maxScope,
boolean incompleteCode) {
final PsiElement qualifier = ref.getQualifier();
final PsiElement classNameElement = ref.getReferenceNameElement();
diff --git a/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy b/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy
index a996ce26aecf..3ad83a0f32bd 100644
--- a/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy
@@ -17,7 +17,9 @@ package com.intellij.psi
import com.intellij.openapi.application.ApplicationManager
import com.intellij.psi.impl.source.PsiFileImpl
+import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+import com.intellij.reference.SoftReference
/**
* @author peter
@@ -30,13 +32,29 @@ class StubAstSwitchTest extends LightCodeInsightFixtureTestCase {
def cls = ((PsiJavaFile)file).classes[0]
assert file.stub
+ def oldCount = psiManager.modificationTracker.javaStructureModificationCount
+
ApplicationManager.application.runWriteAction { file.virtualFile.setBinaryContent(file.virtualFile.contentsToByteArray()) }
assert file.stub
- //todo
- //either: assert !cls.valid
- //or: assert cls == PsiTreeUtil.findElementOfClassAtOffset(file, 1, PsiClass, false)
- //assert !file.stub
+ assert psiManager.modificationTracker.javaStructureModificationCount != oldCount
+ assert !cls.valid
+ assert cls != PsiTreeUtil.findElementOfClassAtOffset(file, 1, PsiClass, false)
+ assert !file.stub
+ }
+
+ public void "test reachable psi classes remain valid when nothing changes"() {
+ int count = 1000
+ List> classList = (0.. affectedBeforeDif = new HashSet(allAffectedFiles);
+ final ModulesBasedFileFilter moduleBasedFilter = new ModulesBasedFileFilter(context, chunk);
final boolean incremental = globalMappings.differentiate(
- delta, removedPaths, filesToCompile, allCompiledFiles, allAffectedFiles
+ delta, removedPaths, filesToCompile, allCompiledFiles, allAffectedFiles, moduleBasedFilter
);
if (LOG.isDebugEnabled()) {
@@ -103,13 +104,13 @@ public abstract class ModuleLevelBuilder extends Builder {
if (!newlyAffectedFiles.isEmpty()) {
-
if (LOG.isDebugEnabled()) {
- final List> wrongFiles = checkAffectedFilesInCorrectModules(context, chunk, newlyAffectedFiles);
+ final List> wrongFiles = checkAffectedFilesInCorrectModules(context, newlyAffectedFiles, moduleBasedFilter);
if (!wrongFiles.isEmpty()) {
LOG.debug("Wrong affected files for module chunk " + chunk.getName() + ": ");
for (Pair pair : wrongFiles) {
- LOG.debug("\t[" + pair.second.getName() + "] " + pair.first.getPath());
+ final String name = pair.second != null? pair.second.getName() : "null";
+ LOG.debug("\t[" + name + "] " + pair.first.getPath());
}
}
}
@@ -146,45 +147,20 @@ public abstract class ModuleLevelBuilder extends Builder {
}
}
-
- private static List> checkAffectedFilesInCorrectModules(CompileContext context, ModuleChunk currentChunk, Collection affected) {
+ private static List> checkAffectedFilesInCorrectModules(CompileContext context, Collection affected, ModulesBasedFileFilter moduleBasedFilter) {
if (affected.isEmpty()) {
return Collections.emptyList();
}
-
- final Set chunkModules = currentChunk.getModules();
- final Map> cache = new HashMap>();
final List> result = new ArrayList>();
-
for (File file : affected) {
- final RootDescriptor moduleAndRoot = context.getModuleAndRoot(file);
- if (moduleAndRoot == null) {
- continue;
+ if (!moduleBasedFilter.accept(file)) {
+ final RootDescriptor moduleAndRoot = context.getModuleAndRoot(file);
+ result.add(Pair.create(file, moduleAndRoot != null? moduleAndRoot.module : null));
}
- final Module moduleOfFile = moduleAndRoot.module;
- if (chunkModules.contains(moduleOfFile)) {
- continue;
- }
- Set moduleOfFileWithDependencies = cache.get(moduleOfFile);
- if (moduleOfFileWithDependencies == null) {
- moduleOfFileWithDependencies = ProjectPaths.getModulesWithDependentsRecursively(moduleOfFile, true);
- cache.put(moduleOfFile, moduleOfFileWithDependencies);
- }
- if (intersects(moduleOfFileWithDependencies, chunkModules)) {
- continue;
- }
- result.add(Pair.create(file, moduleOfFile));
}
return result;
}
- private static boolean intersects(Set set1, Set set2) {
- if (set1.size() < set2.size()) {
- return new HashSet(set1).removeAll(set2);
- }
- return new HashSet(set2).removeAll(set1);
- }
-
private static boolean chunkContainsAffectedFiles(CompileContext context, ModuleChunk chunk, final Set affected) throws IOException {
final Set chunkModules = new HashSet(chunk.getModules());
if (!chunkModules.isEmpty()) {
@@ -221,4 +197,40 @@ public abstract class ModuleLevelBuilder extends Builder {
return removed != null? removed : Collections.emptySet();
}
+ private static class ModulesBasedFileFilter implements Mappings.DependentFilesFilter{
+ private final CompileContext myContext;
+ private final Set myChunkModules;
+ private final Map> myCache = new HashMap>();
+
+ private ModulesBasedFileFilter(CompileContext context, ModuleChunk chunk) {
+ myContext = context;
+ myChunkModules = chunk.getModules();
+ }
+
+ @Override
+ public boolean accept(File file) {
+ final RootDescriptor moduleAndRoot = myContext.getModuleAndRoot(file);
+ if (moduleAndRoot == null) {
+ return true;
+ }
+ final Module moduleOfFile = moduleAndRoot.module;
+ if (myChunkModules.contains(moduleOfFile)) {
+ return true;
+ }
+ Set moduleOfFileWithDependencies = myCache.get(moduleOfFile);
+ if (moduleOfFileWithDependencies == null) {
+ moduleOfFileWithDependencies = ProjectPaths.getModulesWithDependentsRecursively(moduleOfFile, true);
+ myCache.put(moduleOfFile, moduleOfFileWithDependencies);
+ }
+ return intersects(moduleOfFileWithDependencies, myChunkModules);
+ }
+
+ private static boolean intersects(Set set1, Set set2) {
+ if (set1.size() < set2.size()) {
+ return new HashSet(set1).removeAll(set2);
+ }
+ return new HashSet(set2).removeAll(set1);
+ }
+ }
+
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java
index 65ba0c22b12d..ffc4b7efff97 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java
@@ -23,13 +23,13 @@ import com.intellij.uiDesigner.compiler.AlienFormFileException;
import com.intellij.uiDesigner.core.GridConstraints;
import com.jgoodies.forms.layout.CellConstraints;
import com.sun.jna.Pointer;
-import com.sun.jna.platform.FileMonitor;
import gnu.trove.TIntHash;
import net.n3.nanoxml.IXMLBuilder;
import org.codehaus.groovy.GroovyException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.MacroExpander;
import org.jetbrains.jps.javac.JavacServer;
+import com.intellij.openapi.util.io.FileUtilRt;
import org.objectweb.asm.ClassWriter;
import javax.tools.*;
@@ -91,10 +91,10 @@ public class ClasspathBootstrap {
cp.add(getResourcePath(com.google.protobuf.Message.class)); // protobuf
cp.add(getResourcePath(org.jboss.netty.bootstrap.Bootstrap.class)); // netty
cp.add(getResourcePath(TIntHash.class)); // trove
+ cp.add(getResourcePath(FileUtilRt.class)); // util-rt module
cp.add(getResourcePath(FileUtil.class)); // util module
cp.add(getResourcePath(Pointer.class)); // jna.jar
cp.add(getResourcePath(CacheBuilder.class)); // guava
- cp.add(getResourcePath(FileMonitor.class)); // jna-utils.jar
cp.add(getResourcePath(ClassWriter.class)); // asm
cp.add(getResourcePath(org.objectweb.asm.commons.EmptyVisitor.class)); // asm-commons
cp.add(getResourcePath(MacroExpander.class)); // jps-model
@@ -136,10 +136,10 @@ public class ClasspathBootstrap {
cp.add(getResourcePath(com.google.protobuf.Message.class)); // protobuf
cp.add(getResourcePath(org.jboss.netty.bootstrap.Bootstrap.class)); // netty
cp.add(getResourcePath(TIntHash.class)); // trove
+ cp.add(getResourcePath(FileUtilRt.class)); // util-rt module
cp.add(getResourcePath(FileUtil.class)); // util module
cp.add(getResourcePath(Pointer.class)); // jna.jar
cp.add(getResourcePath(CacheBuilder.class)); // guava
- cp.add(getResourcePath(FileMonitor.class)); // jna-utils.jar
cp.add(getResourcePath(org.jdom.input.SAXBuilder.class)); // jdom
final Class optimizedFileManagerClass = getOptimizedFileManagerClass();
diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java
index d6190d61d815..7ff64fdb13bc 100644
--- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java
+++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java
@@ -806,7 +806,10 @@ public class Mappings {
}
}
- private boolean incrementalDecision(final DependencyContext.S owner, final Proto member, final Collection affectedFiles) {
+ private boolean incrementalDecision(final DependencyContext.S owner,
+ final Proto member,
+ final Collection affectedFiles,
+ DependentFilesFilter filter) {
final boolean isField = member instanceof FieldRepr;
final Util self = new Util(this);
@@ -842,19 +845,33 @@ public class Mappings {
if (ClassRepr.getPackageName(myContext.getValue(className)).equals(packageName)) {
final String f = myContext.getValue(fileName);
- debug("Adding: ", f);
- affectedFiles.add(new File(f));
+ final File file = new File(f);
+ if (filter.accept(file)) {
+ debug("Adding: ", f);
+ affectedFiles.add(file);
+ }
}
}
return true;
}
+ public interface DependentFilesFilter {
+ DependentFilesFilter ALL_FILES = new DependentFilesFilter() {
+ @Override
+ public boolean accept(File file) {
+ return true;
+ }
+ };
+
+ boolean accept(File file);
+ }
+
public boolean differentiate(final Mappings delta,
final Collection removed,
final Collection filesToCompile,
final Collection compiledFiles,
- final Collection affectedFiles) {
+ final Collection affectedFiles, DependentFilesFilter filter) {
synchronized (myLock) {
debug("Begin of Differentiate:");
@@ -926,7 +943,7 @@ public class Mappings {
if (it.isAnnotation() && it.policy == RetentionPolicy.SOURCE) {
debug("Annotation, retention policy = SOURCE => a switch to non-incremental mode requested");
- if (!incrementalDecision(it.outerClassName, it, affectedFiles)) {
+ if (!incrementalDecision(it.outerClassName, it, affectedFiles, filter)) {
debug("End of Differentiate, returning false");
return false;
}
@@ -970,7 +987,7 @@ public class Mappings {
if (removedtargets.contains(ElementType.LOCAL_VARIABLE)) {
debug("Removed target contains LOCAL_VARIABLE => a switch to non-incremental mode requested");
- if (!incrementalDecision(it.outerClassName, it, affectedFiles)) {
+ if (!incrementalDecision(it.outerClassName, it, affectedFiles, filter)) {
debug("End of Differentiate, returning false");
return false;
}
@@ -1396,7 +1413,7 @@ public class Mappings {
if ((f.access & Opcodes.ACC_PRIVATE) == 0 && (f.access & mask) == mask && f.hasValue()) {
debug("Field had value and was (non-private) final static => a switch to non-incremental mode requested");
- if (!incrementalDecision(it.name, f, affectedFiles)) {
+ if (!incrementalDecision(it.name, f, affectedFiles, filter)) {
debug("End of Differentiate, returning false");
return false;
}
@@ -1417,7 +1434,7 @@ public class Mappings {
if ((field.access & Opcodes.ACC_PRIVATE) == 0 && (field.access & mask) == mask) {
if ((d.base() & Difference.ACCESS) > 0 || (d.base() & Difference.VALUE) > 0) {
debug("Inline field changed it's access or value => a switch to non-incremental mode requested");
- if (!incrementalDecision(it.name, field, affectedFiles)) {
+ if (!incrementalDecision(it.name, field, affectedFiles, filter)) {
debug("End of Differentiate, returning false");
return false;
}
@@ -1633,40 +1650,46 @@ public class Mappings {
if (delta.isDifferentiated()) {
for (DependencyContext.S c : delta.getChangedClasses()) {
- myClassToSubclasses.remove(c);
-
final Collection subClasses = delta.myClassToSubclasses.get(c);
-
if (subClasses != null) {
- myClassToSubclasses.put(c, subClasses);
+ myClassToSubclasses.replace(c, subClasses);
+ }
+ else {
+ myClassToSubclasses.remove(c);
}
- myClassToSourceFile.remove(c);
-
final DependencyContext.S sourceFile = delta.myClassToSourceFile.get(c);
-
if (sourceFile != null) {
myClassToSourceFile.put(c, sourceFile);
}
+ else {
+ myClassToSourceFile.remove(c);
+ }
}
for (DependencyContext.S f : delta.getChangedFiles()) {
- mySourceFileToClasses.remove(f);
final Collection classes = delta.mySourceFileToClasses.get(f);
if (classes != null) {
- mySourceFileToClasses.put(f, classes);
+ mySourceFileToClasses.replace(f, classes);
+ }
+ else {
+ mySourceFileToClasses.remove(f);
}
- mySourceFileToUsages.remove(f);
final Collection clusters = delta.mySourceFileToUsages.get(f);
if (clusters != null) {
- mySourceFileToUsages.put(f, clusters);
+ mySourceFileToUsages.replace(f, clusters);
+ }
+ else {
+ mySourceFileToUsages.remove(f);
}
- mySourceFileToAnnotationUsages.remove(f);
final Collection usages = delta.mySourceFileToAnnotationUsages.get(f);
if (usages != null) {
- mySourceFileToAnnotationUsages.put(f, usages);
+ mySourceFileToAnnotationUsages.replace(f, usages);
+ }
+ else {
+ mySourceFileToAnnotationUsages.remove(f);
}
}
}
@@ -1711,8 +1734,7 @@ public class Mappings {
changed |= past.addAll(now);
if (changed) {
- myClassToClassDependency.remove(aClass);
- myClassToClassDependency.put(aClass, past);
+ myClassToClassDependency.replace(aClass, past);
}
}
}
diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/MultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/MultiMaplet.java
index a7152b3684dc..15a2875086e3 100644
--- a/jps/model/src/org/jetbrains/ether/dependencyView/MultiMaplet.java
+++ b/jps/model/src/org/jetbrains/ether/dependencyView/MultiMaplet.java
@@ -30,6 +30,7 @@ interface MultiMaplet {
Collection get(final K key);
void put(final K key, final V value);
void put(final K key, final Collection value);
+ void replace(final K key, final Collection value);
void putAll(MultiMaplet m);
void replaceAll(MultiMaplet m);
void remove(final K key);
diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java
index f1d288696244..e5497ab73994 100644
--- a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java
+++ b/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java
@@ -66,6 +66,21 @@ class PersistentMultiMaplet implements MultiMaplet {
}
}
+ @Override
+ public void replace(K key, Collection value) {
+ try {
+ if (value == null) {
+ myMap.remove(key);
+ }
+ else {
+ myMap.put(key, value);
+ }
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
@Override
public void put(final K key, final Collection value) {
try {
@@ -149,9 +164,7 @@ class PersistentMultiMaplet implements MultiMaplet {
@Override
public void replaceAll(MultiMaplet m) {
for (Map.Entry> entry : m.entrySet()) {
- final K key = entry.getKey();
- remove(key);
- put(key, entry.getValue());
+ replace(entry.getKey(), entry.getValue());
}
}
diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/TransientMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/TransientMultiMaplet.java
index 7a5f2b85eb90..71aafd8696c8 100644
--- a/jps/model/src/org/jetbrains/ether/dependencyView/TransientMultiMaplet.java
+++ b/jps/model/src/org/jetbrains/ether/dependencyView/TransientMultiMaplet.java
@@ -72,6 +72,16 @@ class TransientMultiMaplet implements MultiMaplet {
}
}
+ @Override
+ public void replace(K key, Collection value) {
+ if (value == null) {
+ myMap.remove(key);
+ }
+ else {
+ myMap.put(key, value);
+ }
+ }
+
@Override
public void put(final K key, final V value) {
final Collection x = constr.create();
@@ -111,8 +121,7 @@ class TransientMultiMaplet implements MultiMaplet {
@Override
public void replaceAll(MultiMaplet m) {
for (Map.Entry> e : m.entrySet()) {
- remove(e.getKey());
- put(e.getKey(), e.getValue());
+ replace(e.getKey(), e.getValue());
}
}
diff --git a/jps/src/org/jetbrains/ether/ProjectWrapper.java b/jps/src/org/jetbrains/ether/ProjectWrapper.java
index 01811ee5a439..05c22f89ada4 100644
--- a/jps/src/org/jetbrains/ether/ProjectWrapper.java
+++ b/jps/src/org/jetbrains/ether/ProjectWrapper.java
@@ -1163,7 +1163,8 @@ public class ProjectWrapper {
final Collection affected = new HashSet();
- final boolean incremental = dependencyMapping.differentiate(delta, removed, files, compiled, affected);
+ final boolean incremental = dependencyMapping.differentiate(delta, removed, files, compiled, affected,
+ Mappings.DependentFilesFilter.ALL_FILES);
for (File a : affected) {
affectedFiles.add(FileUtil.toSystemIndependentName(a.getAbsolutePath()));
diff --git a/platform/core-api/src/com/intellij/psi/PsiElement.java b/platform/core-api/src/com/intellij/psi/PsiElement.java
index f26dbf06b44d..99bc7789c90c 100644
--- a/platform/core-api/src/com/intellij/psi/PsiElement.java
+++ b/platform/core-api/src/com/intellij/psi/PsiElement.java
@@ -269,7 +269,7 @@ public interface PsiElement extends UserDataHolder, Iconable {
* @return the element which was actually added (either element or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
- PsiElement addBefore(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException;
+ PsiElement addBefore(@NotNull PsiElement element, @Nullable PsiElement anchor) throws IncorrectOperationException;
/**
* Adds a child to this PSI element, after the specified anchor element.
@@ -279,7 +279,7 @@ public interface PsiElement extends UserDataHolder, Iconable {
* @return the element which was actually added (either element or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
- PsiElement addAfter(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException;
+ PsiElement addAfter(@NotNull PsiElement element, @Nullable PsiElement anchor) throws IncorrectOperationException;
/**
* Checks if it is possible to add the specified element as a child to this element,
diff --git a/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
index c092c70e2d10..9c751afbed35 100644
--- a/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
+++ b/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
@@ -41,11 +41,11 @@ public class LocalSearchScope extends SearchScope {
public static final LocalSearchScope EMPTY = new LocalSearchScope(PsiElement.EMPTY_ARRAY);
private String myDisplayName;
- public LocalSearchScope(PsiElement scope) {
+ public LocalSearchScope(@NotNull PsiElement scope) {
this(scope, null);
}
- public LocalSearchScope(PsiElement scope, String displayName) {
+ public LocalSearchScope(@NotNull PsiElement scope, @Nullable String displayName) {
this(new PsiElement[]{scope});
myDisplayName = displayName;
}
@@ -54,16 +54,17 @@ public class LocalSearchScope extends SearchScope {
this(scope, null);
}
- public LocalSearchScope(PsiElement[] scope, String displayName) {
+ public LocalSearchScope(PsiElement[] scope, @Nullable String displayName) {
this(scope, displayName, false);
}
- public LocalSearchScope(final PsiElement[] scope, final String displayName, final boolean ignoreInjectedPsi) {
+ public LocalSearchScope(final PsiElement[] scope, @Nullable final String displayName, final boolean ignoreInjectedPsi) {
myIgnoreInjectedPsi = ignoreInjectedPsi;
myDisplayName = displayName;
Set localScope = new LinkedHashSet(scope.length);
for (final PsiElement element : scope) {
+ LOG.assertTrue(element != null, "null element");
LOG.assertTrue(element.getContainingFile() != null, element.getClass().getName());
if (element instanceof PsiFile) {
List files = ((PsiFile)element).getViewProvider().getAllFiles();
diff --git a/platform/core-impl/src/com/intellij/core/CoreASTFactory.java b/platform/core-impl/src/com/intellij/core/CoreASTFactory.java
index 5e91b4fc3e57..a70a1eb13b1f 100644
--- a/platform/core-impl/src/com/intellij/core/CoreASTFactory.java
+++ b/platform/core-impl/src/com/intellij/core/CoreASTFactory.java
@@ -60,6 +60,7 @@ public class CoreASTFactory extends ASTFactory implements DefaultASTFactory {
return new LeafPsiElement(type, text);
}
+ @Override
public LeafElement createComment(IElementType type, CharSequence text) {
return new PsiCoreCommentImpl(type, text);
}
diff --git a/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java b/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java
index 83dd5c3e9abd..1477e2344d70 100644
--- a/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java
+++ b/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java
@@ -111,7 +111,7 @@ public class StubBasedPsiElementBase extends ASTDelegateP
"; stubTree=" + stubTree;
PsiElement each = this;
while (each != null) {
- message += "\n each=" + each + " of class " + each.getClass();
+ message += "\n each of class " + each.getClass();
if (each instanceof StubBasedPsiElementBase) {
message += "; node=" + ((StubBasedPsiElementBase)each).myNode + "; stub=" + ((StubBasedPsiElementBase)each).myStub;
each = ((StubBasedPsiElementBase)each).getParentByStub();
@@ -154,11 +154,11 @@ public class StubBasedPsiElementBase extends ASTDelegateP
public boolean isValid() {
T stub = myStub;
if (stub != null) {
- if (stub instanceof PsiFileStub) {
- return stub.getPsi().isValid();
+ PsiElement parentPsi = stub.getParentStub().getPsi();
+ if (parentPsi instanceof PsiFileImpl) {
+ return ((PsiFileImpl) parentPsi).isStubBasedChildValid(this);
}
-
- return stub.getParentStub().getPsi().isValid();
+ return parentPsi.isValid();
}
return super.isValid();
diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
index 6ddebaf8b7f8..505689a11b30 100644
--- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
+++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
@@ -423,6 +423,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, AS
return myType;
}
+ @Override
public void remapTokenType(IElementType type) {
//assert myType != null && type != null;
myType = type;
@@ -547,6 +548,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, AS
return myParsed;
}
+ @Override
public ASTNodeBuilder getBuilder() {
return myBuilder;
}
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/ex/DocumentBulkUpdateListener.java b/platform/core-impl/src/com/intellij/openapi/editor/ex/DocumentBulkUpdateListener.java
index b85db01dc00b..999482c517df 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/ex/DocumentBulkUpdateListener.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/ex/DocumentBulkUpdateListener.java
@@ -24,7 +24,7 @@ import com.intellij.util.messages.Topic;
import org.jetbrains.annotations.NotNull;
public interface DocumentBulkUpdateListener {
- Topic TOPIC = Topic.create("Bulk document change notifcation like reformat, etc.", DocumentBulkUpdateListener.class);
+ Topic TOPIC = Topic.create("Bulk document change notification like reformat, etc.", DocumentBulkUpdateListener.class);
void updateStarted(@NotNull Document doc);
void updateFinished(@NotNull Document doc);
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java
index a3f9d7d5b652..08c65c2ac35f 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java
@@ -44,7 +44,7 @@ abstract class CharArray implements CharSequenceBackedByArray {
private static final boolean DISABLE_DEFERRED_PROCESSING = Boolean.getBoolean("idea.document.deny.deferred.changes");
@SuppressWarnings("UseOfArchaicSystemPropertyAccessors")
- private static final boolean DEBUG_DEFERRED_PROCESSING = LOG.isDebugEnabled() || Boolean.getBoolean("idea.document.debug.bulk.processing");
+ private static final boolean DEBUG_DEFERRED_PROCESSING = LOG.isDebugEnabled() || Boolean.getBoolean("idea.document.debug.bulk.processing") || DocumentImpl.CHECK_DOCUMENT_CONSISTENCY;
/**
* We can't exclude possibility of situation when 'defer changes' state is {@link #setDeferredChangeMode(boolean) entered}
* but not exited, hence, we want to perform automatic flushing if necessary in order to avoid memory leaks. This constant holds
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
index 18c0a2347654..e2a823c10e71 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
@@ -50,6 +50,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.DocumentImpl");
+ public static boolean CHECK_DOCUMENT_CONSISTENCY = ApplicationManager.getApplication().isUnitTestMode();
private final CopyOnWriteArrayList myDocumentListeners = ContainerUtil.createEmptyCOWList();
private final RangeMarkerTree myRangeMarkers = new RangeMarkerTree(this);
diff --git a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
index 9bb2fe2f2d72..af2a1cab97f5 100644
--- a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
+++ b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
@@ -144,7 +144,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
}
@Nullable
- protected PsiFile getPsiInner(final Language target) {
+ protected PsiFile getPsiInner(@NotNull Language target) {
if (target != getBaseLanguage()) {
return null;
}
@@ -510,6 +510,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
}
if (myContent != null) return myContent;
return myContent = ApplicationManager.getApplication().runReadAction(new Computable() {
+ @Override
@NotNull
public CharSequence compute() {
return myFile.calcTreeElement().getText();
diff --git a/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java
index d95321ece57a..e8e5cc3e3899 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/AbstractModificationTracker.java
@@ -17,6 +17,7 @@ package com.intellij.psi.impl;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
/**
* @author Roman.Chernyatchik
@@ -40,7 +41,8 @@ public abstract class AbstractModificationTracker implements PsiTreeChangePrepro
myPsiManager.addTreeChangePreprocessor(this);
}
- public void treeChanged(final PsiTreeChangeEventImpl event) {
+ @Override
+ public void treeChanged(@NotNull final PsiTreeChangeEventImpl event) {
boolean changedInsideCodeBlock = false;
switch (event.getCode()) {
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
index 360720da51a6..d3c6b410abd8 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.messages.MessageBus;
+import org.jetbrains.annotations.NotNull;
import java.util.concurrent.atomic.AtomicLong;
@@ -68,7 +69,7 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr
}
@Override
- public void treeChanged(PsiTreeChangeEventImpl event) {
+ public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
myModificationCount.getAndIncrement();
if (event.getParent() instanceof PsiDirectory) {
incOutOfCodeBlockModificationCounter();
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessor.java b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessor.java
index 35224e14613f..7eaac7f30076 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessor.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessor.java
@@ -17,6 +17,7 @@
package com.intellij.psi.impl;
import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
@@ -24,5 +25,5 @@ import com.intellij.openapi.extensions.ExtensionPointName;
public interface PsiTreeChangePreprocessor {
ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.psi.treeChangePreprocessor");
- void treeChanged(PsiTreeChangeEventImpl event);
+ void treeChanged(@NotNull PsiTreeChangeEventImpl event);
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
index dd202dd57883..d3ff3e9ae771 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
@@ -249,6 +249,20 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
return findTreeForStub(ast, stubs, stub);
}
+ public boolean isStubBasedChildValid(@NotNull StubBasedPsiElementBase psi) {
+ StubElement fileStub = getStub();
+ if (fileStub != null) {
+ synchronized (myStubLock) {
+ fileStub = getStub();
+ StubElement childStub = psi.getStub();
+ if (fileStub != null && childStub != null && fileStub != childStub.getParentStub()) {
+ return false;
+ }
+ }
+ }
+ return isValid();
+ }
+
@Nullable
private static ASTNode findTreeForStub(ASTNode tree, final Iterator> stubs, final StubElement stub) {
final IElementType type = tree.getElementType();
diff --git a/platform/icons/src/actions/checked_16x16.png b/platform/icons/src/actions/checked_16x16.png
new file mode 100644
index 000000000000..d55c1fc133c9
Binary files /dev/null and b/platform/icons/src/actions/checked_16x16.png differ
diff --git a/platform/icons/src/actions/checked_16x16_selected.png b/platform/icons/src/actions/checked_16x16_selected.png
new file mode 100644
index 000000000000..2dfa1eda3c12
Binary files /dev/null and b/platform/icons/src/actions/checked_16x16_selected.png differ
diff --git a/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java b/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java
index cc6c34625ef8..689ad61035da 100644
--- a/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java
+++ b/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java
@@ -58,7 +58,7 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements D
private void addCustomFoldingRegionsRecursively(@Nullable FoldingStack foldingStack,
@NotNull ASTNode node,
- List descriptors,
+ @NotNull List descriptors,
int currDepth) {
FoldingStack localFoldingStack = isCustomFoldingRoot(node) || foldingStack == null ? new FoldingStack(node) : foldingStack;
for (ASTNode child = node.getFirstChildNode(); child != null; child = child.getTreeNext()) {
@@ -196,7 +196,7 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements D
}
private static class FoldingStack extends Stack {
- private ASTNode owner;
+ private final ASTNode owner;
public FoldingStack(@NotNull ASTNode owner) {
super(1);
@@ -205,7 +205,7 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements D
@NotNull
public ASTNode getOwner() {
- return this.owner;
+ return owner;
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeEditor/printing/TextPainter.java b/platform/lang-impl/src/com/intellij/codeEditor/printing/TextPainter.java
index e36efc870d41..b57def2b36be 100644
--- a/platform/lang-impl/src/com/intellij/codeEditor/printing/TextPainter.java
+++ b/platform/lang-impl/src/com/intellij/codeEditor/printing/TextPainter.java
@@ -27,7 +27,6 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -93,8 +92,6 @@ public class TextPainter implements Printable {
myFileName = fileName;
mySegmentEnd = myDocument.getTextLength();
- PsiDocumentManager.getInstance(project).commitAllDocuments();
-
myFileType = psiFile.getFileType();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
index 16e61e3fa520..df0cea32c0c2 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java
@@ -50,6 +50,8 @@ public class ExternalToolPass extends TextEditorHighlightingPass {
private final Map myAnnotator2DataMap;
+ private final ExternalToolPassFactory myExternalToolPassFactory;
+
private static class MyData {
final PsiFile myPsiRoot;
final Object myCollectedInfo;
@@ -61,7 +63,8 @@ public class ExternalToolPass extends TextEditorHighlightingPass {
}
}
- public ExternalToolPass(@NotNull PsiFile file,
+ public ExternalToolPass(@NotNull ExternalToolPassFactory externalToolPassFactory,
+ @NotNull PsiFile file,
@NotNull Editor editor,
int startOffset,
int endOffset) {
@@ -72,6 +75,7 @@ public class ExternalToolPass extends TextEditorHighlightingPass {
myAnnotationHolder = new AnnotationHolderImpl(new AnnotationSession(file));
myAnnotator2DataMap = new HashMap();
+ myExternalToolPassFactory = externalToolPassFactory;
}
@Override
@@ -159,7 +163,7 @@ public class ExternalToolPass extends TextEditorHighlightingPass {
r.run();
}
else {
- ApplicationManager.getApplication().executeOnPooledThread(r);
+ myExternalToolPassFactory.scheduleExternalActivity(myFile, r);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPassFactory.java
index 4dec3b2a23b6..f719f5e89cf4 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPassFactory.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPassFactory.java
@@ -28,6 +28,8 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
+import com.intellij.util.ui.update.MergingUpdateQueue;
+import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,10 +40,15 @@ import java.util.List;
* @author cdr
*/
public class ExternalToolPassFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory {
+ private final MergingUpdateQueue myExternalActivitiesQueue;
+
public ExternalToolPassFactory(Project project, TextEditorHighlightingPassRegistrar highlightingPassRegistrar) {
super(project);
// start after PostHighlightingPass completion since it could report errors that can prevent us to run
highlightingPassRegistrar.registerTextEditorHighlightingPass(this, new int[]{Pass.POST_UPDATE_ALL}, null, true, Pass.EXTERNAL_TOOLS);
+
+ myExternalActivitiesQueue = new MergingUpdateQueue("ExternalActivitiesQueue", 300, true, MergingUpdateQueue.ANY_COMPONENT, project,
+ null, false);
}
@Override
@@ -54,11 +61,11 @@ public class ExternalToolPassFactory extends AbstractProjectComponent implements
@Override
@Nullable
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
- TextRange textRange = file.getTextRange();
+ TextRange textRange = FileStatusMap.getDirtyTextRange(editor, Pass.EXTERNAL_TOOLS) == null ? null : file.getTextRange();
if (textRange == null || !externalAnnotatorsDefined(file)) {
return null;
}
- return new ExternalToolPass(file, editor, textRange.getStartOffset(), textRange.getEndOffset());
+ return new ExternalToolPass(this, file, editor, textRange.getStartOffset(), textRange.getEndOffset());
}
private static boolean externalAnnotatorsDefined(PsiFile file) {
@@ -70,4 +77,13 @@ public class ExternalToolPassFactory extends AbstractProjectComponent implements
}
return false;
}
+
+ void scheduleExternalActivity(@NotNull PsiFile file, @NotNull final Runnable r) {
+ myExternalActivitiesQueue.queue(new Update(file) {
+ @Override
+ public void run() {
+ r.run();
+ }
+ });
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
index ef1ca8393cf9..978dbe22d15d 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
@@ -890,8 +890,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
public boolean performGuardedChange(Runnable change, @Nullable final String debug) {
checkValid();
- assert myLookupStartMarker.isValid();
- assert !myChangeGuard;
+ assert myLookupStartMarker != null : "null start before";
+ assert myLookupStartMarker.isValid() : "invalid start";
+ assert !myChangeGuard : "already in change";
myChangeGuard = true;
final Document document = myEditor.getDocument();
@@ -911,7 +912,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
document.removeDocumentListener(spy);
myChangeGuard = false;
}
- if (!myLookupStartMarker.isValid() || myDisposed) {
+ if (myDisposed || !myLookupStartMarker.isValid()) {
hide();
return false;
}
@@ -924,7 +925,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
@Override
public boolean vetoesHiding() {
- return myChangeGuard || myDisposed;
+ return myChangeGuard;
}
public boolean isAvailableToUser() {
diff --git a/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java b/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java
index 0c163ed00a14..f6c95bf4276b 100644
--- a/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java
+++ b/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.execution.rmi;
import com.intellij.execution.ExecutionException;
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java
index fc6488f989db..ae9624772796 100644
--- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java
@@ -363,7 +363,9 @@ public class GridCellImpl implements GridCell {
service.setSize(getDimensionKey(), size, myContext.getProject());
if (myContext.getWindow() != 0) {
final Window frame = SwingUtilities.getWindowAncestor(myPlaceholder);
- service.setLocation(getDimensionKey(), frame.getLocationOnScreen());
+ if (frame != null) {
+ service.setLocation(getDimensionKey(), frame.getLocationOnScreen());
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java
index af422a858909..1a7796276ff2 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java
@@ -804,12 +804,7 @@ public class FindDialog extends DialogWrapper {
gbConstraints.gridx++;
gbConstraints.weightx = 1;
gbConstraints.gridwidth = 2;
- myScopeCombo = new ScopeChooserCombo(myProject, true, true, FindSettings.getInstance().getDefaultScopeName()) {
- @Override
- public Dimension getMinimumSize() {
- return new Dimension(200, super.getMinimumSize().height);
- }
- };
+ myScopeCombo = new ScopeChooserCombo(myProject, true, true, FindSettings.getInstance().getDefaultScopeName());
Disposer.register(myDisposable, myScopeCombo);
scopePanel.add(myScopeCombo, gbConstraints);
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java
index dd3afc04bb4e..f7586f8ce300 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java
@@ -175,7 +175,8 @@ public abstract class GotoActionBase extends AnAction {
@Override
public void onClose() {
ourLastStrings.put(myInAction, Pair.create(popup.getEnteredText(), popup.getSelectedIndex()));
- if (startedAction.equals(myInAction)) {
+ //noinspection ConstantConditions
+ if (startedAction != null && startedAction.equals(myInAction)) {
myInAction = null;
}
if (filter != null) {
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
index 08d9c320118f..9b63a06d17bc 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
@@ -253,8 +253,6 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo
myViewContentPanel = new JPanel();
myPanel = new SimpleToolWindowPanel(true).setProvideQuickActions(false);
myPanel.setContent(myViewContentPanel);
-
- myPanel.setBorder(new ToolWindow.Border(true, false, false, false));
}
public String getName() {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
index db21ded54762..b02c3272bc89 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
@@ -16,10 +16,13 @@
package com.intellij.ide.util.gotoByName;
import com.intellij.concurrency.JobUtil;
+import com.intellij.diagnostic.PluginException;
+import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.util.NavigationItemListCellRenderer;
import com.intellij.navigation.ChooseByNameContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbService;
@@ -109,7 +112,13 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModel
try {
for (NavigationItem item : contributor.getItemsByName(name, pattern, myProject, checkBoxState)) {
if (item == null) {
- LOG.error("null item from contributor " + contributor + " for name " + name);
+ final PluginId pluginId = PluginManager.getPluginByClassName(contributor.getClass().getName());
+ if (pluginId != null) {
+ LOG.error(new PluginException("null item from contributor " + contributor + " for name " + name, pluginId));
+ }
+ else {
+ LOG.error("null item from contributor " + contributor + " for name " + name);
+ }
continue;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
index 7dcd14a4b40b..48b78e2bee88 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
@@ -190,6 +190,15 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
return new Dimension(Math.min(400, preferredSize.width), preferredSize.height);
}
+ @Override
+ public Dimension getMinimumSize() {
+ if (isMinimumSizeSet()) {
+ return super.getMinimumSize();
+ }
+ Dimension minimumSize = super.getMinimumSize();
+ return new Dimension(Math.min(200, minimumSize.width), minimumSize.height);
+ }
+
private void createPredefinedScopeDescriptors(DefaultComboBoxModel model) {
for (SearchScope scope : getPredefinedScopes(myProject, DataManager.getInstance().getDataContext(), mySuggestSearchInLibs, myPrevSearchFiles, true, true)) {
model.addElement(new ScopeDescriptor(scope));
diff --git a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
index 90bd69e50224..e1768278e035 100644
--- a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
+++ b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
@@ -70,12 +70,15 @@ public class ModuleAttachProcessor extends ProjectAttachProcessor {
token.finish();
}
}
- for(String file: projectDir.list()) {
- if (FileUtil.getExtension(file).equals("iml")) {
- VirtualFile imlFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(projectDir, file));
- if (imlFile != null) {
- attachModule(project, imlFile, callback);
- return true;
+ final String[] files = projectDir.list();
+ if (files != null) {
+ for(String file: files) {
+ if (FileUtil.getExtension(file).equals("iml")) {
+ VirtualFile imlFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(projectDir, file));
+ if (imlFile != null) {
+ attachModule(project, imlFile, callback);
+ return true;
+ }
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/psi/MultiplePsiFilesPerDocumentFileViewProvider.java b/platform/lang-impl/src/com/intellij/psi/MultiplePsiFilesPerDocumentFileViewProvider.java
index ec5ee72b429b..bc650fdf8ef4 100644
--- a/platform/lang-impl/src/com/intellij/psi/MultiplePsiFilesPerDocumentFileViewProvider.java
+++ b/platform/lang-impl/src/com/intellij/psi/MultiplePsiFilesPerDocumentFileViewProvider.java
@@ -28,7 +28,6 @@ import com.intellij.psi.impl.SharedPsiElementImplUtil;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
-import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.ReflectionCache;
import com.intellij.util.containers.ConcurrentHashMap;
@@ -72,7 +71,7 @@ public abstract class MultiplePsiFilesPerDocumentFileViewProvider extends Single
}
@Override
- protected PsiFile getPsiInner(final Language target) {
+ protected PsiFile getPsiInner(@NotNull final Language target) {
PsiFile file = myRoots.get(target);
if (file == null) {
if (isPhysical()) {
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java
index 84e455f565d3..2d97fc4052a7 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java
@@ -31,6 +31,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.editor.ex.DocumentBulkUpdateListener;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter;
@@ -79,7 +80,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
private final List myListeners = ContainerUtil.createEmptyCOWList();
private final SmartPointerManagerImpl mySmartPointerManager;
- public PsiDocumentManagerImpl(@NotNull Project project,
+ public PsiDocumentManagerImpl(@NotNull final Project project,
@NotNull PsiManager psiManager,
@NotNull SmartPointerManager smartPointerManager,
@NotNull EditorFactory editorFactory,
@@ -105,6 +106,12 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
fireDocumentCreated(document, psiFile);
}
});
+ bus.connect().subscribe(DocumentBulkUpdateListener.TOPIC, new DocumentBulkUpdateListener.Adapter() {
+ @Override
+ public void updateFinished(@NotNull Document doc) {
+ documentCommitThread.queueCommit(project, doc, "Bulk update finished");
+ }
+ });
ApplicationManager.getApplication().addApplicationListener(new ApplicationAdapter() {
@Override
public void beforeWriteActionStart(Object action) {
@@ -668,12 +675,13 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
commitNecessary = true;
}
+ boolean fromRefresh = ApplicationManager.getApplication().hasWriteAction(ExternalChangeAction.class);
if (commitNecessary) {
myUncommittedDocuments.add(document);
- myDocumentCommitThread.log("PDI: added to uncommitted", null, false, document, event, myUncommittedDocuments);
-
- myDocumentCommitThread.queueCommit(myProject, document, event);
+ if (!fromRefresh && !((DocumentEx)document).isInBulkUpdate()) {
+ myDocumentCommitThread.queueCommit(myProject, document, event);
+ }
}
// Consider that it's worth to perform complete re-parse instead of merge if the whole document text is replaced and
@@ -683,7 +691,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, Boolean.TRUE);
}
- if (commitNecessary && ApplicationManager.getApplication().hasWriteAction(ExternalChangeAction.class)){
+ if (commitNecessary && fromRefresh){
commitDocument(document);
}
// avoid documents piling up during batch processing
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java
index 3e018129246b..fad5f62205e9 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java
@@ -18,6 +18,7 @@ package com.intellij.psi.impl;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
@@ -31,7 +32,7 @@ public abstract class PsiTreeChangePreprocessorBase implements PsiTreeChangePrep
}
@Override
- public void treeChanged(PsiTreeChangeEventImpl event) {
+ public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
boolean changedInsideCodeBlock = false;
switch (event.getCode()) {
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java
index dde40cb8887b..ad73760f78ed 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java
@@ -106,6 +106,7 @@ class SmartPsiElementPointerImpl implements SmartPointerEx
myElement = element == null ? null : new SoftReference(element);
}
+ @Override
public E getCachedElement() {
Reference ref = myElement;
return ref == null ? null : ref.get();
diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/ShowSelectionHistoryAction.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/ShowSelectionHistoryAction.java
index 90bafa107ef6..843795e24455 100644
--- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/ShowSelectionHistoryAction.java
+++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/ShowSelectionHistoryAction.java
@@ -20,12 +20,14 @@ import com.intellij.history.core.LocalHistoryFacade;
import com.intellij.history.integration.IdeaGateway;
import com.intellij.history.integration.ui.views.SelectionHistoryDialog;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.actions.VcsContext;
import com.intellij.openapi.vcs.actions.VcsContextWrapper;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsSelection;
import com.intellij.vcsUtil.VcsSelectionUtil;
+import org.jetbrains.annotations.Nullable;
public class ShowSelectionHistoryAction extends ShowHistoryAction {
@Override
@@ -44,12 +46,23 @@ public class ShowSelectionHistoryAction extends ShowHistoryAction {
return sel == null ? super.getText(e) : sel.getActionName();
}
+ @Override
+ public void update(AnActionEvent e) {
+ if (e.getData(PlatformDataKeys.EDITOR) == null) {
+ e.getPresentation().setVisible(false);
+ }
+ else {
+ super.update(e);
+ }
+ }
+
@Override
protected boolean isEnabled(LocalHistoryFacade vcs, IdeaGateway gw, VirtualFile f, AnActionEvent e) {
return super.isEnabled(vcs, gw, f, e) && !f.isDirectory() && getSelection(e) != null;
}
- private VcsSelection getSelection(AnActionEvent e) {
+ @Nullable
+ private static VcsSelection getSelection(AnActionEvent e) {
VcsContext c = VcsContextWrapper.createCachedInstanceOn(e);
return VcsSelectionUtil.getSelection(c);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/progress/ProgressManagerQueue.java b/platform/platform-api/src/com/intellij/openapi/progress/ProgressManagerQueue.java
index 18beef5fcedc..6e86c7bd2d74 100644
--- a/platform/platform-api/src/com/intellij/openapi/progress/ProgressManagerQueue.java
+++ b/platform/platform-api/src/com/intellij/openapi/progress/ProgressManagerQueue.java
@@ -37,11 +37,13 @@ public class ProgressManagerQueue extends AbstractTaskQueue {
protected void runMe() {
final Application app = ApplicationManager.getApplication();
if (app.isDispatchThread()) {
+ if (myTask.myProject != null && myTask.myProject.isDisposed()) return;
myProgressManager.run(myTask);
}
else {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
+ if (myTask.myProject != null && myTask.myProject.isDisposed()) return;
myProgressManager.run(myTask);
}
});
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
index 62c78bbb0f6c..c7d0dcbacf19 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
@@ -462,7 +462,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
boolean hasFocus) {
if (value instanceof MyNode) {
final MyNode node = ((MyNode)value);
- setIcon(node.getConfigurable().getIcon(expanded));
+ setIcon(node.getIcon(expanded));
final Font font = UIUtil.getTreeFont();
if (node.isDisplayInBold()) {
setFont(font.deriveFont(Font.BOLD));
@@ -699,8 +699,8 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
throw new ConfigurationException("Name should contain non-space characters");
}
if (names.contains(name)) {
- final NamedConfigurable selectedConfugurable = getSelectedConfugurable();
- if (selectedConfugurable == null || !Comparing.strEqual(selectedConfugurable.getDisplayName(), name)) {
+ final NamedConfigurable selectedConfigurable = getSelectedConfugurable();
+ if (selectedConfigurable == null || !Comparing.strEqual(selectedConfigurable.getDisplayName(), name)) {
selectNodeInTree(node);
}
throw new ConfigurationException(CommonBundle.message("smth.already.exist.error.message", prefix, name), title);
@@ -836,6 +836,16 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
public void setDisplayInBold(boolean displayInBold) {
myDisplayInBold = displayInBold;
}
+
+ @Nullable
+ public Icon getIcon(boolean expanded) {
+ // thanks to invokeLater() in TreeUtil.showAndSelect(), we can get calls to getIcon() after the tree has been disposed
+ final NamedConfigurable configurable = getConfigurable();
+ if (configurable != null) {
+ return configurable.getIcon(expanded);
+ }
+ return null;
+ }
}
@SuppressWarnings({"ConstantConditions"})
diff --git a/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java b/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
index 9a7a047a812b..98757ca2ff8f 100644
--- a/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/ColoredTreeCellRenderer.java
@@ -56,7 +56,7 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
clear();
mySelected = selected;
- myFocused = tree.hasFocus();
+ myFocused = isFocused();
// We paint background if and only if tree path is selected and tree has focus.
// If path is selected and tree is not focused then we just paint focused border.
@@ -104,7 +104,7 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
super.setIconOpaque(false);
}
else {
- super.setOpaque(myOpaque || selected && hasFocus || selected && tree.hasFocus()); // draw selection background even for non-opaque tree
+ super.setOpaque(myOpaque || selected && hasFocus || selected && isFocused()); // draw selection background even for non-opaque tree
}
if (tree.getUI() instanceof UIUtil.MacTreeUI) {
@@ -121,6 +121,10 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
return this;
}
+ protected boolean isFocused() {
+ return myTree.hasFocus();
+ }
+
public void setOpaque(boolean isOpaque) {
myOpaque = isOpaque;
super.setOpaque(isOpaque);
diff --git a/platform/platform-api/src/com/intellij/ui/HtmlListCellRenderer.java b/platform/platform-api/src/com/intellij/ui/HtmlListCellRenderer.java
index 179e6418c92d..f383b18eb0b6 100644
--- a/platform/platform-api/src/com/intellij/ui/HtmlListCellRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/HtmlListCellRenderer.java
@@ -90,6 +90,15 @@ public abstract class HtmlListCellRenderer extends ListCellRendererWrapper
}
}
+ public void append(SimpleColoredText text) {
+ int length = text.getTexts().size();
+ for (int i = 0; i < length; i++) {
+ String fragment = text.getTexts().get(i);
+ SimpleTextAttributes attributes = text.getAttributes().get(i);
+ append(fragment, attributes);
+ }
+ }
+
private static void formatStyle(final StringBuilder builder, final SimpleTextAttributes attributes) {
final Color fgColor = attributes.getFgColor();
final Color bgColor = attributes.getBgColor();
diff --git a/platform/platform-api/src/com/intellij/ui/RawCommandLineEditor.java b/platform/platform-api/src/com/intellij/ui/RawCommandLineEditor.java
index f2af238df062..5b0296ecfd54 100644
--- a/platform/platform-api/src/com/intellij/ui/RawCommandLineEditor.java
+++ b/platform/platform-api/src/com/intellij/ui/RawCommandLineEditor.java
@@ -15,7 +15,9 @@
*/
package com.intellij.ui;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.IconLoader;
@@ -27,6 +29,8 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class RawCommandLineEditor extends JPanel {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.ui.RawCommandLineEditor");
+
private final TextFieldWithBrowseButton myTextField;
private String myDialogCaption = "";
@@ -34,6 +38,14 @@ public class RawCommandLineEditor extends JPanel {
super(new BorderLayout());
myTextField = new TextFieldWithBrowseButton(new ActionListener() {
public void actionPerformed(ActionEvent e) {
+ if (myDialogCaption == null) {
+ Container parent = getParent();
+ if (parent instanceof LabeledComponent) {
+ parent = parent.getParent();
+ }
+ LOG.error("Did not call RawCommandLineEditor.setDialogCaption() in " + parent);
+ myDialogCaption = "Parameters";
+ }
Messages.showTextAreaDialog(myTextField.getTextField(), myDialogCaption, "EditParametersPopupWindow");
}
});
diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredText.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredText.java
index d568198030c0..a267e62a87d8 100644
--- a/platform/platform-api/src/com/intellij/ui/SimpleColoredText.java
+++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredText.java
@@ -81,4 +81,15 @@ public class SimpleColoredText {
public ArrayList getAttributes() {
return myAttributes;
}
+
+ public SimpleColoredText derive(SimpleTextAttributes attributes, boolean override) {
+ SimpleColoredText result = new SimpleColoredText();
+ for (int i = 0; i < myTexts.size(); i++) {
+ SimpleTextAttributes overridden = override
+ ? SimpleTextAttributes.merge(myAttributes.get(i), attributes)
+ : SimpleTextAttributes.merge(attributes, myAttributes.get(i));
+ result.append(myTexts.get(i), overridden);
+ }
+ return result;
+ }
}
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
index 45c466bf66e9..53ec6dcc98ab 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
@@ -337,7 +337,9 @@ public class JBTabsImpl extends JComponent
BufferedImage img;
if (cmp.isShowing()) {
- img = new BufferedImage(cmp.getWidth(), cmp.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ final int width = cmp.getWidth();
+ final int height = cmp.getHeight();
+ img = new BufferedImage(width > 0 ? width : 500, height > 0 ? height : 500, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img.createGraphics();
cmp.paint(g);
} else {
diff --git a/platform/platform-api/src/com/intellij/util/ui/StatusText.java b/platform/platform-api/src/com/intellij/util/ui/StatusText.java
index 2510f91d6940..043b377610bc 100644
--- a/platform/platform-api/src/com/intellij/util/ui/StatusText.java
+++ b/platform/platform-api/src/com/intellij/util/ui/StatusText.java
@@ -16,7 +16,6 @@
package com.intellij.util.ui;
-import com.intellij.ui.ScreenUtil;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.UIBundle;
@@ -134,6 +133,7 @@ public abstract class StatusText {
myText = "";
myComponent.clear();
myClickListeners.clear();
+ if (myOwner != null) myOwner.repaint();
return this;
}
@@ -154,7 +154,7 @@ public abstract class StatusText {
myText += text;
myComponent.append(text, attrs);
myClickListeners.add(listener);
-
+ if (myOwner != null) myOwner.repaint();
return this;
}
diff --git a/platform/platform-impl/src/com/intellij/notification/EventLog.java b/platform/platform-impl/src/com/intellij/notification/EventLog.java
index 2ac011e9a5b9..89e8189e62e0 100644
--- a/platform/platform-impl/src/com/intellij/notification/EventLog.java
+++ b/platform/platform-impl/src/com/intellij/notification/EventLog.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.*;
@@ -403,7 +404,7 @@ public class EventLog implements Notifications {
myProjectModel.addNotification(notification);
- ApplicationManager.getApplication().invokeLater(new Runnable() {
+ StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
@Override
public void run() {
if (!ShutDownTracker.isShutdownHookRunning() && !myProject.isDisposed()) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
index e53742e1e2f4..4c32efd347a6 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.editor.highlighter;
import com.intellij.lang.Language;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
@@ -32,6 +33,8 @@ import org.jetbrains.annotations.Nullable;
* @author yole
*/
public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.highlighter.EditorHighlighterFactoryImpl");
+
@Override
public EditorHighlighter createEditorHighlighter(SyntaxHighlighter highlighter, final EditorColorsScheme colors) {
if (highlighter == null) highlighter = new PlainSyntaxHighlighter();
@@ -74,8 +77,16 @@ public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
final ContentBasedFileSubstitutor[] processors = Extensions.getExtensions(ContentBasedFileSubstitutor.EP_NAME);
SyntaxHighlighter highlighter = null;
for (ContentBasedFileSubstitutor processor : processors) {
- if (processor.isApplicable(project, vFile) && processor instanceof ContentBasedClassFileProcessor) {
- highlighter = ((ContentBasedClassFileProcessor) processor).createHighlighter(project, vFile);
+ boolean applicable;
+ try {
+ applicable = processor.isApplicable(project, vFile);
+ }
+ catch (Exception e) {
+ LOG.error(e);
+ continue;
+ }
+ if (applicable && processor instanceof ContentBasedClassFileProcessor) {
+ highlighter = ((ContentBasedClassFileProcessor)processor).createHighlighter(project, vFile);
}
}
if (highlighter == null) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index fb2f5a32ae26..b44e8d539581 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -5803,7 +5803,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (last != null && !(last instanceof EditorComponentImpl)) return;
final Editor editor = getEditor(source);
- if (action == MOVE && !editor.isViewer()) {
+ if (action == MOVE && !editor.isViewer() && myDraggedRange != null) {
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), editor.getProject())) {
return;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
index bf47f92b6559..57309076daf1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
@@ -99,6 +99,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
myBus = ApplicationManager.getApplication().getMessageBus();
InvocationHandler handler = new InvocationHandler() {
+ @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
multicast(method, args);
return null;
@@ -135,17 +136,21 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
}
}
+ @Override
@NotNull
public String getComponentName() {
return "FileDocumentManager";
}
+ @Override
public void initComponent() {
}
+ @Override
public void disposeComponent() {
}
+ @Override
@Nullable
public Document getDocument(@NotNull final VirtualFile file) {
DocumentEx document = (DocumentEx)getCachedDocument(file);
@@ -167,6 +172,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
if (!(file instanceof LightVirtualFile || file.getFileSystem() instanceof DummyFileSystem)) {
document.addDocumentListener(
new DocumentAdapter() {
+ @Override
public void documentChanged(DocumentEvent e) {
final Document document = e.getDocument();
myUnsavedDocuments.add(document);
@@ -205,6 +211,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
return EditorFactory.getInstance().createDocument(text);
}
+ @Override
@Nullable
public Document getCachedDocument(@NotNull VirtualFile file) {
Reference reference = file.getUserData(DOCUMENT_KEY);
@@ -222,6 +229,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
public static void registerDocument(@NotNull final Document document, @NotNull VirtualFile virtualFile) {
synchronized (lock) {
virtualFile.putUserData(DOCUMENT_KEY, new SoftReference(document) {
+ @Override
public Document get() {
return document;
}
@@ -230,6 +238,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
}
}
+ @Override
@Nullable
public VirtualFile getFile(@NotNull Document document) {
return document.getUserData(FILE_KEY);
@@ -269,6 +278,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
});
}
+ @Override
public void saveAllDocuments() {
ApplicationManager.getApplication().assertIsDispatchThread();
@@ -293,11 +303,13 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
}
}
+ @Override
public void saveDocument(@NotNull final Document document) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (!myUnsavedDocuments.contains(document)) return;
ApplicationManager.getApplication().runWriteAction(new DocumentRunnable(document, null) {
+ @Override
public void run() {
_saveDocument(document);
}
@@ -394,6 +406,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
return lineSeparator;
}
+ @Override
@NotNull
public String getLineSeparator(@Nullable VirtualFile file, @Nullable Project project) {
String lineSeparator = file != null ? LoadTextUtil.getDetectedLineSeparator(file) : null;
@@ -421,6 +434,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
return false;
}
+ @Override
public void reloadFiles(final VirtualFile... files) {
for (VirtualFile file : files) {
if (file.exists()) {
@@ -432,6 +446,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
}
}
+ @Override
@NotNull
public Document[] getUnsavedDocuments() {
if (myUnsavedDocuments.isEmpty()) {
@@ -442,15 +457,18 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
return list.toArray(new Document[list.size()]);
}
+ @Override
public boolean isDocumentUnsaved(@NotNull Document document) {
return myUnsavedDocuments.contains(document);
}
+ @Override
public boolean isFileModified(@NotNull VirtualFile file) {
final Document doc = getCachedDocument(file);
return doc != null && isDocumentUnsaved(doc) && doc.getModificationStamp() != file.getModificationStamp();
}
+ @Override
public void propertyChanged(final VirtualFilePropertyEvent event) {
if (VirtualFile.PROP_WRITABLE.equals(event.getPropertyName())) {
final VirtualFile file = event.getFile();
@@ -459,6 +477,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
+ @Override
public void run() {
document.setReadOnly(!event.getFile().isWritable());
}
@@ -478,6 +497,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
return ft.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) == null;
}
+ @Override
public void contentsChanged(VirtualFileEvent event) {
if (event.isFromSave()) return;
final VirtualFile file = event.getFile();
@@ -499,6 +519,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
LOG.info(" oldFileStamp:" + oldFileStamp);
Runnable askReloadRunnable = new Runnable() {
+ @Override
public void run() {
if (!file.isValid()) return;
if (askReloadFromDisk(file, document)) {
@@ -518,6 +539,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
myMultiCaster.fileWithNoDocumentChanged(file);
}
+ @Override
public void reloadFromDisk(@NotNull final Document document) {
ApplicationManager.getApplication().assertIsDispatchThread();
final VirtualFile file = getFile(document);
@@ -527,9 +549,11 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
final Project project = ProjectLocator.getInstance().guessProjectForFile(file);
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+ @Override
public void run() {
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction.ExternalDocumentChange(document, project) {
+ @Override
public void run() {
boolean wasWritable = document.isWritable();
DocumentEx documentEx = (DocumentEx)document;
@@ -558,6 +582,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
builder.addOkAction().setText(UIBundle.message("file.cache.conflict.load.fs.changes.button"));
builder.addCancelAction().setText(UIBundle.message("file.cache.conflict.keep.memory.changes.button"));
builder.addAction(new AbstractAction(UIBundle.message("file.cache.conflict.show.difference.button")) {
+ @Override
public void actionPerformed(ActionEvent e) {
String windowtitle = UIBundle.message("file.cache.conflict.for.file.dialog.title", file.getPresentableUrl());
final ProjectEx project = (ProjectEx)ProjectLocator.getInstance().guessProjectForFile(file);
@@ -591,6 +616,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
protected void reportErrorOnSave(final IOException e) {
// invokeLater here prevents attempt to show dialog in write action
ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
public void run() {
Messages.showMessageDialog(
UIBundle.message("cannot.save.file.with.error.error.message", e.getMessage()),
@@ -601,9 +627,11 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
});
}
+ @Override
public void fileCreated(VirtualFileEvent event) {
}
+ @Override
public void fileDeleted(VirtualFileEvent event) {
Document doc = getCachedDocument(event.getFile());
if (doc != null) {
@@ -611,22 +639,28 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
}
}
+ @Override
public void fileMoved(VirtualFileMoveEvent event) {
}
+ @Override
public void fileCopied(VirtualFileCopyEvent event) {
fileCreated(event);
}
+ @Override
public void beforePropertyChange(VirtualFilePropertyEvent event) {
}
+ @Override
public void beforeContentsChange(VirtualFileEvent event) {
}
+ @Override
public void beforeFileDeletion(VirtualFileEvent event) {
}
+ @Override
public void beforeFileMovement(VirtualFileMoveEvent event) {
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
index fb4c6759109a..e56a68e89719 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
@@ -1647,6 +1647,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
if (newFilePair == null) continue;
VirtualFile newFile = newFilePair.first;
+ if (newFile == null) continue;
// already open
if (eachWindow.findFileIndex(newFile) != -1) continue;
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ChooseActionsDialog.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ChooseActionsDialog.java
index 2a668c4cb46c..072aea54019c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ChooseActionsDialog.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ChooseActionsDialog.java
@@ -19,41 +19,85 @@
*/
package com.intellij.openapi.keymap.impl.ui;
+import com.intellij.ide.CommonActionsManager;
+import com.intellij.ide.TreeExpander;
+import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.QuickList;
+import com.intellij.openapi.keymap.KeyMapBundle;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.packageDependencies.ui.TreeExpansionMonitor;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.FilterComponent;
+import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.IJSwingUtilities;
+import com.intellij.util.ui.FormBuilder;
+import com.intellij.util.ui.UIUtil;
+import com.intellij.util.ui.tree.TreeUtil;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.DocumentEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import java.util.ArrayList;
public class ChooseActionsDialog extends DialogWrapper {
private final ActionsTree myActionsTree;
+ private FilterComponent myFilterComponent;
+ private TreeExpansionMonitor myTreeExpansionMonitor;
+ private Keymap myKeymap;
+ private QuickList[] myQuicklists;
+ private JBPopup myPopup;
public ChooseActionsDialog(Component parent, Keymap keymap, QuickList[] quicklists) {
super(parent, true);
+ myKeymap = keymap;
+ myQuicklists = quicklists;
myActionsTree = new ActionsTree();
myActionsTree.reset(keymap, quicklists);
myActionsTree.getTree().getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
+ myActionsTree.getTree().addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2) {
+ doOKAction();
+ }
+ }
+ });
+
+ myTreeExpansionMonitor = TreeExpansionMonitor.install(myActionsTree.getTree());
+
setTitle("Add Actions to Quick List");
init();
}
+ @Override
+ protected JComponent createNorthPanel() {
+ return createToolbarPanel();
+ }
+
@Override
protected JComponent createCenterPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(myActionsTree.getComponent());
panel.setPreferredSize(new Dimension(400, 500));
-
+
return panel;
}
-
+
public String[] getTreeSelectedActionIds() {
TreePath[] paths = myActionsTree.getTree().getSelectionPaths();
if (paths == null) return ArrayUtil.EMPTY_STRING_ARRAY;
@@ -74,4 +118,160 @@ public class ChooseActionsDialog extends DialogWrapper {
}
return ArrayUtil.toStringArray(actions);
}
+
+ private JPanel createToolbarPanel() {
+ final JPanel panel = new JPanel(new BorderLayout());
+ DefaultActionGroup group = new DefaultActionGroup();
+ final JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent();
+ final CommonActionsManager commonActionsManager = CommonActionsManager.getInstance();
+ final TreeExpander treeExpander = new TreeExpander() {
+ public void expandAll() {
+ TreeUtil.expandAll(myActionsTree.getTree());
+ }
+
+ public boolean canExpand() {
+ return true;
+ }
+
+ public void collapseAll() {
+ TreeUtil.collapseAll(myActionsTree.getTree(), 0);
+ }
+
+ public boolean canCollapse() {
+ return true;
+ }
+ };
+ group.add(commonActionsManager.createExpandAllAction(treeExpander, myActionsTree.getTree()));
+ group.add(commonActionsManager.createCollapseAllAction(treeExpander, myActionsTree.getTree()));
+
+ panel.add(toolbar, BorderLayout.WEST);
+ group = new DefaultActionGroup();
+ final JComponent searchToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent();
+ final Alarm alarm = new Alarm();
+ myFilterComponent = new FilterComponent("KEYMAP_IN_QUICK_LISTS", 5) {
+ public void filter() {
+ alarm.cancelAllRequests();
+ alarm.addRequest(new Runnable() {
+ public void run() {
+ if (!myFilterComponent.isShowing()) return;
+ if (!myTreeExpansionMonitor.isFreeze()) myTreeExpansionMonitor.freeze();
+ final String filter = getFilter();
+ myActionsTree.filter(filter, myQuicklists);
+ final JTree tree = myActionsTree.getTree();
+ TreeUtil.expandAll(tree);
+ if (filter == null || filter.length() == 0) {
+ TreeUtil.collapseAll(tree, 0);
+ myTreeExpansionMonitor.restore();
+ }
+ }
+ }, 300);
+ }
+ };
+ myFilterComponent.reset();
+
+ panel.add(myFilterComponent, BorderLayout.CENTER);
+
+ group.add(new AnAction(KeyMapBundle.message("filter.shortcut.action.text"),
+ KeyMapBundle.message("filter.shortcut.action.text"),
+ IconLoader.getIcon("/ant/shortcutFilter.png")) {
+ public void actionPerformed(AnActionEvent e) {
+ myFilterComponent.reset();
+ if (myPopup == null || myPopup.getContent() == null) {
+ myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(createFilteringPanel(), null)
+ .setRequestFocus(true)
+ .setTitle(KeyMapBundle.message("filter.settings.popup.title"))
+ .setMovable(true)
+ .createPopup();
+ }
+ myPopup.showUnderneathOf(searchToolbar);
+ }
+ });
+ group.add(new AnAction(KeyMapBundle.message("filter.clear.action.text"),
+ KeyMapBundle.message("filter.clear.action.text"), IconLoader.getIcon("/actions/gc.png")) {
+ public void actionPerformed(AnActionEvent e) {
+ myActionsTree.filter(null, myQuicklists); //clear filtering
+ TreeUtil.collapseAll(myActionsTree.getTree(), 0);
+ myTreeExpansionMonitor.restore();
+ }
+ });
+
+ panel.add(searchToolbar, BorderLayout.EAST);
+ return panel;
+ }
+
+ private void filterTreeByShortcut(final ShortcutTextField firstShortcut,
+ final JCheckBox enable2Shortcut,
+ final ShortcutTextField secondShortcut) {
+ final KeyStroke keyStroke = firstShortcut.getKeyStroke();
+ if (keyStroke != null) {
+ if (!myTreeExpansionMonitor.isFreeze()) myTreeExpansionMonitor.freeze();
+ myActionsTree.filterTree(new KeyboardShortcut(keyStroke, enable2Shortcut.isSelected() ? secondShortcut.getKeyStroke() : null),
+ myQuicklists);
+ final JTree tree = myActionsTree.getTree();
+ TreeUtil.expandAll(tree);
+ }
+ }
+
+ private JPanel createFilteringPanel() {
+ myActionsTree.reset(myKeymap, myQuicklists);
+
+ final JLabel firstLabel = new JLabel(KeyMapBundle.message("filter.first.stroke.input"));
+ final JCheckBox enable2Shortcut = new JCheckBox(KeyMapBundle.message("filter.second.stroke.input"));
+ final ShortcutTextField firstShortcut = new ShortcutTextField();
+ firstShortcut.setColumns(10);
+ final ShortcutTextField secondShortcut = new ShortcutTextField();
+ secondShortcut.setColumns(10);
+
+ enable2Shortcut.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ secondShortcut.setEnabled(enable2Shortcut.isSelected());
+ if (enable2Shortcut.isSelected()) {
+ secondShortcut.requestFocusInWindow();
+ }
+ }
+ });
+
+ firstShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(DocumentEvent e) {
+ filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
+ }
+ });
+
+ secondShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(DocumentEvent e) {
+ filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
+ }
+ });
+
+ IJSwingUtilities.adjustComponentsOnMac(firstLabel, firstShortcut);
+ JPanel filterComponent = FormBuilder.createFormBuilder()
+ .addLabeledComponent(firstLabel, firstShortcut, true)
+ .addComponent(enable2Shortcut)
+ .setVerticalGap(0)
+ .setIndent(5)
+ .addComponent(secondShortcut)
+ .getPanel();
+
+ filterComponent.setBorder(new EmptyBorder(UIUtil.PANEL_SMALL_INSETS));
+
+ enable2Shortcut.setSelected(false);
+ secondShortcut.setEnabled(false);
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ firstShortcut.requestFocus();
+ }
+ });
+ return filterComponent;
+ }
+
+
+ public void dispose() {
+ super.dispose();
+ if (myPopup != null && myPopup.isVisible()) {
+ myPopup.cancel();
+ }
+ if (myFilterComponent != null) {
+ myFilterComponent.dispose();
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java
index a53ec8bed25b..6d223a185ef1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java
@@ -50,12 +50,16 @@ import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.FilterComponent;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Alarm;
+import com.intellij.util.IJSwingUtilities;
import com.intellij.util.containers.HashMap;
+import com.intellij.util.ui.FormBuilder;
+import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.*;
@@ -119,7 +123,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
if (shortcuts != null) {
for (Shortcut shortcut : shortcuts) {
- impl.removeShortcut(actionId, shortcut);
+ impl.removeShortcut(actionId, shortcut);
impl.addShortcut(newActionId, shortcut);
}
}
@@ -270,7 +274,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
importButton.setMargin(insets);
panel.add(importButton,gc);
-
+
}
@@ -376,7 +380,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
};
group.add(commonActionsManager.createExpandAllAction(treeExpander, myActionsTree.getTree()));
group.add(commonActionsManager.createCollapseAllAction(treeExpander, myActionsTree.getTree()));
-
+
group.add(new AnAction("Edit Shortcut", "Edit Shortcut", IconLoader.getIcon("/actions/properties.png")) {
{
registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)), myActionsTree.getTree());
@@ -459,40 +463,45 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
private JPanel createFilteringPanel() {
myActionsTree.reset(getSelectedKeymap(), getCurrentQuickListIds());
- JPanel filterComponent = new JPanel(new GridBagLayout());
- filterComponent.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
+ final JLabel firstLabel = new JLabel(KeyMapBundle.message("filter.first.stroke.input"));
+ final JCheckBox enable2Shortcut = new JCheckBox(KeyMapBundle.message("filter.second.stroke.input"));
final ShortcutTextField firstShortcut = new ShortcutTextField();
final ShortcutTextField secondShortcut = new ShortcutTextField();
- final JCheckBox enable2Shortcut = new JCheckBox(KeyMapBundle.message("filter.enable.second.stroke.checkbox"));
- firstShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
- protected void textChanged(DocumentEvent e) {
- filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
- }
- });
- secondShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
- protected void textChanged(DocumentEvent e) {
- filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
- }
- });
- final JLabel firstLabel = new JLabel(KeyMapBundle.message("filter.first.stroke.input"));
- final JLabel secondLabel = new JLabel(KeyMapBundle.message("filter.second.stroke.input"));
- filterComponent.add(firstLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(5,2,0,0),0,0));
- filterComponent.add(firstShortcut, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,2,0,0),0,0));
+
enable2Shortcut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
secondShortcut.setEnabled(enable2Shortcut.isSelected());
- secondLabel.setEnabled(enable2Shortcut.isSelected());
if (enable2Shortcut.isSelected()){
secondShortcut.requestFocusInWindow();
}
}
});
- filterComponent.add(enable2Shortcut, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),0,0));
- filterComponent.add(secondLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,2,0,0),0,0));
- filterComponent.add(secondShortcut, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,2,0,0),0,0));
+
+ firstShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(DocumentEvent e) {
+ filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
+ }
+ });
+
+ secondShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
+ protected void textChanged(DocumentEvent e) {
+ filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
+ }
+ });
+
+ IJSwingUtilities.adjustComponentsOnMac(firstLabel, firstShortcut);
+ JPanel filterComponent = FormBuilder.createFormBuilder()
+ .addLabeledComponent(firstLabel, firstShortcut, true)
+ .addComponent(enable2Shortcut)
+ .setVerticalGap(0)
+ .setIndent(5)
+ .addComponent(secondShortcut)
+ .getPanel();
+
+ filterComponent.setBorder(new EmptyBorder(UIUtil.PANEL_SMALL_INSETS));
+
enable2Shortcut.setSelected(false);
- secondLabel.setEnabled(false);
secondShortcut.setEnabled(false);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
@@ -938,7 +947,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
DefaultActionGroup group = new DefaultActionGroup();
final Shortcut[] shortcuts = mySelectedKeymap.getShortcuts(actionId);
-
+
group.add(new AnAction("Add Keyboard Shortcut") {
@Override
public void actionPerformed(AnActionEvent e) {
@@ -953,7 +962,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
addKeyboardShortcut(firstKeyboard);
}
});
-
+
group.add(new AnAction("Add Mouse Shortcut") {
@Override
public void actionPerformed(AnActionEvent e) {
@@ -991,7 +1000,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
dataContext,
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
true);
-
+
if (e instanceof MouseEvent) {
popup.show(new RelativePoint((MouseEvent)e));
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
index 719dd5276cd4..ce5ad9dacc10 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
@@ -50,6 +50,7 @@ public class CheckForUpdateAction extends AnAction implements DumbAware {
ProgressManager.getInstance().run(new Task.Modal(project, "Checking for updates", false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
+ indicator.setIndeterminate(true);
final CheckForUpdateResult result = UpdateChecker.checkForUpdates(instance, PropertiesComponent.getInstance(),
true
);
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
index 55440a7c90a8..75a7c922e459 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
@@ -329,6 +329,7 @@ public class PluginDownloader {
if (fileName == null || !PathUtil.isValidFileName(fileName)) {
FileUtil.delete(file);
+ LOG.warn("Invalid file name (header=" + contentDisposition + "; url=" + connection.getURL() + "; name=" + fileName + ")");
throw new IOException("Invalid filename returned by the server");
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java
index c1b580603cbd..fa98c84c896e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java
@@ -219,11 +219,13 @@ public class VirtualFilePointerImpl extends UserDataHolderBase implements Virtua
disposed = true;
final Pair pair = myFileAndUrl;
- if (pair.first != null) {
- ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).clearPointerCaches(pair.first.getUrl(), myListener);
+ VirtualFile file = pair.first;
+ if (file != null) {
+ ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).clearPointerCaches(file.getUrl(), myListener);
}
- if (pair.second != null) {
- ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).clearPointerCaches(pair.second, myListener);
+ String url = pair.second;
+ if (url != null && (file == null || !url.equals(file.getUrl()))) {
+ ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).clearPointerCaches(url, myListener);
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java
index 15ec1b998201..6b9ac8d5ab93 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java
@@ -72,7 +72,6 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
synchronized void clearPointerCaches(String url, VirtualFilePointerListener listener) {
TreeMap urlToPointer = myUrlToPointerMaps.get(listener);
- if (urlToPointer == null && ApplicationManager.getApplication().isUnitTestMode()) return;
assert urlToPointer != null;
urlToPointer.remove(VfsUtil.urlToPath(url));
if (urlToPointer.isEmpty()) {
@@ -148,12 +147,6 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
return url.substring(separatorIndex + JarFileSystem.JAR_SEPARATOR.length());
}
- @TestOnly
- public synchronized void cleanupForNextTest() {
- myUrlToPointerMaps.clear();
- myContainers.clear();
- }
-
/**
* @see #create(String, com.intellij.openapi.Disposable, com.intellij.openapi.vfs.pointers.VirtualFilePointerListener)
*/
@@ -339,7 +332,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
VirtualFilePointerListener listener = entry.getKey();
TreeMap map = entry.getValue();
for (VirtualFilePointerImpl pointer : map.values()) {
- myUrlToPointerMaps.clear();
+ //myUrlToPointerMaps.clear();
pointer.throwNotDisposedError("Not disposed pointer: listener="+listener);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java
index cc6e397f8e86..e1f9760bb1f8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java
@@ -128,8 +128,11 @@ public class PositionPanel extends EditorBasedWidget implements StatusBarWidget.
public void caretPositionChanged(final CaretEvent e) {
final Editor editor = e.getEditor();
Project project = editor.getProject();
- if (project != null && !project.isDisposed() && FileEditorManager.getInstance(project).getSelectedTextEditor() == e.getEditor()) {
- updatePosition(editor);
+ if (project != null && !project.isDisposed()) {
+ final FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); // returns null for default project
+ if (fileEditorManager != null && fileEditorManager.getSelectedTextEditor() == e.getEditor()) {
+ updatePosition(editor);
+ }
}
}
diff --git a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java
index b40e9ca29530..d902cbe95204 100644
--- a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java
+++ b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java
@@ -103,6 +103,11 @@ public class NewDirectoryProjectDialog extends DialogWrapper {
setErrorText("Project name can't be empty");
return;
}
+ if (myLocationField.getText().indexOf('$') >= 0) {
+ setOKActionEnabled(false);
+ setErrorText("Project directory name must not contain the $ character");
+ return;
+ }
DirectoryProjectGenerator generator = getProjectGenerator();
if (generator != null) {
String baseDirPath = myLocationField.getTextField().getText();
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java
index 116a6c59557c..ec9f7b074671 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java
@@ -424,6 +424,39 @@ public class VirtualFilePointerTest extends PlatformLangTestCase {
});
}
+ public void testDoubleDispose() throws IOException {
+ final File tempDir = createTempDirectory();
+ final File file = new File(tempDir, "f1");
+ boolean created = file.createNewFile();
+ assertTrue(created);
+
+ final VirtualFile[] vFile = new VirtualFile[1];
+ final String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, file.getCanonicalPath().replace(File.separatorChar, '/'));
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ vFile[0] = VirtualFileManager.getInstance().refreshAndFindFileByUrl(url);
+ }
+ });
+
+ Disposable disposable = Disposer.newDisposable();
+ final VirtualFilePointer pointer = myVirtualFilePointerManager.create(vFile[0], disposable, new VirtualFilePointerListener() {
+ @Override
+ public void beforeValidityChanged(VirtualFilePointer[] pointers) {
+ }
+
+ @Override
+ public void validityChanged(VirtualFilePointer[] pointers) {
+ }
+ });
+
+
+ assertTrue(pointer.isValid());
+
+ Disposer.dispose(disposable);
+ assertFalse(pointer.isValid());
+ }
+
public void testThreads() throws IOException, InterruptedException {
final File ioTempDir = createTempDirectory();
final File ioPtrBase = new File(ioTempDir, "parent");
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
index 01eca8e8d941..f4e051cf3f87 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
@@ -45,6 +45,7 @@ import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.editor.impl.EditorFactoryImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
@@ -335,6 +336,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
storeSettings();
myThreadTracker = new ThreadTracker();
+ DocumentImpl.CHECK_DOCUMENT_CONSISTENCY = !isPerformanceTest();
}
public static void doSetup(final LightProjectDescriptor descriptor,
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
index 2a853d4ea32f..84a3123ea6cf 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.module.EmptyModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
@@ -53,11 +54,9 @@ import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl;
import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
-import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
@@ -191,6 +190,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
}
DocumentCommitThread.getInstance().clearQueue();
+ DocumentImpl.CHECK_DOCUMENT_CONSISTENCY = !isPerformanceTest();
}
public Project getProject() {
@@ -339,10 +339,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
LocalHistoryImpl.getInstanceImpl().cleanupForNextTest();
- VirtualFilePointerManagerImpl virtualFilePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance();
- if (virtualFilePointerManager != null) {
- virtualFilePointerManager.cleanupForNextTest();
- }
PatchedWeakReference.clearAll();
}
diff --git a/platform/util-rt/src/com/intellij/BundleBase.java b/platform/util-rt/src/com/intellij/BundleBase.java
new file mode 100644
index 000000000000..566be37adda1
--- /dev/null
+++ b/platform/util-rt/src/com/intellij/BundleBase.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij;
+
+import com.intellij.openapi.util.SystemInfoRt;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author yole
+ */
+public abstract class BundleBase {
+ public static final char MNEMONIC = 0x1B;
+
+ public static boolean assertKeyIsFound = false;
+
+ public static String messageOrDefault(@Nullable final ResourceBundle bundle,
+ final String key,
+ @Nullable final String defaultValue,
+ final Object... params) {
+ if (bundle == null) return defaultValue;
+
+ String value;
+ try {
+ value = bundle.getString(key);
+ }
+ catch (MissingResourceException e) {
+ if (defaultValue != null) {
+ value = defaultValue;
+ }
+ else {
+ value = "!" + key + "!";
+ if (assertKeyIsFound) {
+ assert false : key + " is not found in " + bundle;
+ }
+ }
+ }
+
+ value = replaceMnemonicAmpersand(value);
+
+ if (params.length > 0 && value.indexOf('{') >= 0) {
+ return MessageFormat.format(value, params);
+ }
+
+ return value;
+ }
+
+ @NotNull
+ public static String message(@NotNull ResourceBundle bundle, @NotNull String key, @NotNull Object... params) {
+ return messageOrDefault(bundle, key, null, params);
+ }
+
+ public static String replaceMnemonicAmpersand(final String value) {
+ if (value.indexOf('&') >= 0) {
+ boolean useMacMnemonic = value.contains("&&");
+ StringBuilder realValue = new StringBuilder();
+ int i = 0;
+ while (i < value.length()) {
+ char c = value.charAt(i);
+ if (c == '\\') {
+ if (i < value.length() - 1 && value.charAt(i + 1) == '&') {
+ realValue.append('&');
+ i++;
+ }
+ else {
+ realValue.append(c);
+ }
+ }
+ else if (c == '&') {
+ if (i < value.length() - 1 && value.charAt(i + 1) == '&') {
+ if (SystemInfoRt.isMac) {
+ realValue.append(MNEMONIC);
+ }
+ i++;
+ }
+ else {
+ if (!SystemInfoRt.isMac || !useMacMnemonic) {
+ realValue.append(MNEMONIC);
+ }
+ }
+ }
+ else {
+ realValue.append(c);
+ }
+ i++;
+ }
+
+ return realValue.toString();
+ }
+ return value;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrPostfixExpression.java b/platform/util-rt/src/com/intellij/execution/rmi/RemoteCastable.java
similarity index 68%
rename from plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrPostfixExpression.java
rename to platform/util-rt/src/com/intellij/execution/rmi/RemoteCastable.java
index de2bb73e0d4d..816cb32afc17 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrPostfixExpression.java
+++ b/platform/util-rt/src/com/intellij/execution/rmi/RemoteCastable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,11 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package com.intellij.execution.rmi;
-package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
/**
- * @author ilyas
+ * @author Gregory.Shrago
*/
-public interface GrPostfixExpression extends GrUnaryExpression {
+public interface RemoteCastable extends Remote {
+ String getCastToClassName() throws RemoteException;
}
diff --git a/platform/util/src/com/intellij/execution/rmi/RemoteObject.java b/platform/util-rt/src/com/intellij/execution/rmi/RemoteObject.java
similarity index 92%
rename from platform/util/src/com/intellij/execution/rmi/RemoteObject.java
rename to platform/util-rt/src/com/intellij/execution/rmi/RemoteObject.java
index 2a487832a849..859186d41bce 100644
--- a/platform/util/src/com/intellij/execution/rmi/RemoteObject.java
+++ b/platform/util-rt/src/com/intellij/execution/rmi/RemoteObject.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,9 @@
*/
package com.intellij.execution.rmi;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import com.intellij.util.containers.ContainerUtilRt;
import java.lang.ref.WeakReference;
import java.rmi.Remote;
@@ -45,7 +45,7 @@ public class RemoteObject implements Remote, Unreferenced {
@Nullable
public synchronized T export(@Nullable T child) throws RemoteException {
if (child == null) return null;
- final T result = (T)UnicastRemoteObject.exportObject(child, 0);
+ @SuppressWarnings("unchecked") final T result = (T)UnicastRemoteObject.exportObject(child, 0);
myChildren.put((RemoteObject)child, result);
((RemoteObject)child).myParent = this;
return result;
@@ -68,7 +68,7 @@ public class RemoteObject implements Remote, Unreferenced {
if (children.isEmpty()) return;
final ArrayList list = new ArrayList(children.size());
for (WeakReference extends RemoteObject> child : children) {
- ContainerUtil.addIfNotNull(child.get(), list);
+ ContainerUtilRt.addIfNotNull(child.get(), list);
}
myChildren.keySet().removeAll(list);
for (RemoteObject child : list) {
@@ -85,6 +85,7 @@ public class RemoteObject implements Remote, Unreferenced {
UnicastRemoteObject.unexportObject(this, false);
}
catch (RemoteException e) {
+ //noinspection CallToPrintStackTrace
e.printStackTrace();
}
}
@@ -113,5 +114,4 @@ public class RemoteObject implements Remote, Unreferenced {
protected boolean isKnownException(Throwable ex) {
return false;
}
-
}
diff --git a/platform/util/src/com/intellij/execution/rmi/RemoteServer.java b/platform/util-rt/src/com/intellij/execution/rmi/RemoteServer.java
similarity index 76%
rename from platform/util/src/com/intellij/execution/rmi/RemoteServer.java
rename to platform/util-rt/src/com/intellij/execution/rmi/RemoteServer.java
index aa1b2100b0b7..9e846ea83a56 100644
--- a/platform/util/src/com/intellij/execution/rmi/RemoteServer.java
+++ b/platform/util-rt/src/com/intellij/execution/rmi/RemoteServer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,9 @@
*/
package com.intellij.execution.rmi;
+import org.jetbrains.annotations.Nullable;
+
import javax.naming.Context;
-import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import java.lang.reflect.InvocationHandler;
@@ -32,18 +33,17 @@ import java.util.Random;
public class RemoteServer {
private static Remote ourRemote;
- private static Remote ourStub;
+ @SuppressWarnings("UseOfSystemOutOrSystemErr")
protected static void start(Remote remote) throws Exception {
setupRMI();
banJNDI();
if (ourRemote != null) throw new AssertionError("Already started");
-
ourRemote = remote;
Registry registry;
- int port = 0;
+ int port;
for (Random random = new Random(); ;) {
port = random.nextInt(0xffff);
if (port < 4000) continue;
@@ -51,22 +51,23 @@ public class RemoteServer {
registry = LocateRegistry.createRegistry(port);
break;
}
- catch (ExportException ex) {
- }
+ catch (ExportException ignored) { }
}
- try {
- ourStub = UnicastRemoteObject.exportObject(ourRemote, 0);
- final String name = remote.getClass().getSimpleName() + Integer.toHexString(ourStub.hashCode());
- registry.bind(name, ourStub);
- System.out.println("Port/ID:" + port + "/" + name);
+ try {
+ Remote stub = UnicastRemoteObject.exportObject(ourRemote, 0);
+ final String name = remote.getClass().getSimpleName() + Integer.toHexString(stub.hashCode());
+ registry.bind(name, stub);
+
+ System.out.println("Port/ID: " + port + "/" + name);
+
Object lock = new Object();
synchronized (lock) {
lock.wait();
}
}
catch (Throwable e) {
- e.printStackTrace();
+ e.printStackTrace(System.err);
System.exit(1);
}
}
@@ -77,23 +78,24 @@ public class RemoteServer {
// do not use domain or http address for server
System.setProperty("java.rmi.server.hostname", "localhost");
- // do not use http tunnelling
+ // do not use HTTP tunnelling
System.setProperty("java.rmi.server.disableHttp", "true");
}
private static void banJNDI() {
- if (System.getProperty(InitialContext.INITIAL_CONTEXT_FACTORY) == null) {
- System.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, "com.intellij.execution.rmi.RemoteServer$Jndi");
+ if (System.getProperty(Context.INITIAL_CONTEXT_FACTORY) == null) {
+ System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.intellij.execution.rmi.RemoteServer$Jndi");
}
}
+ @SuppressWarnings("UnusedDeclaration")
public static class Jndi implements InitialContextFactory, InvocationHandler {
-
@Override
public Context getInitialContext(final Hashtable, ?> environment) throws NamingException {
- return (Context) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Context.class}, this );
+ return (Context)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Context.class}, this);
}
+ @Nullable
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
return null;
diff --git a/platform/util-rt/src/com/intellij/openapi/diagnostic/rt/Logger.java b/platform/util-rt/src/com/intellij/openapi/diagnostic/rt/Logger.java
new file mode 100644
index 000000000000..8eb116e18585
--- /dev/null
+++ b/platform/util-rt/src/com/intellij/openapi/diagnostic/rt/Logger.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.diagnostic.rt;
+
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.Method;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+
+/**
+ * A wrapper which uses either IDE logging subsystem (if available) or java.util.logging.
+ *
+ * @since 12.0
+ */
+public abstract class Logger {
+ private interface Factory {
+ Logger getInstance(@NotNull @NonNls final String category);
+ }
+
+ private static Factory ourFactory;
+
+ private synchronized static Factory getFactory() {
+ if (ourFactory == null) {
+ try {
+ ourFactory = new IdeaFactory();
+ }
+ catch (Throwable t) {
+ ourFactory = new JavaFactory();
+ }
+ }
+ return ourFactory;
+ }
+
+ @NotNull
+ public static Logger getInstance(@NotNull @NonNls final String category) {
+ return getFactory().getInstance(category);
+ }
+
+ public void info(@Nullable @NonNls final String message) {
+ info(message, null);
+ }
+
+ public void info(@NotNull final Throwable t) {
+ info(t.getMessage(), t);
+ }
+
+ public void warn(@Nullable @NonNls final String message) {
+ warn(message, null);
+ }
+
+ public void warn(@NotNull final Throwable t) {
+ warn(t.getMessage(), t);
+ }
+
+ public void error(@Nullable @NonNls final String message) {
+ error(message, null);
+ }
+
+ public void error(@NotNull final Throwable t) {
+ error(t.getMessage(), t);
+ }
+
+ public abstract void info(@Nullable @NonNls final String message, @Nullable final Throwable t);
+ public abstract void warn(@Nullable @NonNls final String message, @Nullable final Throwable t);
+ public abstract void error(@Nullable @NonNls final String message, @Nullable final Throwable t);
+
+ private static class JavaFactory implements Factory {
+ private final LogManager myManager = LogManager.getLogManager();
+
+ @Override
+ public Logger getInstance(@NotNull @NonNls final String category) {
+ final java.util.logging.Logger logger = myManager.getLogger(category);
+ return new Logger() {
+ @Override
+ public void info(@Nullable @NonNls final String message, @Nullable final Throwable t) {
+ logger.log(Level.INFO, message, t);
+ }
+
+ @Override
+ public void warn(@Nullable @NonNls final String message, @Nullable final Throwable t) {
+ logger.log(Level.WARNING, message, t);
+ }
+
+ @Override
+ public void error(@Nullable @NonNls final String message, @Nullable final Throwable t) {
+ logger.log(Level.SEVERE, message, t);
+ }
+ };
+ }
+ }
+
+ private static class IdeaFactory implements Factory {
+ private final Method myGetInstance;
+ private final Method myInfo;
+ private final Method myWarn;
+ private final Method myError;
+
+ private IdeaFactory() throws Exception {
+ final Class> loggerClass = Class.forName("com.intellij.openapi.diagnostic.Logger");
+ myGetInstance = loggerClass.getMethod("getInstance", String.class);
+ myGetInstance.setAccessible(true);
+ myInfo = loggerClass.getMethod("info", String.class, Throwable.class);
+ myInfo.setAccessible(true);
+ myWarn = loggerClass.getMethod("warn", String.class, Throwable.class);
+ myInfo.setAccessible(true);
+ myError = loggerClass.getMethod("error", String.class, Throwable.class);
+ myError.setAccessible(true);
+ }
+
+ @Override
+ public Logger getInstance(@NotNull @NonNls final String category) {
+ try {
+ final Object logger = myGetInstance.invoke(null, category);
+ return new Logger() {
+ @Override
+ public void info(@Nullable @NonNls final String message, @Nullable final Throwable t) {
+ try {
+ myInfo.invoke(logger, message, t);
+ }
+ catch (Exception ignored) { }
+ }
+
+ @Override
+ public void warn(@Nullable @NonNls final String message, @Nullable final Throwable t) {
+ try {
+ myWarn.invoke(logger, message, t);
+ }
+ catch (Exception ignored) { }
+ }
+
+ @Override
+ public void error(@Nullable @NonNls final String message, @Nullable final Throwable t) {
+ try {
+ myError.invoke(logger, message, t);
+ }
+ catch (Exception ignored) { }
+ }
+ };
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/platform/util/src/com/intellij/openapi/util/Comparing.java b/platform/util-rt/src/com/intellij/openapi/util/Comparing.java
similarity index 94%
rename from platform/util/src/com/intellij/openapi/util/Comparing.java
rename to platform/util-rt/src/com/intellij/openapi/util/Comparing.java
index 95f5f8ab166a..95c7d6df8676 100644
--- a/platform/util/src/com/intellij/openapi/util/Comparing.java
+++ b/platform/util-rt/src/com/intellij/openapi/util/Comparing.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
*/
package com.intellij.openapi.util;
-import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.util.text.StringUtilRt;
import java.util.Arrays;
import java.util.Collection;
@@ -77,7 +77,7 @@ public class Comparing {
if (c1 == c2) {
continue;
}
- if (!caseSensitive && StringUtil.charsEqualIgnoreCase(c1, c2)) continue;
+ if (!caseSensitive && StringUtilRt.charsEqualIgnoreCase(c1, c2)) continue;
return false;
}
@@ -140,6 +140,10 @@ public class Comparing {
return o1 < o2 ? -1 : o1 == o2 ? 0 : 1;
}
+ public static int compare(boolean o1, boolean o2) {
+ return o1 == o2 ? 0 : o1 ? 1 : -1;
+ }
+
public static int compare(int o1, int o2) {
return o1 < o2 ? -1 : o1 == o2 ? 0 : 1;
}
diff --git a/platform/util/src/com/intellij/openapi/util/Pair.java b/platform/util-rt/src/com/intellij/openapi/util/Pair.java
similarity index 98%
rename from platform/util/src/com/intellij/openapi/util/Pair.java
rename to platform/util-rt/src/com/intellij/openapi/util/Pair.java
index d380de5a044a..ce63e207fcfa 100644
--- a/platform/util/src/com/intellij/openapi/util/Pair.java
+++ b/platform/util-rt/src/com/intellij/openapi/util/Pair.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package com.intellij.openapi.util;
import com.intellij.util.Function;
import org.jetbrains.annotations.Nullable;
-
public class Pair {
public final A first;
public final B second;
diff --git a/platform/util-rt/src/com/intellij/openapi/util/SystemInfoRt.java b/platform/util-rt/src/com/intellij/openapi/util/SystemInfoRt.java
new file mode 100644
index 000000000000..cdce6e247e32
--- /dev/null
+++ b/platform/util-rt/src/com/intellij/openapi/util/SystemInfoRt.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.util;
+
+/**
+ * Stripped-down version of {@code com.intellij.openapi.util.SystemInfo}.
+ * Intended to use by external (out-of-IDE-process) runners and helpers so it should not contain any library dependencies.
+ *
+ * @since 12.0
+ */
+@SuppressWarnings({"HardCodedStringLiteral", "UtilityClassWithoutPrivateConstructor"})
+public class SystemInfoRt {
+ public static final String OS_NAME = System.getProperty("os.name");
+ public static final String OS_VERSION = System.getProperty("os.version").toLowerCase();
+
+ protected static final String _OS_NAME = OS_NAME.toLowerCase();
+ public static final boolean isWindows = _OS_NAME.startsWith("windows");
+ public static final boolean isOS2 = _OS_NAME.startsWith("os/2") || _OS_NAME.startsWith("os2");
+ public static final boolean isMac = _OS_NAME.startsWith("mac");
+ public static final boolean isLinux = _OS_NAME.startsWith("linux");
+ public static final boolean isUnix = !isWindows && !isOS2;
+
+ public static final boolean isFileSystemCaseSensitive = !isWindows && !isOS2 && !isMac;
+}
diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtilLight.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java
similarity index 74%
rename from platform/util/src/com/intellij/openapi/util/io/FileUtilLight.java
rename to platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java
index ae174b7901d7..ff77c63af49c 100644
--- a/platform/util/src/com/intellij/openapi/util/io/FileUtilLight.java
+++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java
@@ -15,9 +15,9 @@
*/
package com.intellij.openapi.util.io;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.diagnostic.rt.Logger;
+import com.intellij.openapi.util.SystemInfoRt;
+import com.intellij.openapi.util.text.StringUtilRt;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,14 +27,22 @@ import java.io.*;
import java.util.UUID;
/**
- * This is a light version of {@link FileUtil}.
- * It is used by scripts loaded externally and almost independent of IDEA, so add here as few dependencies as possible.
+ * Stripped-down version of {@code com.intellij.openapi.util.io.FileUtil}.
+ * Intended to use by external (out-of-IDE-process) runners and helpers so it should not contain any library dependencies.
+ *
+ * @since 12.0
*/
-public class FileUtilLight {
-
- private static String ourCanonicalTempPathCache = null;
+@SuppressWarnings({"UtilityClassWithoutPrivateConstructor"})
+public class FileUtilRt {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.io.FileUtilLight");
+ protected static final ThreadLocal BUFFER = new ThreadLocal() {
+ protected byte[] initialValue() {
+ return new byte[1024 * 20];
+ }
+ };
+
+ private static String ourCanonicalTempPathCache = null;
@NotNull
public static File createTempDirectory(@NotNull @NonNls String prefix, @Nullable @NonNls String suffix) throws IOException {
@@ -55,8 +63,7 @@ public class FileUtilLight {
}
@NotNull
- public static File createTempFile(@NonNls final File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix, final boolean create)
- throws IOException {
+ public static File createTempFile(@NonNls File dir, @NotNull @NonNls String prefix, @Nullable @NonNls String suffix, boolean create) throws IOException {
return createTempFile(dir, prefix, suffix, create, true);
}
@@ -122,7 +129,7 @@ public class FileUtilLight {
private static File normalizeFile(File temp) throws IOException {
final File canonical = temp.getCanonicalFile();
- return SystemInfo.isWindows && canonical.getAbsolutePath().contains(" ") ? temp.getAbsoluteFile() : canonical;
+ return SystemInfoRt.isWindows && canonical.getAbsolutePath().contains(" ") ? temp.getAbsoluteFile() : canonical;
}
public static String getTempDirectory() {
@@ -136,7 +143,7 @@ public class FileUtilLight {
final File file = new File(System.getProperty("java.io.tmpdir"));
try {
final String canonical = file.getCanonicalPath();
- if (!SystemInfo.isWindows || !canonical.contains(" ")) {
+ if (!SystemInfoRt.isWindows || !canonical.contains(" ")) {
return canonical;
}
}
@@ -169,7 +176,7 @@ public class FileUtilLight {
*
* @param path the path to use
* @param executableFlag new value of executable attribute
- * @throws IOException if there is a problem with setting the flag
+ * @throws java.io.IOException if there is a problem with setting the flag
*/
public static void setExecutableAttribute(@NotNull String path, boolean executableFlag) throws IOException {
final File file = new File(path);
@@ -189,14 +196,14 @@ public class FileUtilLight {
}
@NotNull
- public static String loadFile(@NotNull File file, String encoding) throws IOException {
+ public static String loadFile(@NotNull File file, @Nullable @NonNls String encoding) throws IOException {
return loadFile(file, encoding, false);
}
@NotNull
- public static String loadFile(@NotNull File file, String encoding, boolean convertLineSeparators) throws IOException {
+ public static String loadFile(@NotNull File file, @Nullable @NonNls String encoding, boolean convertLineSeparators) throws IOException {
final String s = new String(loadFileText(file, encoding));
- return convertLineSeparators ? StringUtil.convertLineSeparators(s) : s;
+ return convertLineSeparators ? StringUtilRt.convertLineSeparators(s) : s;
}
@NotNull
@@ -205,8 +212,9 @@ public class FileUtilLight {
}
@NotNull
- public static char[] loadFileText(@NotNull File file, @NonNls String encoding) throws IOException {
+ public static char[] loadFileText(@NotNull File file, @Nullable @NonNls String encoding) throws IOException {
InputStream stream = new FileInputStream(file);
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
Reader reader = encoding == null ? new InputStreamReader(stream) : new InputStreamReader(stream, encoding);
try {
return loadText(reader, (int)file.length());
@@ -235,4 +243,29 @@ public class FileUtilLight {
}
}
+ @NotNull
+ public static byte[] loadBytes(@NotNull InputStream stream) throws IOException {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ final byte[] bytes = BUFFER.get();
+ while (true) {
+ int n = stream.read(bytes, 0, bytes.length);
+ if (n <= 0) break;
+ buffer.write(bytes, 0, n);
+ }
+ buffer.close();
+ return buffer.toByteArray();
+ }
+
+ @NotNull
+ public static byte[] loadBytes(@NotNull InputStream stream, int length) throws IOException {
+ byte[] bytes = new byte[length];
+ int count = 0;
+ while (count < length) {
+ int n = stream.read(bytes, count, length - count);
+ if (n <= 0) break;
+ count += n;
+ }
+ return bytes;
+ }
+
}
diff --git a/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java
new file mode 100644
index 000000000000..9b98436709b8
--- /dev/null
+++ b/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.util.text;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Stripped-down version of {@code com.intellij.openapi.util.text.StringUtil}.
+ * Intended to use by external (out-of-IDE-process) runners and helpers so it should not contain any library dependencies.
+ *
+ * @since 12.0
+ */
+@SuppressWarnings({"UtilityClassWithoutPrivateConstructor"})
+public class StringUtilRt {
+ public static boolean charsEqualIgnoreCase(char a, char b) {
+ return a == b || toUpperCase(a) == toUpperCase(b) || toLowerCase(a) == toLowerCase(b);
+ }
+
+ public static char toUpperCase(char a) {
+ if (a < 'a') {
+ return a;
+ }
+ if (a >= 'a' && a <= 'z') {
+ return (char)(a + ('A' - 'a'));
+ }
+ return Character.toUpperCase(a);
+ }
+
+ public static char toLowerCase(final char a) {
+ if (a < 'A' || a >= 'a' && a <= 'z') {
+ return a;
+ }
+
+ if (a >= 'A' && a <= 'Z') {
+ return (char)(a + ('a' - 'A'));
+ }
+
+ return Character.toLowerCase(a);
+ }
+
+ /**
+ * Converts line separators to "\n"
+ */
+ @NotNull
+ public static String convertLineSeparators(@NotNull String text) {
+ return convertLineSeparators(text, false);
+ }
+
+ @NotNull
+ public static String convertLineSeparators(@NotNull String text, boolean keepCarriageReturn) {
+ return convertLineSeparators(text, "\n", null, keepCarriageReturn);
+ }
+
+ @NotNull
+ public static String convertLineSeparators(@NotNull String text, @NotNull String newSeparator) {
+ return convertLineSeparators(text, newSeparator, null);
+ }
+
+ @NotNull
+ public static String convertLineSeparators(@NotNull String text, @NotNull String newSeparator, @Nullable int[] offsetsToKeep) {
+ return convertLineSeparators(text, newSeparator, offsetsToKeep, false);
+ }
+
+ @NotNull
+ public static String convertLineSeparators(@NotNull String text, @NotNull String newSeparator, @Nullable int[] offsetsToKeep,
+ boolean keepCarriageReturn) {
+ StringBuilder buffer = null;
+ int intactLength = 0;
+ final boolean newSeparatorIsSlashN = "\n".equals(newSeparator);
+ for (int i = 0; i < text.length(); i++) {
+ char c = text.charAt(i);
+ if (c == '\n') {
+ if (!newSeparatorIsSlashN) {
+ if (buffer == null) {
+ buffer = new StringBuilder(text.length());
+ buffer.append(text, 0, intactLength);
+ }
+ buffer.append(newSeparator);
+ shiftOffsets(offsetsToKeep, buffer.length(), 1, newSeparator.length());
+ }
+ else if (buffer == null) {
+ intactLength++;
+ }
+ else {
+ buffer.append(c);
+ }
+ }
+ else if (c == '\r') {
+ boolean followedByLineFeed = i < text.length() - 1 && text.charAt(i + 1) == '\n';
+ if (!followedByLineFeed && keepCarriageReturn) {
+ if (buffer == null) {
+ intactLength++;
+ }
+ else {
+ buffer.append(c);
+ }
+ continue;
+ }
+ if (buffer == null) {
+ buffer = new StringBuilder(text.length());
+ buffer.append(text, 0, intactLength);
+ }
+ buffer.append(newSeparator);
+ if (followedByLineFeed) {
+ //noinspection AssignmentToForLoopParameter
+ i++;
+ shiftOffsets(offsetsToKeep, buffer.length(), 2, newSeparator.length());
+ }
+ else {
+ shiftOffsets(offsetsToKeep, buffer.length(), 1, newSeparator.length());
+ }
+ }
+ else {
+ if (buffer == null) {
+ intactLength++;
+ }
+ else {
+ buffer.append(c);
+ }
+ }
+ }
+ return buffer == null ? text : buffer.toString();
+ }
+
+ private static void shiftOffsets(int[] offsets, int changeOffset, int oldLength, int newLength) {
+ if (offsets == null) return;
+ int shift = newLength - oldLength;
+ if (shift == 0) return;
+ for (int i = 0; i < offsets.length; i++) {
+ int offset = offsets[i];
+ if (offset >= changeOffset + oldLength) {
+ offsets[i] += shift;
+ }
+ }
+ }
+
+ public static int parseInt(final String string, final int defaultValue) {
+ try {
+ return Integer.parseInt(string);
+ }
+ catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ public static double parseDouble(final String string, final double defaultValue) {
+ try {
+ return Double.parseDouble(string);
+ }
+ catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ @NotNull
+ public static String getShortName(@NotNull Class aClass) {
+ return getShortName(aClass.getName());
+ }
+
+ @NotNull
+ public static String getShortName(@NotNull String fqName) {
+ return getShortName(fqName, '.');
+ }
+
+ @NotNull
+ public static String getShortName(@NotNull String fqName, char separator) {
+ int lastPointIdx = fqName.lastIndexOf(separator);
+ if (lastPointIdx >= 0) {
+ return fqName.substring(lastPointIdx + 1);
+ }
+ return fqName;
+ }
+}
diff --git a/platform/util-rt/src/com/intellij/util/ArrayUtilRt.java b/platform/util-rt/src/com/intellij/util/ArrayUtilRt.java
new file mode 100644
index 000000000000..c898e0149572
--- /dev/null
+++ b/platform/util-rt/src/com/intellij/util/ArrayUtilRt.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util;
+
+import org.jetbrains.annotations.NotNull;
+import com.intellij.util.containers.ContainerUtilRt;
+
+import java.io.File;
+import java.util.Collection;
+
+/**
+ * Stripped-down version of {@code com.intellij.util.ArrayUtil}.
+ * Intended to use by external (out-of-IDE-process) runners and helpers so it should not contain any library dependencies.
+ *
+ * @since 12.0
+ */
+@SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "SSBasedInspection"})
+public class ArrayUtilRt {
+ public static final short[] EMPTY_SHORT_ARRAY = new short[0];
+ public static final char[] EMPTY_CHAR_ARRAY = new char[0];
+ public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+ public static final int[] EMPTY_INT_ARRAY = new int[0];
+ public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
+ public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+ public static final String[] EMPTY_STRING_ARRAY = new String[0];
+ public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+ public static final long[] EMPTY_LONG_ARRAY = new long[0];
+ public static final Collection[] EMPTY_COLLECTION_ARRAY = new Collection[0];
+ public static final File[] EMPTY_FILE_ARRAY = new File[0];
+ public static final Runnable[] EMPTY_RUNNABLE_ARRAY = new Runnable[0];
+
+ @NotNull
+ public static String[] toStringArray(@NotNull Collection collection) {
+ if (collection.isEmpty()) return EMPTY_STRING_ARRAY;
+ return ContainerUtilRt.toArray(collection, new String[collection.size()]);
+ }
+}
diff --git a/platform/util/src/com/intellij/util/Function.java b/platform/util-rt/src/com/intellij/util/Function.java
similarity index 94%
rename from platform/util/src/com/intellij/util/Function.java
rename to platform/util-rt/src/com/intellij/util/Function.java
index 089895796a25..fef2a94aaf2d 100644
--- a/platform/util/src/com/intellij/util/Function.java
+++ b/platform/util-rt/src/com/intellij/util/Function.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
*/
package com.intellij.util;
-import org.jetbrains.annotations.Nullable;
-
import java.util.Collection;
/**
diff --git a/platform/util/src/com/intellij/util/NotNullFunction.java b/platform/util-rt/src/com/intellij/util/NotNullFunction.java
similarity index 95%
rename from platform/util/src/com/intellij/util/NotNullFunction.java
rename to platform/util-rt/src/com/intellij/util/NotNullFunction.java
index cae730360bd4..802172e3e5c4 100644
--- a/platform/util/src/com/intellij/util/NotNullFunction.java
+++ b/platform/util-rt/src/com/intellij/util/NotNullFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/platform/util/src/com/intellij/util/NullableFunction.java b/platform/util-rt/src/com/intellij/util/NullableFunction.java
similarity index 95%
rename from platform/util/src/com/intellij/util/NullableFunction.java
rename to platform/util-rt/src/com/intellij/util/NullableFunction.java
index a57e9b5dff17..ed768ae3ef7a 100644
--- a/platform/util/src/com/intellij/util/NullableFunction.java
+++ b/platform/util-rt/src/com/intellij/util/NullableFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java
new file mode 100644
index 000000000000..7716a6d7d050
--- /dev/null
+++ b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.containers;
+
+import com.intellij.util.ArrayUtilRt;
+import com.intellij.util.Function;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Stripped-down version of {@code com.intellij.util.containers.ContainerUtil}.
+ * Intended to use by external (out-of-IDE-process) runners and helpers so it should not contain any library dependencies.
+ *
+ * @since 12.0
+ */
+@SuppressWarnings({"UtilityClassWithoutPrivateConstructor"})
+public class ContainerUtilRt {
+ private static final int ARRAY_COPY_THRESHOLD = 20;
+
+ /**
+ * Optimized toArray() as opposed to the {@link java.util.Collections#emptyList()}.
+ */
+ private static class EmptyList extends AbstractList