editor) {
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/code.html b/java/java-tests/testData/codeInsight/javadocIG/code.html
new file mode 100644
index 000000000000..e75e09176a2f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/code.html
@@ -0,0 +1,10 @@
+ Fooint foo
+
+
+ class Clazzz {
+ def f[U](u: U) {}
+
+ val a = 1
+ }
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/code.java b/java/java-tests/testData/codeInsight/javadocIG/code.java
new file mode 100644
index 000000000000..f5cf2a77f600
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/code.java
@@ -0,0 +1,14 @@
+class Foo {
+ /**
+ *
+ * {@code
+ * class Clazzz {
+ * def f[U](u: U) {}
+ *
+ * val a = 1
+ * }
+ * }
+ *
+ */
+ int foo;
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass.log b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass.log
new file mode 100644
index 000000000000..228bc41f8f7e
--- /dev/null
+++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass.log
@@ -0,0 +1,11 @@
+Compiling files:
+src/package2/A.java
+End of files
+Cleaning output files:
+out/production/AddClassHidingImportedClass/package2/B.class
+out/production/AddClassHidingImportedClass/package3/C.class
+End of files
+Compiling files:
+src/package2/B.java
+src/package3/C.java
+End of files
diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package1/A.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package1/A.java
new file mode 100644
index 000000000000..a61ecd9b2705
--- /dev/null
+++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package1/A.java
@@ -0,0 +1,7 @@
+package package1;
+
+public class A {
+ public static class D {
+ public final String s = new String("package1");
+ }
+}
diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/A.java.new b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/A.java.new
new file mode 100644
index 000000000000..98b0feeffca2
--- /dev/null
+++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/A.java.new
@@ -0,0 +1,7 @@
+package package2;
+
+public class A {
+ public static class D {
+ public final String s = new String("package2");
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/B.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/B.java
new file mode 100644
index 000000000000..a32b694a09c8
--- /dev/null
+++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package2/B.java
@@ -0,0 +1,6 @@
+package package2;
+import package1.*;
+
+public class B extends A{
+
+}
diff --git a/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package3/C.java b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package3/C.java
new file mode 100644
index 000000000000..04d86d390ea6
--- /dev/null
+++ b/java/java-tests/testData/compileServer/incremental/common/addClassHidingImportedClass/src/package3/C.java
@@ -0,0 +1,14 @@
+package package3;
+
+import package2.B;
+
+public class C {
+
+ public B.D p;
+
+ public String get() {
+ p = new B.D();
+ return p.s;
+ }
+
+}
diff --git a/java/java-tests/testData/psi/resolve/method/generics/CovariantReturnTypeAnonymous.java b/java/java-tests/testData/psi/resolve/method/generics/CovariantReturnTypeAnonymous.java
new file mode 100644
index 000000000000..b487a309af24
--- /dev/null
+++ b/java/java-tests/testData/psi/resolve/method/generics/CovariantReturnTypeAnonymous.java
@@ -0,0 +1,20 @@
+interface X {
+ A[] foo();
+}
+
+class A {}
+
+class B extends A {}
+
+class C {
+ final X x = new X() {
+ @Override
+ public B[] foo() {
+ return new B[0];
+ }
+ };
+
+ B[] bar() {
+ return x.f[oo();
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy
index 45f79b2ce770..b9620a18b0ab 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy
@@ -20,6 +20,7 @@ import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.PsiTestUtil
@@ -141,5 +142,12 @@ public class Test {
myFixture.assertPreferredCompletionItems 0, 'getBuilder'
}
+ public void testNoJavaStructureModificationOnSecondInvocation() {
+ myFixture.configureByText 'a.java', 'class Foo { Xxxxx }'
+ def oldCount = PsiManager.getInstance(project).modificationTracker.javaStructureModificationCount
+ assert !myFixture.completeBasic()
+ assert !myFixture.completeBasic()
+ assert oldCount == PsiManager.getInstance(project).modificationTracker.javaStructureModificationCount
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
index 34a45ee3e094..7cc843809a0e 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
@@ -82,6 +82,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
+ public void testArgumentOfAnonymousClass() throws Exception {
+ doTest();
+ }
+
private void doTest() {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
index ae3df006df09..80d2e4ac2fb6 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
@@ -72,6 +72,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
doTestField();
}
+ public void testCode() throws Exception {
+ doTestField();
+ }
+
public void testEnumConstantOrdinal() throws Exception {
PsiClass psiClass = getTestClass();
PsiField field = psiClass.getFields() [0];
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java
index ed2db874ef46..a84b0703eef8 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java
@@ -313,7 +313,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
assertEquals(0, countInitializedTools(profile));
profile.writeExternal(new Element("profile"));
List initializedTools = getInitializedTools(profile);
- if (initializedTools.size() != 1) {
+ if (initializedTools.size() > 0) {
for (InspectionToolWrapper initializedTool : initializedTools) {
System.out.println(initializedTool.getShortName());
}
diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java
index 3641d9dc06f4..a721f29a8a88 100644
--- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java
+++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java
@@ -186,7 +186,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
return instance;
}
- public void testDirInfos() {
+ public void testDirInfos() throws IOException {
checkInfoNull(myRootVFile);
// beware: files in directory index
@@ -215,9 +215,13 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertEquals(myModule1Dir, checkInfoNotNull(myLibClsDir).getContentRoot());
checkInfo(myModule3Dir, myModule3, false, false, null, null);
+
+ VirtualFile cvs = myPack1Dir.createChildDirectory(this, "CVS");
+ checkInfoNull(cvs);
+ assertNull(ProjectRootManager.getInstance(myProject).getFileIndex().getPackageNameByDirectory(cvs));
}
- public void testDirsByPackageName() {
+ public void testDirsByPackageName() throws IOException {
checkPackage("", true, myFileLibSrc, myFileLibCls, mySrcDir1, myTestSrc1, myResDir, myTestResDir, myLibSrcDir, myLibClsDir, mySrcDir2);
checkPackage("", false, myFileLibCls, mySrcDir1, myTestSrc1, myResDir, myTestResDir, myLibClsDir, mySrcDir2);
diff --git a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveMethod15Test.java b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveMethod15Test.java
index 36b1c4c9de63..788febf4da6e 100644
--- a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveMethod15Test.java
+++ b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveMethod15Test.java
@@ -7,7 +7,6 @@ import com.intellij.navigation.NavigationItem;
import org.jetbrains.annotations.NonNls;
import static org.junit.Assert.assertThat;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.Assert.assertTrue;
/**
* @author dsl
@@ -129,6 +128,16 @@ public class ResolveMethod15Test extends Resolve15TestCase {
assertTrue(containingClass != null ? containingClass.getName() : null, containingClass instanceof PsiAnonymousClass);
}
+ public void testCovariantReturnTypeAnonymous() throws Exception {
+ final PsiReference ref = configureByFile();
+ assertThat(ref, instanceOf(PsiReferenceExpression.class));
+ final PsiReferenceExpression refExpr = (PsiReferenceExpression)ref;
+ final PsiElement resolve = refExpr.resolve();
+ assertTrue(resolve != null ? resolve.toString() : null, resolve instanceof PsiMethod);
+ final PsiClass containingClass = ((PsiMethod)resolve).getContainingClass();
+ assertTrue(containingClass != null ? containingClass.getName() : null, !(containingClass instanceof PsiAnonymousClass));
+ }
+
public void testFilterFixedVsVarargs1() throws Exception {
final PsiReference ref = configureByFile();
assertThat(ref, instanceOf(PsiReferenceExpression.class));
diff --git a/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java b/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java
index 3fcd9c959a50..ff02aadc3856 100644
--- a/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java
+++ b/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java
@@ -15,26 +15,29 @@
*/
package com.intellij.execution.filters;
-import com.intellij.openapi.application.AccessToken;
-import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
/**
* User: Irina.Chernushina
@@ -61,8 +64,8 @@ public class ExceptionWorker {
private final Project myProject;
private final GlobalSearchScope mySearchScope;
private Filter.Result myResult;
- private PsiClass myClass;
- private PsiFile myFile;
+ private PsiClass[] myClasses = PsiClass.EMPTY_ARRAY;
+ private PsiFile[] myFiles = PsiFile.EMPTY_ARRAY;
private String myMethod;
private Trinity myInfo;
@@ -90,16 +93,17 @@ public class ExceptionWorker {
final String lineString = fileAndLine.substring(colonIndex + 1);
try {
final int lineNumber = Integer.parseInt(lineString);
- myClass = findPositionClass(line);
- myFile = myClass == null ? null : (PsiFile)myClass.getContainingFile().getNavigationElement();
- if (myFile == null) {
- // try find the file with the required name
- PsiFile[] files = PsiShortNamesCache.getInstance(myProject).getFilesByName(fileAndLine.substring(0, colonIndex).trim());
- if (files.length > 0) {
- myFile = files[0];
- }
+ myClasses = findPositionClasses(line);
+ myFiles = new PsiFile[myClasses.length];
+ for (int i = 0; i < myClasses.length; i++) {
+ myFiles[i] = (PsiFile)myClasses[i].getContainingFile().getNavigationElement();
}
- if (myFile == null) return;
+ if (myFiles.length == 0) {
+ // try find the file with the required name
+ //todo[nik] it would be better to use FilenameIndex here to honor the scope by it isn't accessible in Open API
+ myFiles = PsiShortNamesCache.getInstance(myProject).getFilesByName(fileAndLine.substring(0, colonIndex).trim());
+ }
+ if (myFiles.length == 0) return;
/*
IDEADEV-4976: Some scramblers put something like SourceFile mock instead of real class name.
@@ -113,12 +117,31 @@ public class ExceptionWorker {
final int highlightStartOffset = textStartOffset + lparenthIndex + 1;
final int highlightEndOffset = textStartOffset + rparenthIndex;
- final VirtualFile virtualFile = myFile.getVirtualFile();
- HyperlinkInfo linkInfo = new MyHyperlinkInfo(myProject, virtualFile, lineNumber);
+ ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
+ List virtualFilesInLibraries = new ArrayList();
+ List virtualFilesInContent = new ArrayList();
+ for (PsiFile file : myFiles) {
+ VirtualFile virtualFile = file.getVirtualFile();
+ if (index.isInContent(virtualFile)) {
+ virtualFilesInContent.add(virtualFile);
+ }
+ else {
+ virtualFilesInLibraries.add(virtualFile);
+ }
+ }
- boolean inContent = ProjectRootManager.getInstance(myProject).getFileIndex().isInContent(virtualFile);
- TextAttributes attributes = inContent ? HYPERLINK_ATTRIBUTES : LIBRARY_HYPERLINK_ATTRIBUTES;
+ List virtualFiles;
+ TextAttributes attributes;
+ if (virtualFilesInContent.isEmpty()) {
+ attributes = LIBRARY_HYPERLINK_ATTRIBUTES;
+ virtualFiles = virtualFilesInLibraries;
+ }
+ else {
+ attributes = HYPERLINK_ATTRIBUTES;
+ virtualFiles = virtualFilesInContent;
+ }
+ HyperlinkInfo linkInfo = HyperlinkInfoFactory.getInstance().createMultipleFilesHyperlinkInfo(virtualFiles, lineNumber - 1, myProject);
myResult = new Filter.Result(highlightStartOffset, highlightEndOffset, linkInfo, attributes);
}
catch (NumberFormatException e) {
@@ -126,22 +149,23 @@ public class ExceptionWorker {
}
}
- private PsiClass findPositionClass(String line) {
+ private PsiClass[] findPositionClasses(String line) {
String className = myInfo.first.substring(line).trim();
- PsiClass result = findClassPreferringMyScope(className);
- if (result == null) {
+ PsiClass[] result = findClassesPreferringMyScope(className);
+ if (result.length == 0) {
final int dollarIndex = className.indexOf('$');
if (dollarIndex >= 0) {
- result = findClassPreferringMyScope(className.substring(0, dollarIndex));
+ result = findClassesPreferringMyScope(className.substring(0, dollarIndex));
}
}
return result;
}
- private PsiClass findClassPreferringMyScope(String className) {
+ @NotNull
+ private PsiClass[] findClassesPreferringMyScope(String className) {
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
- PsiClass result = psiFacade.findClass(className, mySearchScope);
- return result != null ? result : psiFacade.findClass(className, GlobalSearchScope.allScope(myProject));
+ PsiClass[] result = psiFacade.findClasses(className, mySearchScope);
+ return result.length != 0 ? result : psiFacade.findClasses(className, GlobalSearchScope.allScope(myProject));
}
public Filter.Result getResult() {
@@ -149,7 +173,7 @@ public class ExceptionWorker {
}
public PsiClass getPsiClass() {
- return myClass;
+ return ArrayUtil.getFirstElement(myClasses);
}
public String getMethod() {
@@ -157,7 +181,7 @@ public class ExceptionWorker {
}
public PsiFile getFile() {
- return myFile;
+ return ArrayUtil.getFirstElement(myFiles);
}
public Trinity getInfo() {
@@ -205,59 +229,4 @@ public class ExceptionWorker {
}
return pos;
}
-
- @Nullable
- static OpenFileHyperlinkInfo getOpenFileHyperlinkInfo(Filter.Result result) {
- if (result.hyperlinkInfo instanceof MyHyperlinkInfo) {
- MyHyperlinkInfo info = (MyHyperlinkInfo)result.hyperlinkInfo;
- return new OpenFileHyperlinkInfo(info.myProject, info.myVirtualFile, info.myLineNumber);
- }
- return null;
- }
-
- private static class MyHyperlinkInfo implements FileHyperlinkInfo {
- private final VirtualFile myVirtualFile;
- private final int myLineNumber;
- private final Project myProject;
-
- public MyHyperlinkInfo(@NotNull Project project, @NotNull VirtualFile virtualFile, int lineNumber) {
- myProject = project;
- myVirtualFile = virtualFile;
- myLineNumber = lineNumber;
- }
-
- @Override
- public void navigate(Project project) {
- VirtualFile currentVirtualFile = null;
-
- AccessToken accessToken = ReadAction.start();
-
- try {
- if (!myVirtualFile.isValid()) return;
-
- PsiFile psiFile = PsiManager.getInstance(project).findFile(myVirtualFile);
- if (psiFile != null) {
- PsiElement navigationElement = psiFile.getNavigationElement(); // Sources may be downloaded.
- if (navigationElement instanceof PsiFile) {
- currentVirtualFile = ((PsiFile)navigationElement).getVirtualFile();
- }
- }
-
- if (currentVirtualFile == null) {
- currentVirtualFile = myVirtualFile;
- }
- }
- finally {
- accessToken.finish();
- }
-
- new OpenFileHyperlinkInfo(myProject, currentVirtualFile, myLineNumber - 1).navigate(project);
- }
-
- @Nullable
- @Override
- public OpenFileDescriptor getDescriptor() {
- return new OpenFileDescriptor(myProject, myVirtualFile, myLineNumber - 1, 0);
- }
- }
}
diff --git a/java/remote-servers/impl/remote-servers-java-impl.iml b/java/remote-servers/impl/remote-servers-java-impl.iml
index c98f909fbfd8..b0228d7f4075 100644
--- a/java/remote-servers/impl/remote-servers-java-impl.iml
+++ b/java/remote-servers/impl/remote-servers-java-impl.iml
@@ -12,7 +12,7 @@
-
+
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/util/ArtifactDeploymentSourceHandlerBase.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/util/ArtifactDeploymentSourceHandlerBase.java
new file mode 100644
index 000000000000..3b50c7752e3d
--- /dev/null
+++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/util/ArtifactDeploymentSourceHandlerBase.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.impl.util;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.remoteServer.agent.util.CloudGitApplication;
+import com.intellij.remoteServer.configuration.deployment.ArtifactDeploymentSource;
+import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
+import com.intellij.remoteServer.util.DeploymentSourceHandler;
+import com.intellij.remoteServer.util.ServerRuntimeException;
+
+import java.io.File;
+
+/**
+ * @author michael.golubev
+ */
+public abstract class ArtifactDeploymentSourceHandlerBase implements DeploymentSourceHandler {
+
+ private static final Logger LOG = Logger.getInstance("#" + ArtifactDeploymentSourceHandlerBase.class.getName());
+
+ private Artifact myArtifact;
+ private File myRepositoryRootFile;
+
+ protected File getArtifactFile() {
+ return new File(myArtifact.getOutputFilePath());
+ }
+
+ @Override
+ public File getRepositoryRootFile() {
+ return myRepositoryRootFile;
+ }
+
+ @Override
+ public boolean init(DeploymentSource deploymentSource) throws ServerRuntimeException {
+ if (!(deploymentSource instanceof ArtifactDeploymentSource)) {
+ return false;
+ }
+ ArtifactDeploymentSource artifactDeploymentSource = (ArtifactDeploymentSource)deploymentSource;
+ Artifact artifact = artifactDeploymentSource.getArtifact();
+ if (artifact == null) {
+ throw new ServerRuntimeException("Artifact not found " + artifactDeploymentSource.getArtifactPointer().getArtifactName());
+ }
+
+ String outputPath = artifact.getOutputPath();
+ LOG.assertTrue(outputPath != null, "Artifact output path not found");
+ myRepositoryRootFile = new File(outputPath, "/deploy");
+ if (!myRepositoryRootFile.exists()) {
+ if (!myRepositoryRootFile.mkdir()) {
+ throw new ServerRuntimeException("Unable to create deploy folder");
+ }
+ }
+ myArtifact = artifact;
+ return true;
+ }
+}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootIndexImpl.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootIndexImpl.java
index 078e1fbe331b..0ec56d99662f 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootIndexImpl.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootIndexImpl.java
@@ -19,7 +19,6 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.util.SmartList;
-import com.intellij.util.containers.ConcurrentHashMap;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,6 +36,7 @@ import org.jetbrains.jps.service.JpsServiceManager;
import java.io.File;
import java.io.FileFilter;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
@@ -55,7 +55,7 @@ public class BuildRootIndexImpl implements BuildRootIndex {
myIgnoredFileIndex = ignoredFileIndex;
myRootsByTarget = new HashMap, List extends BuildRootDescriptor>>();
myRootToDescriptors = new THashMap>(FileUtil.FILE_HASHING_STRATEGY);
- myFileFilters = new ConcurrentHashMap();
+ myFileFilters = new ConcurrentHashMap(16, 0.75f, 1);
final Iterable rootsProviders = JpsServiceManager.getInstance().getExtensions(AdditionalRootsProviderService.class);
for (BuildTargetType> targetType : TargetTypeRegistry.getInstance().getTargetTypes()) {
for (BuildTarget> target : targetIndex.getAllTargets(targetType)) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
index fdc84abf785f..154d5daa6215 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
@@ -321,15 +321,17 @@ public class ClassRepr extends Proto {
}
public String getPackageName() {
- return getPackageName(name);
+ final String strValue = myContext.getValue(name);
+ return strValue != null? getPackageName(strValue) : null;
}
- public String getPackageName(final int s) {
- return getPackageName(myContext.getValue(s));
+ public String getShortName() {
+ final String strValue = myContext.getValue(name);
+ return strValue != null? getShortName(strValue) : null;
}
@NotNull
- public static String getPackageName(final String raw) {
+ public static String getPackageName(@NotNull final String raw) {
final int index = raw.lastIndexOf('/');
if (index == -1) {
@@ -339,6 +341,17 @@ public class ClassRepr extends Proto {
return raw.substring(0, index);
}
+ @NotNull
+ public static String getShortName(@NotNull final String fqName) {
+ final int index = fqName.lastIndexOf('/');
+
+ if (index == -1) {
+ return fqName;
+ }
+
+ return fqName.substring(index + 1);
+ }
+
@Nullable
public FieldRepr findField(final int name) {
for (FieldRepr f : myFields) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
index 29c92aa7a916..8d178ad46990 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
@@ -45,6 +45,7 @@ public class Mappings {
private final static String CLASS_TO_SUBCLASSES = "classToSubclasses.tab";
private final static String CLASS_TO_CLASS = "classToClass.tab";
+ private final static String SHORT_NAMES = "shortNames.tab";
private final static String SOURCE_TO_CLASS = "sourceToClass.tab";
private final static String CLASS_TO_SOURCE = "classToSource.tab";
private static final IntInlineKeyDescriptor INT_KEY_DESCRIPTOR = new IntInlineKeyDescriptor();
@@ -65,6 +66,7 @@ public class Mappings {
private final TIntHashSet myChangedClasses;
private final THashSet myChangedFiles;
private final Set myDeletedClasses;
+ private final Set myAddedClasses;
private final Object myLock;
private final File myRootDir;
@@ -83,6 +85,10 @@ public class Mappings {
private IntIntMultiMaplet myClassToClassDependency;
private ObjectObjectMultiMaplet mySourceFileToClasses;
private IntObjectMaplet myClassToSourceFile;
+ /**
+ * [short className] -> list of FQ names
+ */
+ private IntIntMultiMaplet myShortClassNameIndex;
private IntIntTransientMultiMaplet myRemovedSuperClasses;
private IntIntTransientMultiMaplet myAddedSuperClasses;
@@ -96,6 +102,7 @@ public class Mappings {
myChangedClasses = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
myChangedFiles = new THashSet(FileUtil.FILE_HASHING_STRATEGY);
myDeletedClasses = new HashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
+ myAddedClasses = new HashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
myDeltaIsTransient = base.myDeltaIsTransient;
myRootDir = new File(FileUtil.toSystemIndependentName(base.myRootDir.getAbsolutePath()) + File.separatorChar + "myDelta");
myContext = base.myContext;
@@ -112,6 +119,7 @@ public class Mappings {
myChangedClasses = null;
myChangedFiles = null;
myDeletedClasses = null;
+ myAddedClasses = null;
myDeltaIsTransient = transientDelta;
myRootDir = rootDir;
createImplementation();
@@ -132,6 +140,7 @@ public class Mappings {
if (myIsDelta && myDeltaIsTransient) {
myClassToSubclasses = new IntIntTransientMultiMaplet();
myClassToClassDependency = new IntIntTransientMultiMaplet();
+ myShortClassNameIndex = null;
mySourceFileToClasses = new ObjectObjectTransientMultiMaplet(FileUtil.FILE_HASHING_STRATEGY, ourClassSetConstructor);
myClassToSourceFile = new IntObjectTransientMaplet();
}
@@ -141,6 +150,7 @@ public class Mappings {
}
myClassToSubclasses = new IntIntPersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_SUBCLASSES), INT_KEY_DESCRIPTOR);
myClassToClassDependency = new IntIntPersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_CLASS), INT_KEY_DESCRIPTOR);
+ myShortClassNameIndex = myIsDelta? null : new IntIntPersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, SHORT_NAMES), INT_KEY_DESCRIPTOR);
mySourceFileToClasses = new ObjectObjectPersistentMultiMaplet(
DependencyContext.getTableFile(myRootDir, SOURCE_TO_CLASS), new FileKeyDescriptor(), ClassRepr.externalizer(myContext),
ourClassSetConstructor
@@ -1788,36 +1798,51 @@ public class Mappings {
for (final ClassRepr c : addedClasses) {
debug("Class name: ", c.name);
- myDelta.addChangedClass(c.name);
+ myDelta.addAddedClass(c);
for (final int sup : c.getSupers()) {
myDelta.registerAddedSuperClass(c.name, sup);
}
- if (!myEasyMode) {
- final TIntHashSet depClasses = myClassToClassDependency.get(c.name);
-
- if (depClasses != null) {
- depClasses.forEach(new TIntProcedure() {
- @Override
- public boolean execute(int depClass) {
- final File fName = myClassToSourceFile.get(depClass);
- if (fName != null) {
- if (myFilter == null || myFilter.accept(fName)) {
- debug("Adding dependent file ", fName);
- myAffectedFiles.add(fName);
- }
- }
- return true;
- }
- });
+ if (!myEasyMode && !c.isAnonymous() && !c.isLocal()) {
+ final TIntHashSet toAffect = new TIntHashSet();
+ toAffect.add(c.name);
+ final TIntHashSet classes = myShortClassNameIndex.get(myContext.get(c.getShortName()));
+ if (classes != null) {
+ // affecting dependencies on all other classes with the same short name
+ toAffect.addAll(classes.toArray());
}
+ toAffect.forEach(new TIntProcedure() {
+ public boolean execute(int qName) {
+ final TIntHashSet depClasses = myClassToClassDependency.get(qName);
+ if (depClasses != null) {
+ affectCorrespondingSourceFiles(depClasses);
+ }
+ return true;
+ }
+ });
}
}
debug("End of added classes processing.");
}
+ private void affectCorrespondingSourceFiles(TIntHashSet toAffect) {
+ toAffect.forEach(new TIntProcedure() {
+ @Override
+ public boolean execute(int depClass) {
+ final File fName = myClassToSourceFile.get(depClass);
+ if (fName != null) {
+ if (myFilter == null || myFilter.accept(fName)) {
+ debug("Adding dependent file ", fName);
+ myAffectedFiles.add(fName);
+ }
+ }
+ return true;
+ }
+ });
+ }
+
private void calculateAffectedFiles(final DiffState state) {
debug("Checking dependent classes:");
@@ -1979,10 +2004,7 @@ public class Mappings {
}
}
- private void cleanupRemovedClass(final Mappings delta,
- @NotNull final ClassRepr cr,
- final Set usages,
- final IntIntMultiMaplet dependenciesTrashBin) {
+ private void cleanupRemovedClass(final Mappings delta, @NotNull final ClassRepr cr, final Set usages, final IntIntMultiMaplet dependenciesTrashBin) {
final int className = cr.name;
for (final int superSomething : cr.getSupers()) {
@@ -1994,6 +2016,9 @@ public class Mappings {
myClassToClassDependency.remove(className);
myClassToSubclasses.remove(className);
myClassToSourceFile.remove(className);
+ if (!cr.isLocal() && !cr.isAnonymous()) {
+ myShortClassNameIndex.removeFrom(myContext.get(cr.getShortName()), className);
+ }
}
public void integrate(final Mappings delta) {
@@ -2025,6 +2050,11 @@ public class Mappings {
for (final ClassRepr repr : delta.getDeletedClasses()) {
cleanupRemovedClass(delta, repr, repr.getUsages(), dependenciesTrashBin);
}
+ for (ClassRepr repr : delta.getAddedClasses()) {
+ if (!repr.isAnonymous() && !repr.isLocal()) {
+ myShortClassNameIndex.put(myContext.get(repr.getShortName()), repr.name);
+ }
+ }
final TIntHashSet superClasses = new TIntHashSet();
final IntIntTransientMultiMaplet addedSuperClasses = delta.getAddedSuperClasses();
@@ -2090,6 +2120,16 @@ public class Mappings {
myClassToSubclasses.putAll(delta.myClassToSubclasses);
myClassToSourceFile.putAll(delta.myClassToSourceFile);
mySourceFileToClasses.replaceAll(delta.mySourceFileToClasses);
+ delta.mySourceFileToClasses.forEachEntry(new TObjectObjectProcedure>() {
+ public boolean execute(File src, Collection classes) {
+ for (ClassRepr repr : classes) {
+ if (!repr.isAnonymous() && !repr.isLocal()) {
+ myShortClassNameIndex.put(myContext.get(repr.getShortName()), repr.name);
+ }
+ }
+ return true;
+ }
+ });
}
// updating classToClass dependencies
@@ -2224,6 +2264,7 @@ public class Mappings {
myClassToSourceFile.close();
if (!myIsDelta) {
+ myShortClassNameIndex.close();
// only close if you own the context
final DependencyContext context = myContext;
if (context != null) {
@@ -2247,6 +2288,7 @@ public class Mappings {
myClassToSourceFile.flush(memoryCachesOnly);
if (!myIsDelta) {
+ myShortClassNameIndex.flush(memoryCachesOnly);
// flush if you own the context
final DependencyContext context = myContext;
if (context != null) {
@@ -2312,6 +2354,14 @@ public class Mappings {
addChangedClass(cr.name);
}
+ private void addAddedClass(final ClassRepr cr) {
+ assert (myAddedClasses != null);
+
+ myAddedClasses.add(cr);
+
+ addChangedClass(cr.name);
+ }
+
private void addChangedClass(final int it) {
assert (myChangedClasses != null && myChangedFiles != null);
myChangedClasses.add(it);
@@ -2328,6 +2378,11 @@ public class Mappings {
return myDeletedClasses == null ? Collections.emptySet() : Collections.unmodifiableSet(myDeletedClasses);
}
+ @NotNull
+ private Set getAddedClasses() {
+ return myAddedClasses == null ? Collections.emptySet() : Collections.unmodifiableSet(myAddedClasses);
+ }
+
private TIntHashSet getChangedClasses() {
return myChangedClasses;
}
@@ -2390,6 +2445,7 @@ public class Mappings {
myClassToClassDependency,
mySourceFileToClasses,
myClassToSourceFile,
+ myShortClassNameIndex
};
final String[] info = {
@@ -2397,6 +2453,7 @@ public class Mappings {
"ClassToClassDependency",
"SourceFileToClasses",
"ClassToSourceFile",
+ "ShortClassNameIndex"
};
for (int i = 0; i < data.length; i++) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/client/ProtobufClientMessageHandler.java b/jps/jps-builders/src/org/jetbrains/jps/client/ProtobufClientMessageHandler.java
index 81acebb74026..821a2ffea980 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/client/ProtobufClientMessageHandler.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/client/ProtobufClientMessageHandler.java
@@ -34,7 +34,7 @@ import java.util.concurrent.Executor;
*/
@ChannelHandler.Sharable
final class ProtobufClientMessageHandler extends SimpleChannelInboundHandler {
- private final ConcurrentHashMap> myHandlers = new ConcurrentHashMap>();
+ private final ConcurrentHashMap> myHandlers = new ConcurrentHashMap>(16, 0.75f, 1);
@NotNull
private final UUIDGetter myUuidGetter;
private final SimpleProtobufClient myClient;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
index 24cbd84aa914..8bc64536a451 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
@@ -88,6 +88,7 @@ public class IncProjectBuilder {
maxThreads = Math.max(2, Integer.parseInt(System.getProperty(GlobalOptions.COMPILE_PARALLEL_MAX_THREADS_OPTION, Integer.toString(maxThreads))));
}
catch (NumberFormatException ignored) {
+ maxThreads = Math.max(2, maxThreads);
}
MAX_BUILDER_THREADS = maxThreads;
}
@@ -632,9 +633,7 @@ public class IncProjectBuilder {
}
private class BuildParallelizer {
- private final BoundedTaskExecutor myParallelBuildExecutor =
- new BoundedTaskExecutor(SharedThreadPool.getInstance(),
- Math.min(MAX_BUILDER_THREADS, Math.max(2, Runtime.getRuntime().availableProcessors())));
+ private final BoundedTaskExecutor myParallelBuildExecutor = new BoundedTaskExecutor(SharedThreadPool.getInstance(), MAX_BUILDER_THREADS);
private final CompileContext myContext;
private final AtomicReference myException = new AtomicReference();
private final Object myQueueLock = new Object();
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
index 1a0ce3bdc1d6..791e2e291f73 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
@@ -41,7 +41,7 @@ import java.util.concurrent.ConcurrentMap;
* Date: 10/7/11
*/
public class BuildDataManager implements StorageOwner {
- private static final int VERSION = 20;
+ private static final int VERSION = 21;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_FORM_STORAGE = "src-form";
private static final String MAPPINGS_STORAGE = "mappings";
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetTypeState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetTypeState.java
index e9e2291a166a..d7053cbb4cd4 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetTypeState.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetTypeState.java
@@ -17,7 +17,6 @@ package org.jetbrains.jps.incremental.storage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.io.IOUtil;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetLoader;
@@ -26,6 +25,7 @@ import org.jetbrains.jps.builders.BuildTargetType;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
@@ -43,7 +43,7 @@ public class BuildTargetTypeState {
myTargetType = targetType;
myTargetsState = state;
myTargetsFile = new File(state.getDataPaths().getTargetTypeDataRoot(targetType), "targets.dat");
- myConfigurations = new ConcurrentHashMap, BuildTargetConfiguration>();
+ myConfigurations = new ConcurrentHashMap, BuildTargetConfiguration>(16, 0.75f, 1);
myTargetIds = new HashMap, Integer>();
load();
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetsState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetsState.java
index b4294293dc86..ad0f85d6dfdf 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetsState.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetsState.java
@@ -17,7 +17,6 @@ package org.jetbrains.jps.incremental.storage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetType;
@@ -27,6 +26,7 @@ import org.jetbrains.jps.incremental.TargetTypeRegistry;
import org.jetbrains.jps.model.JpsModel;
import java.io.*;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -37,7 +37,7 @@ public class BuildTargetsState {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildTargetsState");
private final BuildDataPaths myDataPaths;
private AtomicInteger myMaxTargetId = new AtomicInteger(0);
- private ConcurrentMap, BuildTargetTypeState> myTypeStates = new ConcurrentHashMap, BuildTargetTypeState>();
+ private ConcurrentMap, BuildTargetTypeState> myTypeStates = new ConcurrentHashMap, BuildTargetTypeState>(16, 0.75f, 1);
private JpsModel myModel;
private final BuildRootIndexImpl myBuildRootIndex;
@@ -99,9 +99,11 @@ public class BuildTargetsState {
private BuildTargetTypeState getTypeState(BuildTargetType> type) {
BuildTargetTypeState state = myTypeStates.get(type);
if (state == null) {
- state = new BuildTargetTypeState(type, this);
- myTypeStates.putIfAbsent(type, state);
- state = myTypeStates.get(type);
+ final BuildTargetTypeState newState = new BuildTargetTypeState(type, this);
+ state = myTypeStates.putIfAbsent(type, newState);
+ if (state == null) {
+ state = newState;
+ }
}
return state;
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java
index c63614e17895..c848aef58a75 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java
@@ -542,6 +542,7 @@ class OptimizedFileManager extends DefaultFileManager {
myDirectoryCache.clear();
myByteBufferCache.clear();
myIsFile.clear();
+ Paths.clearPathExistanceCache();
}
}
}
diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java b/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java
index 8f97b867cdbd..7adfbea6124f 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java
+++ b/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java
@@ -113,4 +113,9 @@ public class CommonTest extends IncrementalTestCase {
public void testAddDuplicateClass() throws Exception {
doTest();
}
+
+ public void testAddClassHidingImportedClass() throws Exception {
+ doTest();
+ }
+
}
diff --git a/jps/lib/optimizedFileManager.jar b/jps/lib/optimizedFileManager.jar
index 55b4e61617f5..9900a870a99b 100644
Binary files a/jps/lib/optimizedFileManager.jar and b/jps/lib/optimizedFileManager.jar differ
diff --git a/jps/model-impl/src/org/jetbrains/jps/service/impl/JpsServiceManagerImpl.java b/jps/model-impl/src/org/jetbrains/jps/service/impl/JpsServiceManagerImpl.java
index 750469071360..3a33747b85da 100644
--- a/jps/model-impl/src/org/jetbrains/jps/service/impl/JpsServiceManagerImpl.java
+++ b/jps/model-impl/src/org/jetbrains/jps/service/impl/JpsServiceManagerImpl.java
@@ -24,8 +24,8 @@ import java.util.concurrent.ConcurrentHashMap;
* @author nik
*/
public class JpsServiceManagerImpl extends JpsServiceManager {
- private final ConcurrentHashMap myServices = new ConcurrentHashMap();
- private final ConcurrentHashMap> myExtensions = new ConcurrentHashMap>();
+ private final ConcurrentHashMap myServices = new ConcurrentHashMap(16, 0.75f, 1);
+ private final ConcurrentHashMap> myExtensions = new ConcurrentHashMap>(16, 0.75f, 1);
@Override
public T getService(Class serviceClass) {
@@ -36,14 +36,16 @@ public class JpsServiceManagerImpl extends JpsServiceManager {
if (!iterator.hasNext()) {
throw new ServiceConfigurationError("Implementation for " + serviceClass + " not found");
}
- service = iterator.next();
+ final T loadedService = iterator.next();
if (iterator.hasNext()) {
throw new ServiceConfigurationError(
- "More than one implementation for " + serviceClass + " found: " + service.getClass() + " and " + iterator.next().getClass());
+ "More than one implementation for " + serviceClass + " found: " + loadedService.getClass() + " and " + iterator.next().getClass());
}
- myServices.putIfAbsent(serviceClass, service);
//noinspection unchecked
- service = (T)myServices.get(serviceClass);
+ service = (T)myServices.putIfAbsent(serviceClass, loadedService);
+ if (service == null) {
+ service = loadedService;
+ }
}
return service;
}
@@ -53,12 +55,14 @@ public class JpsServiceManagerImpl extends JpsServiceManager {
List> cached = myExtensions.get(extensionClass);
if (cached == null) {
final ServiceLoader loader = ServiceLoader.load(extensionClass, extensionClass.getClassLoader());
- List extensions = new ArrayList();
+ final List extensions = new ArrayList();
for (T t : loader) {
extensions.add(t);
}
- myExtensions.putIfAbsent(extensionClass, extensions);
- cached = myExtensions.get(extensionClass);
+ cached = myExtensions.putIfAbsent(extensionClass, extensions);
+ if (cached == null) {
+ cached = extensions;
+ }
}
//noinspection unchecked
return (List)cached;
diff --git a/lib/pty4j-0.3.jar b/lib/pty4j-0.3.jar
index 94b515636331..8ffcc9c0d67b 100644
Binary files a/lib/pty4j-0.3.jar and b/lib/pty4j-0.3.jar differ
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
index a017575a3f27..f8d215ceee24 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
@@ -145,7 +145,9 @@ public class ToolsImpl implements Tools {
scopeElement.setAttribute(LEVEL_ATTRIBUTE, state.getLevel().toString());
scopeElement.setAttribute(ENABLED_ATTRIBUTE, Boolean.toString(state.isEnabled()));
InspectionToolWrapper toolWrapper = state.getTool();
- toolWrapper.getTool().writeSettings(scopeElement);
+ if (toolWrapper.isInitialized()) {
+ toolWrapper.getTool().writeSettings(scopeElement);
+ }
inspectionElement.addContent(scopeElement);
}
}
@@ -153,7 +155,9 @@ public class ToolsImpl implements Tools {
inspectionElement.setAttribute(LEVEL_ATTRIBUTE, getLevel().toString());
inspectionElement.setAttribute(ENABLED_BY_DEFAULT_ATTRIBUTE, Boolean.toString(myDefaultState.isEnabled()));
InspectionToolWrapper toolWrapper = myDefaultState.getTool();
- toolWrapper.getTool().writeSettings(inspectionElement);
+ if (toolWrapper.isInitialized()) {
+ toolWrapper.getTool().writeSettings(inspectionElement);
+ }
}
void readExternal(@NotNull Element toolElement, @NotNull InspectionProfile profile) throws InvalidDataException {
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java
index 1452ed0d53a4..695e948cce32 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java
@@ -106,7 +106,9 @@ public class BlockSupportImpl extends BlockSupport {
if (baseLanguage.isKindOf(reparseable.getLanguage())) {
final int start = textRange.getStartOffset();
final int end = start + textRange.getLength() + lengthShift;
- assertFileLength(file, newFileText, node, elementType, start, end);
+ if (!assertFileLength(file, newFileText, node, elementType, start, end)) {
+ break;
+ }
CharSequence newTextStr = newFileText.subSequence(start, end);
@@ -134,11 +136,13 @@ public class BlockSupportImpl extends BlockSupport {
return makeFullParse(node, newFileText, textLength, fileImpl, indicator);
}
- private static void assertFileLength(PsiFile file, CharSequence newFileText, ASTNode node, IElementType elementType, int start, int end) {
- if (end > newFileText.length() && ApplicationManager.getApplication().isInternal()) {
+ private static boolean assertFileLength(PsiFile file, CharSequence newFileText, ASTNode node, IElementType elementType, int start, int end) {
+ if ((end > newFileText.length() || start > end) && ApplicationManager.getApplication().isInternal()) {
String newTextBefore = newFileText.subSequence(0, start).toString();
String oldTextBefore = file.getText().subSequence(0, start).toString();
String message = "IOOBE: type=" + elementType +
+ "; start=" + start +
+ "; end=" + end +
"; oldText=" + node.getText() +
"; newText=" + newFileText.subSequence(start, newFileText.length()) +
"; length=" + node.getTextLength();
@@ -148,8 +152,10 @@ public class BlockSupportImpl extends BlockSupport {
message += "; oldTextBefore=" + oldTextBefore +
"; newTextBefore=" + newTextBefore;
}
- throw new AssertionError(message);
+ LOG.error(message);
+ return false;
}
+ return true;
}
@NotNull
diff --git a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties
index 17078c097875..a8660af76cb0 100644
--- a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties
+++ b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties
@@ -11,6 +11,7 @@ setting.type.location.explicit.correct={0} location is defined
setting.type.location.explicit.incorrect={0} location is incorrect
settings.label.select.project={0} project:
settings.label.use.auto.import=Use auto-import
+settings.label.create.empty.content.root.directories=Create directories for empty content roots automatically
settings.title.linked.projects=Linked {0} projects
settings.title.project.settings=Project-level settings
settings.title.system.settings=Global {0} settings
@@ -59,6 +60,8 @@ run.configuration.settings.label.project={0} project:
run.configuration.settings.label.tasks=Tasks:
run.configuration.settings.label.vmoptions=VM options:
run.configuration.settings.caption.vmoptions=VM options:
-run.text.starting.multiple.task=Executing external tasks ''{0}''...\n
-run.text.starting.single.task=Executing external task ''{0}''...\n
+run.text.starting.multiple.task={0}: Executing external tasks ''{1}''...\n
+run.text.starting.single.task={0}: Executing external task ''{1}''...\n
+run.text.ended.multiple.task={0}: External tasks execution finished ''{1}''.\n
+run.text.ended.single.task={0}: External task execution finished ''{1}''.\n
run.error.undefined.task=No task to execute is specified
\ No newline at end of file
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractDependencyData.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractDependencyData.java
index a765ef5a8fd0..fb82dfe4d2cc 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractDependencyData.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/AbstractDependencyData.java
@@ -77,6 +77,7 @@ public abstract class AbstractDependencyData that = (AbstractDependencyData>)o;
- return myOwnerModule.equals(that.myOwnerModule) && myTarget.equals(that.myTarget);
+ return myScope.equals(that.myScope) && myOwnerModule.equals(that.myOwnerModule) && myTarget.equals(that.myTarget);
}
@Override
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalProjectSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalProjectSettings.java
index c7a6ecbd5443..c3e68dea3942 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalProjectSettings.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/ExternalProjectSettings.java
@@ -28,6 +28,7 @@ public abstract class ExternalProjectSettings implements Comparable 1) {
- greeting = ExternalSystemBundle.message("run.text.starting.multiple.task", StringUtil.join(mySettings.getTaskNames(), " "));
+ greeting = ExternalSystemBundle.message("run.text.starting.multiple.task", startDateTime, StringUtil.join(mySettings.getTaskNames(), " "));
}
else {
- greeting = ExternalSystemBundle.message("run.text.starting.single.task", StringUtil.join(mySettings.getTaskNames(), " "));
+ greeting = ExternalSystemBundle.message("run.text.starting.single.task", startDateTime, StringUtil.join(mySettings.getTaskNames(), " "));
}
processHandler.notifyTextAvailable(greeting, ProcessOutputTypes.SYSTEM);
task.execute(new ExternalSystemTaskNotificationListenerAdapter() {
@@ -189,6 +191,15 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase {
@Override
public void onEnd(@NotNull ExternalSystemTaskId id) {
+ final String endDateTime = DateFormatUtil.formatTimeWithSeconds(System.currentTimeMillis());
+ final String farewell;
+ if (mySettings.getTaskNames().size() > 1) {
+ farewell = ExternalSystemBundle.message("run.text.ended.multiple.task", endDateTime, StringUtil.join(mySettings.getTaskNames(), " "));
+ }
+ else {
+ farewell = ExternalSystemBundle.message("run.text.ended.single.task", endDateTime, StringUtil.join(mySettings.getTaskNames(), " "));
+ }
+ processHandler.notifyTextAvailable(farewell, ProcessOutputTypes.SYSTEM);
processHandler.notifyProcessTerminated(0);
}
});
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java
index ad37b00fbb2b..e0c52255fb58 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java
@@ -4,10 +4,13 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.Key;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.project.ContentRootData;
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.service.project.ProjectStructureHelper;
+import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
+import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
@@ -95,30 +98,45 @@ public class ContentRootDataService implements ProjectDataService data : datas) {
final ContentRootData contentRoot = data.getData();
+
final ContentEntry contentEntry = findOrCreateContentRoot(model, contentRoot.getRootPath());
contentEntry.clearExcludeFolders();
contentEntry.clearSourceFolders();
LOG.info(String.format("Importing content root '%s' for module '%s'", contentRoot.getRootPath(), module.getName()));
for (String path : contentRoot.getPaths(ExternalSystemSourceType.SOURCE)) {
- createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.SOURCE, false);
+ createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.SOURCE, false, createEmptyContentRootDirectories);
}
for (String path : contentRoot.getPaths(ExternalSystemSourceType.TEST)) {
- createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, false);
+ createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, false, createEmptyContentRootDirectories);
}
for (String path : contentRoot.getPaths(ExternalSystemSourceType.RESOURCE)) {
- createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaResourceRootType.RESOURCE, false);
+ createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaResourceRootType.RESOURCE, false, createEmptyContentRootDirectories);
}
for (String path : contentRoot.getPaths(ExternalSystemSourceType.TEST_RESOURCE)) {
- createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaResourceRootType.TEST_RESOURCE, false);
+ createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaResourceRootType.TEST_RESOURCE, false, createEmptyContentRootDirectories);
}
for (String path : contentRoot.getPaths(ExternalSystemSourceType.SOURCE_GENERATED)) {
- createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.SOURCE, true);
+ createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.SOURCE, true, createEmptyContentRootDirectories);
}
for (String path : contentRoot.getPaths(ExternalSystemSourceType.TEST_GENERATED)) {
- createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, true);
+ createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, true, createEmptyContentRootDirectories);
}
for (String path : contentRoot.getPaths(ExternalSystemSourceType.EXCLUDED)) {
createExcludedRootIfAbsent(contentEntry, path, module.getName());
@@ -154,7 +172,7 @@ public class ContentRootDataService implements ProjectDataService folders = entry.getSourceFolders(sourceRootType);
for (SourceFolder folder : folders) {
VirtualFile file = folder.getFile();
@@ -173,11 +191,13 @@ public class ContentRootDataService implements ProjectDataService/* library paths */, LibraryDependencyData> moduleLibrariesToImport = ContainerUtilRt.newHashMap();
- Map projectLibrariesToImport = ContainerUtilRt.newHashMap();
+ Map projectLibrariesToImport = ContainerUtilRt.newHashMap();
Set toImport = ContainerUtilRt.newLinkedHashSet();
boolean hasUnresolved = false;
@@ -132,7 +132,7 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService<
}
break;
case PROJECT:
- projectLibrariesToImport.put(ExternalSystemApiUtil.getLibraryName(libraryData), dependencyData);
+ projectLibrariesToImport.put(ExternalSystemApiUtil.getLibraryName(libraryData) + dependencyData.getScope().name(), dependencyData);
toImport.add(dependencyData);
}
}
@@ -224,8 +224,8 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService<
else if (entry instanceof LibraryOrderEntry) {
final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)entry;
final String libraryName = libraryOrderEntry.getLibraryName();
- final LibraryDependencyData existing = projectLibrariesToImport.remove(libraryName);
- if (existing != null && libraryOrderEntry.getScope() == existing.getScope()) {
+ final LibraryDependencyData existing = projectLibrariesToImport.remove(libraryName + libraryOrderEntry.getScope().name());
+ if (existing != null) {
toImport.remove(existing);
}
else if (!hasUnresolvedLibraries) {
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java
index a7d09ebc58d9..c44eb9123a42 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java
@@ -37,6 +37,7 @@ public abstract class AbstractExternalProjectSettingsControl] myPathsToProcessCollapseState = ContainerUtilRt.newHashSet();
-
+
@NotNull private final Map myExpandedStateHolder;
private boolean mySuppressCollapseTracking;
@@ -86,7 +88,7 @@ public class ExternalSystemTasksTree extends Tree implements Producer map = ContainerUtil.newHashMap();
+ for (TreePath selectionPath : selectionPaths) {
+ Object component = selectionPath.getLastPathComponent();
+ if (!(component instanceof ExternalSystemNode)) {
+ continue;
+ }
+
+ Object element = ((ExternalSystemNode)component).getDescriptor().getElement();
+ if (element instanceof ExternalTaskExecutionInfo) {
+ ExternalTaskExecutionInfo taskExecutionInfo = (ExternalTaskExecutionInfo)element;
+ ExternalSystemTaskExecutionSettings executionSettings = taskExecutionInfo.getSettings();
+ String key = executionSettings.getExternalSystemIdString() + executionSettings.getExternalProjectPath() + executionSettings.getVmOptions();
+ ExternalTaskExecutionInfo executionInfo = map.get(key);
+ if(executionInfo == null) {
+ ExternalSystemTaskExecutionSettings taskExecutionSettings = new ExternalSystemTaskExecutionSettings();
+ taskExecutionSettings.setExternalProjectPath(executionSettings.getExternalProjectPath());
+ taskExecutionSettings.setExternalSystemIdString(executionSettings.getExternalSystemIdString());
+ taskExecutionSettings.setVmOptions(executionSettings.getVmOptions());
+ executionInfo = new ExternalTaskExecutionInfo(taskExecutionSettings, taskExecutionInfo.getExecutorId());
+ map.put(key, executionInfo);
+ }
+ executionInfo.getSettings().getTaskNames().addAll(executionSettings.getTaskNames());
+ executionInfo.getSettings().getTaskDescriptions().addAll(executionSettings.getTaskDescriptions());
+ }
+ }
+
+ // Disable tasks execution if it comes from different projects
+ if(map.values().size() > 1) return null;
+ return map.values().iterator().next();
}
}
diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/service/project/ExternalProjectServiceTest.groovy b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/service/project/ExternalProjectServiceTest.groovy
index b763920caf7c..cdbd81190895 100644
--- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/service/project/ExternalProjectServiceTest.groovy
+++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/service/project/ExternalProjectServiceTest.groovy
@@ -54,7 +54,7 @@ public class ExternalProjectServiceTest extends AbstractExternalSystemTest {
dependencies[name]++
}
}
- ExternalSystemTestUtil.assertMapsEqual(['lib1': 1, 'lib2': 1], dependencies)
+ ExternalSystemTestUtil.assertMapsEqual(['Test_external_system_id: lib1': 1, 'Test_external_system_id: lib2': 1], dependencies)
}
void 'test changes in a project layout (content roots) could be detected on Refresh'() {
diff --git a/platform/lang-api/src/com/intellij/execution/filters/HyperlinkInfoFactory.java b/platform/lang-api/src/com/intellij/execution/filters/HyperlinkInfoFactory.java
new file mode 100644
index 000000000000..42beb03faeff
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/execution/filters/HyperlinkInfoFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.execution.filters;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class HyperlinkInfoFactory {
+ @NotNull
+ public static HyperlinkInfoFactory getInstance() {
+ return ServiceManager.getService(HyperlinkInfoFactory.class);
+ }
+
+ @NotNull
+ public abstract HyperlinkInfo createMultipleFilesHyperlinkInfo(@NotNull List files,
+ int line, @NotNull Project project);
+}
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesUIConfiguration.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesUIConfiguration.java
index 75784fc1e525..7780f7ae9c41 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesUIConfiguration.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesUIConfiguration.java
@@ -75,7 +75,10 @@ public class CodeStyleSchemesUIConfiguration implements PersistentStateComponent
public static void setRecentImportFile(@NotNull VirtualFile recentFile) {
CodeStyleSchemesUIConfiguration configuration = getInstance();
if (configuration != null) {
- configuration.RECENT_IMPORT_FILE_LOCATION = recentFile.getUrl();
+ URL url = VfsUtil.convertToURL(recentFile.getUrl());
+ if (url != null) {
+ configuration.RECENT_IMPORT_FILE_LOCATION = url.toString();
+ }
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
index c5c5d6fe1737..c4ff55b2972a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
@@ -45,8 +45,8 @@ import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
@@ -457,7 +457,7 @@ public class CodeCompletionHandlerBase {
public void run() {
AccessToken token = WriteAction.start();
try {
- hostCopy[0] = createFileCopy(hostFile);
+ hostCopy[0] = createFileCopy(hostFile, initContext.getStartOffset(), initContext.getSelectionEndOffset());
}
finally {
token.finish();
@@ -748,7 +748,7 @@ public class CodeCompletionHandlerBase {
}
}
- public static final Key>> FILE_COPY_KEY = Key.create("CompletionFileCopy");
+ private static final Key>> FILE_COPY_KEY = Key.create("CompletionFileCopy");
private static boolean isCopyUpToDate(Document document, @NotNull PsiFile file) {
if (!file.isValid()) {
@@ -760,31 +760,37 @@ public class CodeCompletionHandlerBase {
return current != null && current.getViewProvider().getPsi(file.getLanguage()) == file;
}
- private static PsiFile createFileCopy(PsiFile file) {
+ private static PsiFile createFileCopy(PsiFile file, long caret, long selEnd) {
final VirtualFile virtualFile = file.getVirtualFile();
- if (file.isPhysical() && virtualFile != null && virtualFile.isInLocalFileSystem()
- // must not cache injected file copy, since it does not reflect changes in host document
- && !InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) {
- final SoftReference> reference = file.getUserData(FILE_COPY_KEY);
- if (reference != null) {
- final Pair pair = reference.get();
- if (pair != null && pair.first.getClass().equals(file.getClass()) && isCopyUpToDate(pair.second, pair.first)) {
- final PsiFile copy = pair.first;
- if (copy.getViewProvider().getModificationStamp() > file.getViewProvider().getModificationStamp()) {
- ((PsiModificationTrackerImpl) file.getManager().getModificationTracker()).incCounter();
- }
- final Document document = pair.second;
- assert document != null;
- document.setText(file.getText());
- return copy;
+ boolean mayCacheCopy = file.isPhysical() &&
+ // we don't want to cache code fragment copies even if they appear to be physical
+ virtualFile != null && virtualFile.isInLocalFileSystem();
+ long combinedOffsets = caret + (selEnd << 32);
+ if (mayCacheCopy) {
+ final Trinity cached = SoftReference.dereference(file.getUserData(FILE_COPY_KEY));
+ if (cached != null && cached.first.getClass().equals(file.getClass()) && isCopyUpToDate(cached.second, cached.first)) {
+ final PsiFile copy = cached.first;
+ if (copy.getViewProvider().getModificationStamp() > file.getViewProvider().getModificationStamp() &&
+ cached.third.longValue() != combinedOffsets) {
+ // the copy PSI might have some caches that are not cleared on its modification because there are no events in the copy
+ // so, clear all the caches
+ // hopefully it's a rare situation that the user invokes completion in different parts of the file
+ // without modifying anything physical in between
+ ((PsiModificationTrackerImpl) file.getManager().getModificationTracker()).incCounter();
}
+ final Document document = cached.second;
+ assert document != null;
+ document.setText(file.getText());
+ return copy;
}
}
final PsiFile copy = (PsiFile)file.copy();
- final Document document = copy.getViewProvider().getDocument();
- assert document != null;
- file.putUserData(FILE_COPY_KEY, new SoftReference>(Pair.create(copy, document)));
+ if (mayCacheCopy) {
+ final Document document = copy.getViewProvider().getDocument();
+ assert document != null;
+ file.putUserData(FILE_COPY_KEY, new SoftReference>(Trinity.create(copy, document, combinedOffsets)));
+ }
return copy;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java
index 14be260ed63d..212489bda65f 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java
@@ -91,17 +91,16 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
return FileStatus.NOT_CHANGED;
}
- protected static HighlightSeverity getSeverity(@NotNull RefElement element,
- @NotNull GlobalInspectionContextImpl context,
- @NotNull InspectionToolWrapper thisToolWrapper) {
+ protected HighlightSeverity getSeverity(@NotNull RefElement element) {
final PsiElement psiElement = element.getPointer().getContainingFile();
if (psiElement != null) {
- String shortName = thisToolWrapper.getShortName();
+ final GlobalInspectionContextImpl context = getContext();
+ final String shortName = getSeverityDelegateName();
final Tools tools = context.getTools().get(shortName);
if (tools != null) {
for (ScopeToolState state : tools.getTools()) {
InspectionToolWrapper toolWrapper = state.getTool();
- if (toolWrapper == thisToolWrapper) {
+ if (toolWrapper == getToolWrapper()) {
return context.getCurrentProfile().getErrorLevel(HighlightDisplayKey.find(shortName), psiElement).getSeverity();
}
}
@@ -114,6 +113,10 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
return null;
}
+ protected String getSeverityDelegateName() {
+ return getToolWrapper().getShortName();
+ }
+
protected static String getTextAttributeKey(@NotNull Project project,
@NotNull HighlightSeverity severity,
@NotNull ProblemHighlightType highlightType) {
@@ -203,7 +206,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
}
InspectionNode toolNode = myToolNode;
if (toolNode == null) {
- final HighlightSeverity currentSeverity = getSeverity((RefElement)refElement, context, myToolWrapper);
+ final HighlightSeverity currentSeverity = getSeverity((RefElement)refElement);
view.addTool(myToolWrapper, HighlightDisplayLevel.find(currentSeverity), context.getUIOptions().GROUP_BY_SEVERITY);
}
else if (toolNode.isTooBigForOnlineRefresh()) {
@@ -437,7 +440,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
problemClassElement.addContent(myToolWrapper.getDisplayName());
if (refEntity instanceof RefElement){
final RefElement refElement = (RefElement)refEntity;
- final HighlightSeverity severity = getSeverity(refElement, getContext(), getToolWrapper());
+ final HighlightSeverity severity = getSeverity(refElement);
ProblemHighlightType problemHighlightType = descriptor instanceof ProblemDescriptor
? ((ProblemDescriptor)descriptor).getHighlightType()
: ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
diff --git a/platform/lang-impl/src/com/intellij/execution/filters/impl/HyperlinkInfoFactoryImpl.java b/platform/lang-impl/src/com/intellij/execution/filters/impl/HyperlinkInfoFactoryImpl.java
new file mode 100644
index 000000000000..f8a800094410
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/execution/filters/impl/HyperlinkInfoFactoryImpl.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.execution.filters.impl;
+
+import com.intellij.execution.filters.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class HyperlinkInfoFactoryImpl extends HyperlinkInfoFactory {
+
+ @NotNull
+ @Override
+ public HyperlinkInfo createMultipleFilesHyperlinkInfo(@NotNull List files,
+ int line, @NotNull Project project) {
+ return new MultipleFilesHyperlinkInfo(files, line, project);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/execution/filters/impl/MultipleFilesHyperlinkInfo.java b/platform/lang-impl/src/com/intellij/execution/filters/impl/MultipleFilesHyperlinkInfo.java
new file mode 100644
index 000000000000..36dc51e15be9
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/execution/filters/impl/MultipleFilesHyperlinkInfo.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.execution.filters.impl;
+
+import com.intellij.execution.filters.FileHyperlinkInfo;
+import com.intellij.execution.filters.HyperlinkInfoBase;
+import com.intellij.execution.filters.OpenFileHyperlinkInfo;
+import com.intellij.ide.util.gotoByName.GotoFileCellRenderer;
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.WindowManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.ui.components.JBList;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @author nik
+*/
+class MultipleFilesHyperlinkInfo extends HyperlinkInfoBase implements FileHyperlinkInfo {
+ private final List myVirtualFiles;
+ private final int myLineNumber;
+ private final Project myProject;
+
+ public MultipleFilesHyperlinkInfo(@NotNull List virtualFiles, int lineNumber, @NotNull Project project) {
+ myVirtualFiles = virtualFiles;
+ myLineNumber = lineNumber;
+ myProject = project;
+ }
+
+ @Override
+ public void navigate(@NotNull final Project project, @Nullable RelativePoint hyperlinkLocationPoint) {
+ List currentFiles = new ArrayList();
+
+ AccessToken accessToken = ReadAction.start();
+ try {
+ for (VirtualFile file : myVirtualFiles) {
+ if (!file.isValid()) continue;
+
+ PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
+ if (psiFile != null) {
+ PsiElement navigationElement = psiFile.getNavigationElement(); // Sources may be downloaded.
+ if (navigationElement instanceof PsiFile) {
+ currentFiles.add((PsiFile)navigationElement);
+ continue;
+ }
+ currentFiles.add(psiFile);
+ }
+ }
+ }
+ finally {
+ accessToken.finish();
+ }
+
+ if (currentFiles.isEmpty()) return;
+
+ if (currentFiles.size() == 1) {
+ new OpenFileHyperlinkInfo(myProject, currentFiles.get(0).getVirtualFile(), myLineNumber).navigate(project);
+ }
+ else {
+ final JBList list = new JBList(currentFiles);
+ int width = WindowManager.getInstance().getFrame(project).getSize().width;
+ list.setCellRenderer(new GotoFileCellRenderer(width));
+ JBPopup popup = JBPopupFactory.getInstance().createListPopupBuilder(list)
+ .setTitle("Choose Target File")
+ .setItemChoosenCallback(new Runnable() {
+ @Override
+ public void run() {
+ VirtualFile file = ((PsiFile)list.getSelectedValue()).getVirtualFile();
+ new OpenFileHyperlinkInfo(myProject, file, myLineNumber).navigate(project);
+ }
+ })
+ .createPopup();
+ if (hyperlinkLocationPoint != null) {
+ popup.show(hyperlinkLocationPoint);
+ }
+ else {
+ popup.showInFocusCenter();
+ }
+ }
+ }
+
+ @Nullable
+ @Override
+ public OpenFileDescriptor getDescriptor() {
+ VirtualFile file = getPreferredFile();
+ return file != null ? new OpenFileDescriptor(myProject, file, myLineNumber, 0) : null;
+ }
+
+ @Nullable
+ private VirtualFile getPreferredFile() {
+ return ContainerUtil.getFirstItem(myVirtualFiles);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
index 154d1e8a36f3..2d4a9c356af1 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
@@ -65,6 +65,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.ui.EditorNotificationPanel;
+import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Alarm;
import com.intellij.util.Consumer;
import com.intellij.util.EditorPopupHandler;
@@ -1384,10 +1385,18 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
return EditorHyperlinkSupport.getNextOccurrence(myEditor, hyperlinks.getHyperlinks().keySet(), delta, new Consumer() {
@Override
public void consume(RangeHighlighter next) {
- scrollTo(next.getStartOffset());
+ int offset = next.getStartOffset();
+ scrollTo(offset);
final HyperlinkInfo hyperlinkInfo = hyperlinks.getHyperlinks().get(next);
if (hyperlinkInfo != null) {
- hyperlinkInfo.navigate(myProject);
+ if (hyperlinkInfo instanceof HyperlinkInfoBase) {
+ VisualPosition position = myEditor.offsetToVisualPosition(offset);
+ Point point = myEditor.visualPositionToXY(new VisualPosition(position.getLine() + 1, position.getColumn()));
+ ((HyperlinkInfoBase)hyperlinkInfo).navigate(myProject, new RelativePoint(myEditor.getContentComponent(), point));
+ }
+ else {
+ hyperlinkInfo.navigate(myProject);
+ }
}
}
});
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsNotification.java b/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsNotification.java
index 04f5bdc160a9..abb2b3b01c89 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsNotification.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsNotification.java
@@ -53,7 +53,7 @@ public class RerunTestsNotification {
return;
}
- GotItMessage message = GotItMessage.createMessage("Press " + shortcutText + " to rerun tests", "");
+ GotItMessage message = GotItMessage.createMessage("Rerun tests with " + shortcutText, "");
message.setDisposable(executionConsole);
message.setCallback(new Runnable() {
@Override
diff --git a/platform/lang-impl/src/com/intellij/find/actions/FindInPathAction.java b/platform/lang-impl/src/com/intellij/find/actions/FindInPathAction.java
index cc332d2ad110..4ced6fb97c3e 100644
--- a/platform/lang-impl/src/com/intellij/find/actions/FindInPathAction.java
+++ b/platform/lang-impl/src/com/intellij/find/actions/FindInPathAction.java
@@ -31,6 +31,10 @@ import com.intellij.psi.PsiElement;
public class FindInPathAction extends AnAction implements DumbAware {
static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("FindInPath", ToolWindowId.FIND, false);
+ { // enabled in modal content for find in path <-> replace in path modal dialog transition
+ setEnabledInModalContext(true);
+ }
+
@Override
public void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
diff --git a/platform/lang-impl/src/com/intellij/find/actions/ReplaceInPathAction.java b/platform/lang-impl/src/com/intellij/find/actions/ReplaceInPathAction.java
index ae7a0233c86f..eef79eed9dac 100644
--- a/platform/lang-impl/src/com/intellij/find/actions/ReplaceInPathAction.java
+++ b/platform/lang-impl/src/com/intellij/find/actions/ReplaceInPathAction.java
@@ -22,6 +22,10 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
public class ReplaceInPathAction extends AnAction {
+ { // enabled in modal content for find in path <-> replace in path modal dialog transition
+ setEnabledInModalContext(true);
+ }
+
@Override
public void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
index 9721e1b00b36..45622f0532c6 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
@@ -23,7 +23,6 @@ import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.editor.Document;
@@ -114,6 +113,13 @@ public class FindInProjectUtil {
if (model.getModuleName() == null || editor == null) {
model.setDirectoryName(directoryName);
model.setProjectScope(directoryName == null && module == null && !model.isCustomScope() || editor != null);
+
+ // for convenience set directory name to directory of current file, note that we doesn't change default projectScope
+ if (directoryName == null) {
+ VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
+ if (virtualFile != null && !virtualFile.isDirectory()) virtualFile = virtualFile.getParent();
+ if (virtualFile != null) model.setDirectoryName(virtualFile.getPresentableUrl());
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
index b35309e40b58..936e379de8c9 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
@@ -454,7 +454,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
SyntaxHighlighter highlighter = getHighlighter(file, lang);
if (highlighter == null) {
- LOG.error("Syntax highlighter is null:"+file);
+ // no syntax highlighter -> no search
return NOT_FOUND_RESULT;
}
@@ -467,12 +467,9 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
public Set compute() {
THashSet result = new THashSet();
- for(Project project: ProjectManager.getInstance().getOpenProjects()) {
- FileViewProvider viewProvider = PsiManager.getInstance(project).findViewProvider(file);
- if (viewProvider != null) {
- result.addAll(viewProvider.getLanguages());
- break;
- }
+ FileViewProvider viewProvider = PsiManager.getInstance(myProject).findViewProvider(file);
+ if (viewProvider != null) {
+ result.addAll(viewProvider.getLanguages());
}
if (result.isEmpty()) {
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index 81b51bfb03ba..a0ef975666ad 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -29,6 +29,7 @@ import com.intellij.ide.ui.search.BooleanOptionDescription;
import com.intellij.ide.ui.search.OptionDescription;
import com.intellij.ide.ui.search.SearchableOptionsRegistrarImpl;
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.gotoByName.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
@@ -92,6 +93,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.*;
@@ -105,6 +107,7 @@ import java.util.concurrent.atomic.AtomicLong;
* @author Konstantin Bulenkov
*/
public class SearchEverywhereAction extends AnAction implements CustomComponentAction, DumbAware{
+ public static final String SE_HISTORY_KEY = "SearchEverywhereHistory";
public static final int SEARCH_FIELD_COLUMNS = 25;
private static final int MAX_CLASSES = 6;
private static final int MAX_FILES = 6;
@@ -149,6 +152,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private static AtomicLong ourLastTimePressed = new AtomicLong(0);
private static AtomicBoolean showAll = new AtomicBoolean(false);
private ArrayList myAlreadyAddedFiles = new ArrayList();
+ private int myHistoryIndex = 0;
static {
IdeEventQueue.getInstance().addPostprocessor(new IdeEventQueue.EventDispatcher() {
@@ -250,8 +254,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
@Override
protected void paintComponent(Graphics g) {
if (myBalloon != null && !myBalloon.isDisposed() && myActionEvent != null && myActionEvent.getInputEvent() instanceof MouseEvent) {
- ((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(147, 162, 174), new Color(64, 80, 94)), 0, getHeight(),
- new JBColor(new Color(116, 128, 143), new Color(53, 65, 87))));
+ final Gradient gradient = getGradientColors();
+ ((Graphics2D)g).setPaint(new GradientPaint(0, 0, gradient.getStartColor(), 0, getHeight(), gradient.getEndColor()));
g.fillRect(0,0,getWidth(), getHeight());
} else {
super.paintComponent(g);
@@ -299,6 +303,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
return panel;
}
+ private static Gradient getGradientColors() {
+ return new Gradient(
+ new JBColor(new Color(101, 147, 242), new Color(64, 80, 94)),
+ new JBColor(new Color(46, 111, 205), new Color(53, 65, 87)));
+ }
public SearchEverywhereAction() {
myRenderer = new MyListRenderer();
@@ -511,6 +520,15 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
if (myPopup != null && myPopup.isVisible()) {
myPopup.cancel();
}
+
+ if (value instanceof BooleanOptionDescription) {
+ final BooleanOptionDescription option = (BooleanOptionDescription)value;
+ option.setOptionState(!option.isOptionEnabled());
+ myList.revalidate();
+ myList.repaint();
+ return;
+ }
+
AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
if (value instanceof PsiElement) {
@@ -531,17 +549,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
@Override
public void run() {
- if (value instanceof BooleanOptionDescription) {
- final BooleanOptionDescription option = (BooleanOptionDescription)value;
- option.setOptionState(!option.isOptionEnabled());
- }
- else {
- Component c = comp;
- if (c == null) {
- c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
- }
- GotoActionAction.openOptionOrPerformAction(value, pattern, project, c, event);
+ Component c = comp;
+ if (c == null) {
+ c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
}
+ GotoActionAction.openOptionOrPerformAction(value, pattern, project, c, event);
}
});
return;
@@ -588,6 +600,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
if (e == null) return;
myContextComponent = PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext());
+ final Project project = e.getProject();
Window wnd = myContextComponent != null ? SwingUtilities.windowForComponent(myContextComponent)
: KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
if (wnd == null && myContextComponent instanceof Window) {
@@ -601,35 +614,53 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myPopupField = new MySearchTextField();
initSearchField(myPopupField);
myPopupField.setOpaque(false);
- myPopupField.getTextEditor().setColumns(SEARCH_FIELD_COLUMNS);
+ final JTextField editor = myPopupField.getTextEditor();
+ editor.setColumns(SEARCH_FIELD_COLUMNS);
final JPanel panel = new JPanel(new BorderLayout()) {
@Override
protected void paintComponent(Graphics g) {
- ((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(147, 162, 174), new Color(64, 80, 94)), 0, getHeight(),
- new JBColor(new Color(116, 128, 143), new Color(53, 65, 87))));
+ final Gradient gradient = getGradientColors();
+ ((Graphics2D)g).setPaint(new GradientPaint(0, 0, gradient.getStartColor(), 0, getHeight(), gradient.getEndColor()));
g.fillRect(0, 0, getWidth(), getHeight());
}
};
final JLabel title = new JLabel(" Search Everywhere: ");
final JPanel topPanel = new NonOpaquePanel(new BorderLayout());
- title.setForeground(new JBColor(Gray._50, Gray._180));
+ title.setForeground(new JBColor(Gray._240, Gray._200));
if (SystemInfo.isMac) {
title.setFont(title.getFont().deriveFont(Font.BOLD, title.getFont().getSize() - 1f));
} else {
title.setFont(title.getFont().deriveFont(Font.BOLD));
}
topPanel.add(title, BorderLayout.WEST);
+ myNonProjectCheckBox.setForeground(new JBColor(Gray._240, Gray._200));
myNonProjectCheckBox.setText("Include non-project items (" + getShortcut() + ")");
topPanel.add(myNonProjectCheckBox, BorderLayout.EAST);
panel.add(myPopupField, BorderLayout.CENTER);
panel.add(topPanel, BorderLayout.NORTH);
panel.setBorder(IdeBorderFactory.createEmptyBorder(3, 5, 4, 5));
- final ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, myPopupField.getTextEditor());
+ final ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, editor);
myBalloon = builder
.setCancelOnClickOutside(true)
.setModalContext(false)
+ .setCancelCallback(new Computable() {
+ @Override
+ public Boolean compute() {
+ final String last = editor.getText().trim();
+ final PropertiesComponent storage = PropertiesComponent.getInstance(project);
+ final String historyString = storage.getValue(SE_HISTORY_KEY);
+ List history = StringUtil.isEmpty(historyString) ? new ArrayList() : StringUtil.split(historyString, "\n");
+ history.remove(last);
+ history.add(last);
+ if (history.size() > 10) {
+ history = history.subList(0, 10);
+ }
+ storage.setValue(SE_HISTORY_KEY, StringUtil.join(history, "\n"));
+ return true;
+ }
+ })
.createPopup();
-
+ myBalloon.getContent().setBorder(new EmptyBorder(0,0,0,0));
final Window window = WindowManager.getInstance().suggestParentWindow(e.getProject());
Component parent = UIUtil.findUltimateParent(window);
@@ -656,7 +687,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myBalloon.show(showPoint);
initSearchActions(myBalloon, myPopupField);
IdeFocusManager focusManager = IdeFocusManager.getInstance(e.getProject());
- focusManager.requestFocus(myPopupField.getTextEditor(), true);
+ focusManager.requestFocus(editor, true);
FeatureUsageTracker.getInstance().triggerFeatureUsed(IdeActions.ACTION_SEARCH_EVERYWHERE);
}
@@ -710,6 +741,28 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
}
}.registerCustomShortcutSet(CustomShortcutSet.fromString("ENTER"), editor, balloon);
+ new DumbAwareAction(){
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final PropertiesComponent storage = PropertiesComponent.getInstance(e.getProject());
+ final String historyString = storage.getValue(SE_HISTORY_KEY);
+ if (historyString != null) {
+ final List history = StringUtil.split(historyString, "\n");
+ if (history.size() > myHistoryIndex) {
+ final String text = history.get(myHistoryIndex);
+ editor.setText(text);
+ editor.setCaretPosition(text.length());
+ editor.moveCaretPosition(0);
+ myHistoryIndex++;
+ }
+ }
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ e.getPresentation().setEnabled(editor.getCaretPosition() == 0);
+ }
+ }.registerCustomShortcutSet(CustomShortcutSet.fromString("LEFT"), editor, balloon);
}
private static class MySearchTextField extends SearchTextField implements DataProvider, Disposable {
@@ -1460,6 +1513,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
})
.createPopup();
+ myPopup.getContent().setBorder(new EmptyBorder(0,0,0,0));
Disposer.register(myPopup, new Disposable() {
@Override
public void dispose() {
@@ -1487,6 +1541,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myRenderer.myProject = null;
myCalcThread = null;
myPopup = null;
+ myHistoryIndex = 0;
showAll.set(false);
myNonProjectCheckBox.setSelected(false);
ActionToolbarImpl.updateAllToolbarsImmediately();
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
index fec55d085d01..06273414191f 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
@@ -82,6 +82,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
@@ -1247,6 +1248,18 @@ public abstract class ChooseByNameBase {
});
}
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension size = super.getPreferredSize();
+ Border border = super.getBorder();
+ if (border != null && UIUtil.isUnderAquaLookAndFeel()) {
+ Insets insets = border.getBorderInsets(this);
+ size.height += insets.top + insets.bottom;
+ size.width += insets.left + insets.right;
+ }
+ return size;
+ }
+
@Nullable
private KeyStroke getShortcut(String actionCodeCompletion) {
final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionCodeCompletion);
diff --git a/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java b/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java
index 8c46ec5b1b0e..5af6db07b9d7 100644
--- a/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java
+++ b/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java
@@ -64,7 +64,7 @@ public abstract class AbstractGithubTagDownloadedProjectGenerator extends WebPro
unpackToDir(project, new File(baseDir.getPath()), tag);
}
catch (GeneratorException e) {
- showErrorMessage(e.getMessage());
+ showErrorMessage(project, e.getMessage());
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
@@ -149,10 +149,9 @@ public abstract class AbstractGithubTagDownloadedProjectGenerator extends WebPro
return GithubDownloadUtil.findCacheFile(getGithubUserName(), getGithubRepositoryName(), fileName);
}
- private void showErrorMessage(@NotNull String message) {
+ private void showErrorMessage(@NotNull Project project, @NotNull String message) {
String fullMessage = "Error creating " + getDisplayName() + " project. " + message;
String title = "Create " + getDisplayName() + " Project";
- Project project = null;
Messages.showErrorDialog(project, fullMessage, title);
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
index cc01c67973d4..df8b295ec9de 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
@@ -420,6 +420,10 @@ class RootIndex {
@Nullable
public String getPackageName(@NotNull final VirtualFile dir) {
if (dir.isDirectory()) {
+ if (FileTypeManager.getInstance().isFileIgnored(dir)) {
+ return null;
+ }
+
for (final Map.Entry> entry : myPackagePrefixRoots.entrySet()) {
if (entry.getValue().contains(dir)) {
return entry.getKey();
diff --git a/platform/lang-impl/src/com/intellij/platform/templates/github/ZipUtil.java b/platform/lang-impl/src/com/intellij/platform/templates/github/ZipUtil.java
index 28f86cbc6b53..73c7b4aea852 100644
--- a/platform/lang-impl/src/com/intellij/platform/templates/github/ZipUtil.java
+++ b/platform/lang-impl/src/com/intellij/platform/templates/github/ZipUtil.java
@@ -12,11 +12,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
import java.util.concurrent.Callable;
import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
/**
@@ -45,13 +47,7 @@ public class ZipUtil {
@Override
public Boolean call() throws IOException {
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
- ZipInputStream stream = new ZipInputStream(new FileInputStream(zipArchive));
- try {
- unzip(progress, extractToDir, stream, null, null, unwrapSingleTopLevelFolder);
- }
- finally {
- stream.close();
- }
+ unzip(progress, extractToDir, zipArchive, null, null, unwrapSingleTopLevelFolder);
return true;
}
},
@@ -73,25 +69,59 @@ public class ZipUtil {
}
}
+ private static File getUnzipToDir(@Nullable ProgressIndicator progress,
+ @NotNull File targetDir,
+ boolean unwrapSingleTopLevelFolder) throws IOException {
+ if (progress != null) {
+ progress.setText("Extracting...");
+ }
+ if (unwrapSingleTopLevelFolder) {
+ return FileUtil.createTempDirectory("unzip-dir-", null);
+ }
+ return targetDir;
+ }
+
+ // This method will throw IOException, if a zipArchive file isn't a valid zip archive.
+ public static void unzip(@Nullable ProgressIndicator progress,
+ @NotNull File targetDir,
+ @NotNull File zipArchive,
+ @Nullable NullableFunction pathConvertor,
+ @Nullable ContentProcessor contentProcessor,
+ boolean unwrapSingleTopLevelFolder) throws IOException {
+ File unzipToDir = getUnzipToDir(progress, targetDir, unwrapSingleTopLevelFolder);
+ ZipFile zipFile = new ZipFile(zipArchive, ZipFile.OPEN_READ);
+ try {
+ Enumeration extends ZipEntry> entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = entries.nextElement();
+ InputStream entryContentStream = zipFile.getInputStream(entry);
+ unzipEntryToDir(progress, entry, entryContentStream, unzipToDir, pathConvertor, contentProcessor);
+ entryContentStream.close();
+ }
+ }
+ finally {
+ zipFile.close();
+ }
+ doUnwrapSingleTopLevelFolder(unwrapSingleTopLevelFolder, unzipToDir, targetDir);
+ }
+
public static void unzip(@Nullable ProgressIndicator progress,
@NotNull File targetDir,
@NotNull ZipInputStream stream,
@Nullable NullableFunction pathConvertor,
@Nullable ContentProcessor contentProcessor,
boolean unwrapSingleTopLevelFolder) throws IOException {
- if (progress != null) {
- progress.setText("Extracting...");
- }
- File unzipToDir = targetDir;
- if (unwrapSingleTopLevelFolder) {
- unzipToDir = FileUtil.createTempDirectory("unzip-dir-", null);
- }
-
+ File unzipToDir = getUnzipToDir(progress, targetDir, unwrapSingleTopLevelFolder);
ZipEntry entry;
while ((entry = stream.getNextEntry()) != null) {
- unzipEntryToDir(progress, entry, unzipToDir, stream, pathConvertor, contentProcessor);
+ unzipEntryToDir(progress, entry, stream, unzipToDir, pathConvertor, contentProcessor);
}
+ doUnwrapSingleTopLevelFolder(unwrapSingleTopLevelFolder, unzipToDir, targetDir);
+ }
+ private static void doUnwrapSingleTopLevelFolder(boolean unwrapSingleTopLevelFolder,
+ @NotNull File unzipToDir,
+ @NotNull File targetDir) throws IOException {
if (unwrapSingleTopLevelFolder) {
File[] topLevelFiles = unzipToDir.listFiles();
File dirToMove;
@@ -110,8 +140,8 @@ public class ZipUtil {
private static void unzipEntryToDir(@Nullable ProgressIndicator progress,
@NotNull final ZipEntry zipEntry,
+ @NotNull final InputStream entryContentStream,
@NotNull final File extractToDir,
- ZipInputStream stream,
@Nullable NullableFunction pathConvertor,
@Nullable ContentProcessor contentProcessor) throws IOException {
String relativeExtractPath = createRelativeExtractPath(zipEntry);
@@ -136,14 +166,14 @@ public class ZipUtil {
if (contentProcessor == null) {
FileOutputStream fileOutputStream = new FileOutputStream(child);
try {
- FileUtil.copy(stream, fileOutputStream);
+ FileUtil.copy(entryContentStream, fileOutputStream);
}
finally {
fileOutputStream.close();
}
}
else {
- byte[] content = contentProcessor.processContent(FileUtil.loadBytes(stream), child);
+ byte[] content = contentProcessor.processContent(FileUtil.loadBytes(entryContentStream), child);
if (content != null) {
FileOutputStream fileOutputStream = new FileOutputStream(child);
try {
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
index 06f4e2703252..5f887b115d03 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
@@ -315,7 +315,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
final MyIndex index = (MyIndex)myIndices.get(indexKey);
try {
- return index.processAllKeys(processor, idFilter);
+ return index.processAllKeys(processor, scope, idFilter);
}
catch (StorageException e) {
forceRebuild(e);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java
index 10adf97d59b1..50e87f85baab 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java
@@ -16,6 +16,7 @@
package com.intellij.util.indexing;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,5 +29,5 @@ public interface AbstractIndex {
@NotNull
ValueContainer getData(Key key) throws StorageException;
- boolean processAllKeys(Processor processor, @Nullable IdFilter idFilter) throws StorageException;
+ boolean processAllKeys(Processor processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) throws StorageException;
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index b0592ed6a590..f0bb5a676e72 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -736,7 +736,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
return true;
}
ensureUpToDate(indexId, scope.getProject(), scope);
- return index.processAllKeys(processor, idFilter);
+ return index.processAllKeys(processor, scope, idFilter);
}
catch (StorageException e) {
scheduleRebuild(indexId, e);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java
index 5e0296b335dd..0f8bb67f00fc 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java
@@ -16,6 +16,7 @@
package com.intellij.util.indexing;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,7 +40,7 @@ public interface IndexStorage extends Flushable {
@NotNull
ValueContainer read(Key key) throws StorageException;
- boolean processKeys(Processor processor, @Nullable IdFilter idFilter) throws StorageException;
+ boolean processKeys(Processor processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) throws StorageException;
Collection getKeys() throws StorageException;
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
index b0eaf2dd29d6..649bd25730fb 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
@@ -18,20 +18,24 @@ package com.intellij.util.indexing;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.ProjectAndLibrariesScope;
+import com.intellij.psi.search.ProjectScopeImpl;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
+import com.intellij.util.SystemProperties;
import com.intellij.util.containers.SLRUCache;
import com.intellij.util.io.*;
+import com.intellij.util.io.DataOutputStream;
import gnu.trove.TIntHashSet;
+import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -44,10 +48,12 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public final class MapIndexStorage implements IndexStorage{
private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.MapIndexStorage");
+ private static final boolean ENABLE_CACHED_HASH_IDS = SystemProperties.getBooleanProperty("idea.index.no.cashed.hashids", true);
private final boolean myBuildKeyHashToVirtualFileMapping;
private PersistentMap> myMap;
private PersistentBTreeEnumerator myKeyHashToVirtualFileMapping;
private SLRUCache> myCache;
+ private volatile int myLastScannedId;
private final File myStorageFile;
private final KeyDescriptor myKeyDescriptor;
private final int myCacheSize;
@@ -216,29 +222,58 @@ public final class MapIndexStorage implements IndexStorage processor, final IdFilter idFilter) throws StorageException {
+ public boolean processKeys(final Processor processor, GlobalSearchScope scope, final IdFilter idFilter) throws StorageException {
l.lock();
try {
myCache.clear(); // this will ensure that all new keys are made into the map
if (myBuildKeyHashToVirtualFileMapping && idFilter != null) {
- final TIntHashSet hashMaskSet = new TIntHashSet(1000);
+ TIntHashSet hashMaskSet = null;
long l = System.currentTimeMillis();
- myKeyHashToVirtualFileMapping.iterateData(new Processor() {
- @Override
- public boolean process(int[] key) {
- if (!idFilter.containsFileId(key[1])) return true;
- hashMaskSet.add(key[0]);
- ProgressManager.checkCanceled();
- return true;
+
+ File fileWithCaches = getSavedProjectFileValueIds(myLastScannedId, scope);
+ final boolean useCachedHashIds = ENABLE_CACHED_HASH_IDS &&
+ (scope instanceof ProjectScopeImpl || scope instanceof ProjectAndLibrariesScope) &&
+ fileWithCaches != null;
+ int id = myKeyHashToVirtualFileMapping.getLargestId();
+
+ if (useCachedHashIds && id == myLastScannedId) {
+ try {
+ hashMaskSet = loadHashedIds(fileWithCaches);
+ } catch (IOException ex) {
+ LOG.info(ex);
}
- });
+ }
+
+ if (hashMaskSet == null) {
+ if (useCachedHashIds && myLastScannedId != 0) {
+ FileUtil.asyncDelete(fileWithCaches);
+ }
+
+ hashMaskSet = new TIntHashSet(1000);
+ final TIntHashSet finalHashMaskSet = hashMaskSet;
+ myKeyHashToVirtualFileMapping.iterateData(new Processor() {
+ @Override
+ public boolean process(int[] key) {
+ if (!idFilter.containsFileId(key[1])) return true;
+ finalHashMaskSet.add(key[0]);
+ ProgressManager.checkCanceled();
+ return true;
+ }
+ });
+
+ if (useCachedHashIds) {
+ saveHashedIds(hashMaskSet, id, scope);
+ }
+ }
+
if (LOG.isDebugEnabled()) {
LOG.debug("Scanned keyHashToVirtualFileMapping of " + myStorageFile + " for " + (System.currentTimeMillis() - l));
}
+ final TIntHashSet finalHashMaskSet = hashMaskSet;
return myMap.processKeys(new Processor() {
@Override
public boolean process(Key key) {
- if (!hashMaskSet.contains(myKeyDescriptor.getHashCode(key))) return true;
+ if (!finalHashMaskSet.contains(myKeyDescriptor.getHashCode(key))) return true;
return processor.process(key);
}
});
@@ -263,11 +298,70 @@ public final class MapIndexStorage implements IndexStorage 0) {
+ hashMaskSet.add(DataInputOutputUtil.readINT(inputStream));
+ --capacity;
+ }
+ inputStream.close();
+ return hashMaskSet;
+ }
+ finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException ex) {}
+ }
+ }
+ }
+
+ private void saveHashedIds(TIntHashSet hashMaskSet, int largestId, GlobalSearchScope scope) {
+ File newFileWithCaches = getSavedProjectFileValueIds(largestId, scope);
+ assert newFileWithCaches != null;
+ DataOutputStream stream = null;
+
+ try {
+ stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(newFileWithCaches)));
+ DataInputOutputUtil.writeINT(stream, hashMaskSet.size());
+ final DataOutputStream finalStream = stream;
+ boolean result = hashMaskSet.forEach(new TIntProcedure() {
+ @Override
+ public boolean execute(int value) {
+ try {
+ DataInputOutputUtil.writeINT(finalStream, value);
+ return true;
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+ });
+ if (result) myLastScannedId = largestId;
+ } catch (IOException ex) {}
+ finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException ex) {}
+ }
+ }
+ }
+
+ private @Nullable File getSavedProjectFileValueIds(int id, GlobalSearchScope scope) {
+ Project project = scope.getProject();
+ if (project == null) return null;
+ return new File(myStorageFile.getPath() + ".project."+project.hashCode() + "."+id + "." + scope.isSearchInLibraries());
+ }
+
@NotNull
@Override
public Collection getKeys() throws StorageException {
List keys = new ArrayList();
- processKeys(new CommonProcessors.CollectProcessor(keys), null);
+ processKeys(new CommonProcessors.CollectProcessor(keys), null, null);
return keys;
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
index 008aa3fd43a0..439770324875 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Processor;
import com.intellij.util.io.PersistentHashMap;
import gnu.trove.THashMap;
@@ -155,11 +156,11 @@ public class MapReduceIndex implements UpdatableIndex processor, IdFilter idFilter) throws StorageException {
+ public boolean processAllKeys(Processor processor, GlobalSearchScope scope, IdFilter idFilter) throws StorageException {
final Lock lock = getReadLock();
try {
lock.lock();
- return myStorage.processKeys(processor, idFilter);
+ return myStorage.processKeys(processor, scope, idFilter);
}
finally {
lock.unlock();
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
index f07fc85b85cb..2b27622810a0 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
@@ -16,6 +16,7 @@
package com.intellij.util.indexing;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
@@ -101,12 +102,12 @@ public class MemoryIndexStorage implements IndexStorage
@Override
public Collection getKeys() throws StorageException {
final Set keys = new HashSet();
- processKeys(new CommonProcessors.CollectProcessor(keys), null);
+ processKeys(new CommonProcessors.CollectProcessor(keys), null, null);
return keys;
}
@Override
- public boolean processKeys(final Processor processor, IdFilter idFilter) throws StorageException {
+ public boolean processKeys(final Processor processor, GlobalSearchScope scope, IdFilter idFilter) throws StorageException {
final Set stopList = new HashSet();
Processor decoratingProcessor = new Processor() {
@@ -128,7 +129,7 @@ public class MemoryIndexStorage implements IndexStorage
}
stopList.add(key);
}
- return myBackendStorage.processKeys(stopList.size() == 0 && myMap.size() == 0 ? processor : decoratingProcessor, idFilter);
+ return myBackendStorage.processKeys(stopList.size() == 0 && myMap.size() == 0 ? processor : decoratingProcessor, scope, idFilter);
}
@Override
diff --git a/platform/lang-impl/testData/platform/templates/github/invalid-archive.zip b/platform/lang-impl/testData/platform/templates/github/invalid-archive.zip
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/platform/lang-impl/testSources/com/intellij/platform/templates/github/ZipUtilTest.java b/platform/lang-impl/testSources/com/intellij/platform/templates/github/ZipUtilTest.java
index 95e065f4ca0c..2f85513863fb 100644
--- a/platform/lang-impl/testSources/com/intellij/platform/templates/github/ZipUtilTest.java
+++ b/platform/lang-impl/testSources/com/intellij/platform/templates/github/ZipUtilTest.java
@@ -3,11 +3,13 @@ package com.intellij.platform.templates.github;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.io.TestFileSystemBuilder;
+import junit.framework.Assert;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOException;
import java.util.zip.ZipInputStream;
import static com.intellij.util.io.TestFileSystemBuilder.fs;
@@ -51,6 +53,41 @@ public class ZipUtilTest {
}
}
+ @Test
+ public void testSimpleUnzipUsingFile() throws Exception {
+ File tempDir = FileUtil.createTempDirectory("unzip-test-", null);
+ File simpleZipFile = new File(getZipParentDir(), "simple.zip");
+ ZipUtil.unzip(null, tempDir, simpleZipFile, null, null, true);
+ checkFileStructure(tempDir,
+ fs()
+ .file("a.txt")
+ .dir("dir").file("b.txt"));
+ }
+
+ @Test
+ public void testSingleRootDirUnzipUsingFile() throws Exception {
+ File tempDir = FileUtil.createTempDirectory("unzip-test-", null);
+ File simpleZipFile = new File(getZipParentDir(), "single-root-dir-archive.zip");
+ ZipUtil.unzip(null, tempDir, simpleZipFile, null, null, true);
+ checkFileStructure(tempDir,
+ fs()
+ .file("a.txt")
+ .dir("dir").file("b.txt"));
+ }
+
+ @Test
+ public void testExpectedFailureOnBrokenZipArchive() throws Exception {
+ File tempDir = FileUtil.createTempDirectory("unzip-test-", null);
+ File file = new File(getZipParentDir(), "invalid-archive.zip");
+ try {
+ ZipUtil.unzip(null, tempDir, file, null, null, true);
+ Assert.fail("Zip archive is broken, but it was unzipped without exceptions.");
+ }
+ catch (IOException e) {
+ // expected exception
+ }
+ }
+
private static void checkFileStructure(@NotNull File parentDir, @NotNull TestFileSystemBuilder expected) {
expected.build().assertDirectoryEqual(parentDir);
}
diff --git a/platform/platform-api/platform-api.iml b/platform/platform-api/platform-api.iml
index e40a631f0c55..f6769b444e2b 100644
--- a/platform/platform-api/platform-api.iml
+++ b/platform/platform-api/platform-api.iml
@@ -32,6 +32,8 @@
+
+
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java b/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
index 3a1e9f431652..8f54a0d6de81 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
@@ -15,6 +15,7 @@
*/
package com.intellij.execution.configurations;
+import com.google.common.collect.Maps;
import com.intellij.execution.CommandLineUtil;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Platform;
@@ -26,10 +27,12 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.PlatformUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
+import com.pty4j.PtyProcess;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -62,8 +65,10 @@ public class GeneralCommandLine implements UserDataHolder {
private Charset myCharset = CharsetToolkit.getDefaultSystemCharset();
private boolean myRedirectErrorStream = false;
private Map