Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2013-11-27 17:43:01 +04:00
205 changed files with 3370 additions and 1697 deletions
+1
View File
@@ -106,6 +106,7 @@
<module fileurl="file://$PROJECT_DIR$/python/main_idea_python_plugin.iml" filepath="$PROJECT_DIR$/python/main_idea_python_plugin.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/python/main_pycharm_ce.iml" filepath="$PROJECT_DIR$/python/main_pycharm_ce.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/java/manifest/manifest.iml" filepath="$PROJECT_DIR$/java/manifest/manifest.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/artifact-resolver-m31/maven-artifact-resolver-m31.iml" filepath="$PROJECT_DIR$/plugins/maven/artifact-resolver-m31/maven-artifact-resolver-m31.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven.iml" filepath="$PROJECT_DIR$/plugins/maven/maven.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/artifact-resolver-m2/maven-artifact-resolver-m2.iml" filepath="$PROJECT_DIR$/plugins/maven/artifact-resolver-m2/maven-artifact-resolver-m2.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/artifact-resolver-m3/maven-artifact-resolver-m3.iml" filepath="$PROJECT_DIR$/plugins/maven/artifact-resolver-m3/maven-artifact-resolver-m3.iml" group="plugins/maven" />
+7
View File
@@ -299,6 +299,13 @@ public def layoutCommunityPlugins(String home) {
}
}
jar("artifact-resolver-m31.jar") {
module("maven-artifact-resolver-m31")
module("maven-artifact-resolver-m2") {
include(name: 'org/jetbrains/idea/maven/artifactResolver/common/*')
}
}
dir("maven3") {
fileset(dir: "$home/plugins/maven/maven3-server-impl/lib") {include(name: "*.jar")}
fileset(dir: "$home/plugins/maven/maven3-server-impl/lib/maven3/lib") {include(name: "*.jar")}
+1
View File
@@ -207,6 +207,7 @@ libraryLicense(name: "markdownj", libraryName: "markdownj", version: "0.4.2", li
libraryLicense(name: "Maven", version: "2.2.1", license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
libraryLicense(name: "plexus-util", version: "2.0.6", license: "Apache 2.0", url: "http://maven.apache.org/", libraryNames:['plexus-utils-2.0.6.jar'], licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "aether-api", version: "1.11", libraryNames: ["aether-api-1.11.jar"], license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
libraryLicense(name: "aether-api-0.9.0.M2.jar", version: "0.9.0.M2", libraryNames: ["aether-api-0.9.0.M2.jar"], license: "Eclipse Public License v1.0", url: "http://nexus.sonatype.org/", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html")
libraryLicense(name: "maven-2.2.1-uber", version: "2.2.1", libraryNames: ["maven-2.2.1-uber.jar"], license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
libraryLicense(name: "maven-artifact", version: "3.0.3", libraryNames: ["maven-artifact-3.0.3.jar"], license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
libraryLicense(name: "maven-core", version: "3.0.3", libraryNames: ["maven-core-3.0.3.jar"], license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://maven.apache.org/license.html")
@@ -3,8 +3,8 @@
<company name="JetBrains s.r.o." url="http://www.jetbrains.com/?fromIDE"/>
<build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
<install-over minbuild="129.1" maxbuild="132.9999" version="12.1"/>
<logo url="/idea_community_logo.png" textcolor="ffffff" progressColor="ffaa16" progressY="230" progressTailIcon="/community_progress_tail.png"/>
<about url="/idea_community_about.png" foreground="f5f5f5" linkColor="9dc0ff" logoX="300" logoY="265" logoW="75" logoH="30"/>
<logo url="/idea_community_logo.png" textcolor="444444" progressColor="ffaa16" progressY="222" progressTailIcon="/community_progress_tail.png"/>
<about url="/idea_community_about.png" foreground="444444" linkColor="000099" logoX="300" logoY="265" logoW="75" logoH="30"/>
<icon size32="/icon_CE.png" size16="/icon_CEsmall.png" size32opaque="/icon_CEwhite.png" size12="/toolwindows/toolWindowProject.png" size128="/icon_CE_128.png" ico="idea_CE.ico"/>
<package code="__PACKAGE_CODE__"/>
<names product="IDEA" fullname="IntelliJ IDEA" script="idea"/>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

After

Width:  |  Height:  |  Size: 346 KiB

@@ -41,7 +41,7 @@ class BuildMessageDispatcher extends SimpleChannelInboundHandler<CmdlineRemotePr
private static final AttributeKey<SessionData> SESSION_DATA = AttributeKey.valueOf("BuildMessageDispatcher.sessionData");
private final Map<UUID, SessionData> myMessageHandlers = new ConcurrentHashMap<UUID, SessionData>();
private final Map<UUID, SessionData> myMessageHandlers = new ConcurrentHashMap<UUID, SessionData>(16, 0.75f, 1);
private final Set<UUID> myCanceledSessions = new ConcurrentHashSet<UUID>();
public void registerBuildMessageHandler(UUID sessionId,
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.Trinity;
import com.intellij.psi.*;
@@ -84,10 +85,16 @@ public class ExceptionExFilterFactory implements ExceptionFilterFactory {
worker.execute(text, lineEndOffset);
Result result = worker.getResult();
if (result == null) continue;
OpenFileHyperlinkInfo hyperlinkInfo = ExceptionWorker.getOpenFileHyperlinkInfo(result);
int offset = hyperlinkInfo == null? -1 : hyperlinkInfo.getDescriptor().getOffset();
HyperlinkInfo hyperlinkInfo = result.hyperlinkInfo;
if (!(hyperlinkInfo instanceof FileHyperlinkInfo)) continue;
OpenFileDescriptor descriptor = ((FileHyperlinkInfo)hyperlinkInfo).getDescriptor();
if (descriptor == null) continue;
int offset = descriptor.getOffset();
PsiFile psiFile = worker.getFile();
if (offset <= 0 || psiFile == null) continue;
PsiElement element = psiFile.findElementAt(offset);
PsiTryStatement parent = PsiTreeUtil.getParentOfType(element, PsiTryStatement.class, true, PsiClass.class);
PsiCodeBlock tryBlock = parent != null? parent.getTryBlock() : null;
@@ -234,25 +234,25 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl
@Override
protected void updateSelection(@Nullable NamedConfigurable configurable) {
boolean selectionChanged = !Comparing.equal(myCurrentConfigurable, configurable);
if (myCurrentConfigurable != null && selectionChanged) {
if (myCurrentConfigurable instanceof LibraryConfigurable && selectionChanged) {
((LibraryConfigurable)myCurrentConfigurable).onUnselected();
}
super.updateSelection(configurable);
if (myCurrentConfigurable != null && selectionChanged) {
if (myCurrentConfigurable instanceof LibraryConfigurable && selectionChanged) {
((LibraryConfigurable)myCurrentConfigurable).onSelected();
}
}
@Override
public void onStructureUnselected() {
if (myCurrentConfigurable != null) {
if (myCurrentConfigurable instanceof LibraryConfigurable) {
((LibraryConfigurable)myCurrentConfigurable).onUnselected();
}
}
@Override
public void onStructureSelected() {
if (myCurrentConfigurable != null) {
if (myCurrentConfigurable instanceof LibraryConfigurable) {
((LibraryConfigurable)myCurrentConfigurable).onSelected();
}
}
@@ -234,15 +234,14 @@ public class HighlightNamesUtil {
DependencyValidationManagerImpl validationManager = (DependencyValidationManagerImpl)DependencyValidationManager.getInstance(file.getProject());
List<Pair<NamedScope,NamedScopesHolder>> scopes = validationManager.getScopeBasedHighlightingCachedScopes();
for (Pair<NamedScope, NamedScopesHolder> scope : scopes) {
NamedScope namedScope = scope.getFirst();
NamedScopesHolder scopesHolder = scope.getSecond();
PackageSet packageSet = namedScope.getValue();
if (packageSet != null && packageSet.contains(file, scopesHolder)) {
TextAttributesKey scopeKey = ScopeAttributesUtil.getScopeTextAttributeKey(namedScope.getName());
TextAttributes attributes = colorsScheme.getAttributes(scopeKey);
if (attributes == null || attributes.isEmpty()) {
continue;
}
final NamedScope namedScope = scope.getFirst();
final TextAttributesKey scopeKey = ScopeAttributesUtil.getScopeTextAttributeKey(namedScope.getName());
final TextAttributes attributes = colorsScheme.getAttributes(scopeKey);
if (attributes == null || attributes.isEmpty()) {
continue;
}
final PackageSet packageSet = namedScope.getValue();
if (packageSet != null && packageSet.contains(file, scope.getSecond())) {
result = TextAttributes.merge(attributes, result);
}
}
@@ -21,21 +21,19 @@ import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.*;
import java.util.List;
/**
* @author max
@@ -55,6 +53,18 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
myQuickFix = new AcceptSuggested();
}
@Override
public void writeSettings(@NotNull Element node) throws WriteExternalException {
node.addContent(new Element("option").setAttribute("name", "REPORT_VARIABLES").setAttribute("value", String.valueOf(REPORT_VARIABLES)));
node.addContent(new Element("option").setAttribute("name", "REPORT_PARAMETERS").setAttribute("value", String.valueOf(REPORT_PARAMETERS)));
if (!REPORT_CATCH_PARAMETERS) {
node.addContent(new Element("option").setAttribute("name", "REPORT_CATCH_PARAMETERS").setAttribute("value", "false"));
}
if (!REPORT_FOREACH_PARAMETERS) {
node.addContent(new Element("option").setAttribute("name", "REPORT_FOREACH_PARAMETERS").setAttribute("value", "false"));
}
}
@Override
public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
List<ProblemDescriptor> list = checkCodeBlock(method.getBody(), manager, isOnTheFly);
@@ -46,6 +46,11 @@ public class DummyEntryPointsPresentation extends UnusedDeclarationPresentation
return myQuickFixActions;
}
@Override
protected String getSeverityDelegateName() {
return UnusedDeclarationInspection.SHORT_NAME;
}
private class MoveEntriesToSuspicious extends QuickFixAction {
private MoveEntriesToSuspicious(@NotNull InspectionToolWrapper toolWrapper) {
super(InspectionsBundle.message("inspection.dead.code.remove.from.entry.point.quickfix"), null, null, toolWrapper);
@@ -117,7 +117,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta
@NonNls Element problemClassElement = new Element(InspectionsBundle.message("inspection.export.results.problem.element.tag"));
final RefElement refElement = (RefElement)refEntity;
final HighlightSeverity severity = getSeverity(refElement, getContext(), getToolWrapper());
final HighlightSeverity severity = getSeverity(refElement);
final String attributeKey =
getTextAttributeKey(refElement.getRefManager().getProject(), severity, ProblemHighlightType.LIKE_UNUSED_SYMBOL);
problemClassElement.setAttribute("severity", severity.myName);
@@ -455,7 +455,12 @@ public class LambdaUtil {
if (!tryToSubstitute) return cachedType;
}
final PsiElement gParent = expressionList.getParent();
PsiElement gParent = expressionList.getParent();
if (gParent instanceof PsiAnonymousClass) {
gParent = gParent.getParent();
}
if (gParent instanceof PsiCall) {
final PsiCall contextCall = (PsiCall)gParent;
final JavaResolveResult resolveResult = contextCall.resolveMethodGenerics();
@@ -9,10 +9,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.*;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -47,12 +44,12 @@ public class OverrideImplementExploreUtil {
Map<MethodSignature, PsiMethod> finals = new LinkedHashMap<MethodSignature,PsiMethod>();
Map<MethodSignature, PsiMethod> concretes = new LinkedHashMap<MethodSignature,PsiMethod>();
LOG.assertTrue(aClass.isValid());
PsiUtilCore.ensureValid(aClass);
Collection<HierarchicalMethodSignature> allMethodSigs = aClass.getVisibleSignatures();
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(aClass.getProject()).getResolveHelper();
for (HierarchicalMethodSignature signature : allMethodSigs) {
PsiMethod method = signature.getMethod();
LOG.assertTrue(method.isValid(), aClass);
PsiUtilCore.ensureValid(method);
if (method.hasModifierProperty(PsiModifier.STATIC) || !resolveHelper.isAccessible(method, aClass, aClass)) continue;
PsiClass hisClass = method.getContainingClass();
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
import com.intellij.psi.impl.source.javadoc.PsiInlineDocTagImpl;
import com.intellij.psi.impl.source.tree.JavaDocElementType;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
@@ -1039,7 +1040,7 @@ public class JavaDocInfoGenerator {
generateLinkValue(tag, buffer, false);
}
else if (tagName.equals(LITERAL_TAG)) {
generateLiteralValue(tag, buffer);
generateLiteralValue(buffer, ((PsiInlineDocTagImpl)tag).getDataElementsIgnoreWhitespaces());
}
else if (tagName.equals(CODE_TAG)) {
generateCodeValue(tag, buffer);
@@ -1073,14 +1074,12 @@ public class JavaDocInfoGenerator {
@SuppressWarnings({"HardCodedStringLiteral"})
private static void generateCodeValue(PsiInlineDocTag tag, StringBuilder buffer) {
buffer.append("<code>");
generateLiteralValue(tag, buffer);
generateLiteralValue(buffer, tag.getDataElements());
buffer.append("</code>");
}
private static void generateLiteralValue(PsiInlineDocTag tag, StringBuilder buffer) {
PsiElement[] elements = tag.getDataElements();
for (PsiElement element : elements) {
private static void generateLiteralValue(StringBuilder buffer, final PsiElement[] dataElements) {
for (PsiElement element : dataElements) {
appendPlainText(element.getText(), buffer);
}
}
@@ -35,10 +35,11 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlineDocTag, Constants {
private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create(
DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF);
private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create(
private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create(DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF);
private static final TokenSet VALUE_NO_WHITESPACE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create(
JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, DOC_COMMENT_BAD_CHARACTER));
private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create(
JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, WHITE_SPACE, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, DOC_COMMENT_BAD_CHARACTER));
public PsiInlineDocTagImpl() {
super(DOC_INLINE_TAG);
@@ -63,6 +64,10 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin
return getChildrenAsPsiElements(VALUE_BIT_SET, PsiElement.ARRAY_FACTORY);
}
public PsiElement[] getDataElementsIgnoreWhitespaces() {
return getChildrenAsPsiElements(VALUE_NO_WHITESPACE_BIT_SET, PsiElement.ARRAY_FACTORY);
}
@Override
public PsiDocTagValue getValueElement() {
return (PsiDocTagValue)findPsiChildByType(TAG_VALUE_BIT_SET);
@@ -439,9 +439,12 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
} else {
if (rightTypes.length != types.length || rightTypes[rightTypes.length - 1].getArrayDimensions() != types[types.length-1].getArrayDimensions()) {
types[types.length - 1] = ((PsiArrayType)types[types.length - 1]).getComponentType();
boolean expandTypeArray = types.length < rightTypes.length;
int min = Math.min(types.length, rightTypes.length);
types = Arrays.copyOf(types, min);
if (expandTypeArray) {
types[types.length - 1] = ((PsiArrayType)types[types.length - 1]).getComponentType();
}
rightTypes = Arrays.copyOf(rightTypes, min);
}
}
@@ -25,6 +25,7 @@ package com.intellij.psi.scope.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.util.Comparing;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
@@ -318,7 +319,13 @@ public class PsiScopesUtil {
if (initializer instanceof PsiNewExpression) {
final PsiAnonymousClass anonymousClass = ((PsiNewExpression)initializer).getAnonymousClass();
if (anonymousClass != null && type.equals(anonymousClass.getBaseClassType())) {
type = initializer.getType();
final PsiMethod[] refMethods = anonymousClass.findMethodsByName(methodCall.getMethodExpression().getReferenceName(), false);
if (refMethods.length > 0) {
final PsiClass baseClass = PsiUtil.resolveClassInType(type);
if (baseClass != null && !hasCovariantOverriding(baseClass, refMethods)) {
type = initializer.getType();
}
}
}
}
}
@@ -381,6 +388,18 @@ public class PsiScopesUtil {
}
}
private static boolean hasCovariantOverriding(PsiClass baseClass, PsiMethod[] refMethods) {
for (PsiMethod method : refMethods) {
final PsiType methodReturnType = method.getReturnType();
for (PsiMethod superMethod : method.findSuperMethods(baseClass)) {
if (!Comparing.equal(methodReturnType, superMethod.getReturnType())) {
return true;
}
}
}
return false;
}
private static boolean processQualifierType(@NotNull final PsiType type,
final MethodsProcessor processor,
PsiManager manager,
@@ -0,0 +1,19 @@
interface I<T> {
void accept(T t);
}
class LamdbaTest<T> {
public void f() {
new A<T>(t -> g(t)) {};
}
private void g(T t) {
}
class A<T2> {
public A(I<T> editor) {
}
}
}
@@ -0,0 +1,10 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Foo"><code>Foo</code></a></b></small><PRE>int <b>foo</b></PRE>
<pre>
<code>
class Clazzz {
def f[U](u: U) {}
val a = 1
}
</code>
</pre></body></html>
@@ -0,0 +1,14 @@
class Foo {
/**
* <pre>
* {@code
* class Clazzz {
* def f[U](u: U) {}
*
* val a = 1
* }
* }
* </pre>
*/
int foo;
}
@@ -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
@@ -0,0 +1,7 @@
package package1;
public class A {
public static class D {
public final String s = new String("package1");
}
}
@@ -0,0 +1,7 @@
package package2;
public class A {
public static class D {
public final String s = new String("package2");
}
}
@@ -0,0 +1,6 @@
package package2;
import package1.*;
public class B extends A{
}
@@ -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;
}
}
@@ -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<ref>oo();
}
}
@@ -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<caret> }'
def oldCount = PsiManager.getInstance(project).modificationTracker.javaStructureModificationCount
assert !myFixture.completeBasic()
assert !myFixture.completeBasic()
assert oldCount == PsiManager.getInstance(project).modificationTracker.javaStructureModificationCount
}
}
@@ -82,6 +82,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testArgumentOfAnonymousClass() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}
@@ -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];
@@ -313,7 +313,7 @@ public class InspectionProfileTest extends LightIdeaTestCase {
assertEquals(0, countInitializedTools(profile));
profile.writeExternal(new Element("profile"));
List<InspectionToolWrapper> initializedTools = getInitializedTools(profile);
if (initializedTools.size() != 1) {
if (initializedTools.size() > 0) {
for (InspectionToolWrapper initializedTool : initializedTools) {
System.out.println(initializedTool.getShortName());
}
@@ -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);
@@ -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));
@@ -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<TextRange, TextRange, TextRange> 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<VirtualFile> virtualFilesInLibraries = new ArrayList<VirtualFile>();
List<VirtualFile> virtualFilesInContent = new ArrayList<VirtualFile>();
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<VirtualFile> 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<TextRange, TextRange, TextRange> 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);
}
}
}
@@ -12,7 +12,7 @@
<orderEntry type="module" module-name="debugger-impl" />
<orderEntry type="module" module-name="execution-openapi" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="remote-servers-impl" scope="RUNTIME" />
<orderEntry type="module" module-name="remote-servers-impl" />
</component>
</module>
@@ -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;
}
}
@@ -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<BuildTarget<?>, List<? extends BuildRootDescriptor>>();
myRootToDescriptors = new THashMap<File, List<BuildRootDescriptor>>(FileUtil.FILE_HASHING_STRATEGY);
myFileFilters = new ConcurrentHashMap<BuildRootDescriptor, FileFilter>();
myFileFilters = new ConcurrentHashMap<BuildRootDescriptor, FileFilter>(16, 0.75f, 1);
final Iterable<AdditionalRootsProviderService> rootsProviders = JpsServiceManager.getInstance().getExtensions(AdditionalRootsProviderService.class);
for (BuildTargetType<?> targetType : TargetTypeRegistry.getInstance().getTargetTypes()) {
for (BuildTarget<?> target : targetIndex.getAllTargets(targetType)) {
@@ -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) {
@@ -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<File> myChangedFiles;
private final Set<ClassRepr> myDeletedClasses;
private final Set<ClassRepr> myAddedClasses;
private final Object myLock;
private final File myRootDir;
@@ -83,6 +85,10 @@ public class Mappings {
private IntIntMultiMaplet myClassToClassDependency;
private ObjectObjectMultiMaplet<File, ClassRepr> mySourceFileToClasses;
private IntObjectMaplet<File> 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<ClassRepr>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
myAddedClasses = new HashSet<ClassRepr>(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<File, ClassRepr>(FileUtil.FILE_HASHING_STRATEGY, ourClassSetConstructor);
myClassToSourceFile = new IntObjectTransientMaplet<File>();
}
@@ -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<File, ClassRepr>(
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<UsageRepr.Usage> usages,
final IntIntMultiMaplet dependenciesTrashBin) {
private void cleanupRemovedClass(final Mappings delta, @NotNull final ClassRepr cr, final Set<UsageRepr.Usage> 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<File, Collection<ClassRepr>>() {
public boolean execute(File src, Collection<ClassRepr> 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.<ClassRepr>emptySet() : Collections.unmodifiableSet(myDeletedClasses);
}
@NotNull
private Set<ClassRepr> getAddedClasses() {
return myAddedClasses == null ? Collections.<ClassRepr>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++) {
@@ -34,7 +34,7 @@ import java.util.concurrent.Executor;
*/
@ChannelHandler.Sharable
final class ProtobufClientMessageHandler<T extends ProtobufResponseHandler> extends SimpleChannelInboundHandler<MessageLite> {
private final ConcurrentHashMap<UUID, RequestFuture<T>> myHandlers = new ConcurrentHashMap<UUID, RequestFuture<T>>();
private final ConcurrentHashMap<UUID, RequestFuture<T>> myHandlers = new ConcurrentHashMap<UUID, RequestFuture<T>>(16, 0.75f, 1);
@NotNull
private final UUIDGetter myUuidGetter;
private final SimpleProtobufClient myClient;
@@ -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<Throwable> myException = new AtomicReference<Throwable>();
private final Object myQueueLock = new Object();
@@ -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";
@@ -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<BuildTarget<?>, BuildTargetConfiguration>();
myConfigurations = new ConcurrentHashMap<BuildTarget<?>, BuildTargetConfiguration>(16, 0.75f, 1);
myTargetIds = new HashMap<BuildTarget<?>, Integer>();
load();
}
@@ -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<BuildTargetType<?>, BuildTargetTypeState> myTypeStates = new ConcurrentHashMap<BuildTargetType<?>, BuildTargetTypeState>();
private ConcurrentMap<BuildTargetType<?>, BuildTargetTypeState> myTypeStates = new ConcurrentHashMap<BuildTargetType<?>, 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;
}
@@ -542,6 +542,7 @@ class OptimizedFileManager extends DefaultFileManager {
myDirectoryCache.clear();
myByteBufferCache.clear();
myIsFile.clear();
Paths.clearPathExistanceCache();
}
}
}
@@ -113,4 +113,9 @@ public class CommonTest extends IncrementalTestCase {
public void testAddDuplicateClass() throws Exception {
doTest();
}
public void testAddClassHidingImportedClass() throws Exception {
doTest();
}
}
Binary file not shown.
@@ -24,8 +24,8 @@ import java.util.concurrent.ConcurrentHashMap;
* @author nik
*/
public class JpsServiceManagerImpl extends JpsServiceManager {
private final ConcurrentHashMap<Class, Object> myServices = new ConcurrentHashMap<Class, Object>();
private final ConcurrentHashMap<Class, List<?>> myExtensions = new ConcurrentHashMap<Class, List<?>>();
private final ConcurrentHashMap<Class, Object> myServices = new ConcurrentHashMap<Class, Object>(16, 0.75f, 1);
private final ConcurrentHashMap<Class, List<?>> myExtensions = new ConcurrentHashMap<Class, List<?>>(16, 0.75f, 1);
@Override
public <T> T getService(Class<T> 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<T> loader = ServiceLoader.load(extensionClass, extensionClass.getClassLoader());
List<T> extensions = new ArrayList<T>();
final List<T> extensions = new ArrayList<T>();
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<T>)cached;
BIN
View File
Binary file not shown.
@@ -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 {
@@ -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
@@ -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
@@ -77,6 +77,7 @@ public abstract class AbstractDependencyData<T extends AbstractExternalEntityDat
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myScope.hashCode();
result = 31 * result + myOwnerModule.hashCode();
result = 31 * result + myTarget.hashCode();
return result;
@@ -88,7 +89,7 @@ public abstract class AbstractDependencyData<T extends AbstractExternalEntityDat
return false;
}
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
@@ -28,6 +28,7 @@ public abstract class ExternalProjectSettings implements Comparable<ExternalProj
private String myExternalProjectPath;
private boolean myUseAutoImport;
private boolean myCreateEmptyContentRootDirectories;
public String getExternalProjectPath() {
return myExternalProjectPath;
@@ -45,6 +46,14 @@ public abstract class ExternalProjectSettings implements Comparable<ExternalProj
myUseAutoImport = useAutoImport;
}
public boolean isCreateEmptyContentRootDirectories() {
return myCreateEmptyContentRootDirectories;
}
public void setCreateEmptyContentRootDirectories(boolean createEmptyContentRootDirectories) {
myCreateEmptyContentRootDirectories = createEmptyContentRootDirectories;
}
@Override
public int compareTo(@NotNull ExternalProjectSettings that) {
return Comparing.compare(myExternalProjectPath, that.myExternalProjectPath);
@@ -76,5 +85,6 @@ public abstract class ExternalProjectSettings implements Comparable<ExternalProj
protected void copyTo(@NotNull ExternalProjectSettings receiver) {
receiver.myExternalProjectPath = myExternalProjectPath;
receiver.myUseAutoImport = myUseAutoImport;
receiver.myCreateEmptyContentRootDirectories = myCreateEmptyContentRootDirectories;
}
}
@@ -33,6 +33,7 @@ import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.net.NetUtils;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -166,12 +167,13 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
final String startDateTime = DateFormatUtil.formatTimeWithSeconds(System.currentTimeMillis());
final String greeting;
if (mySettings.getTaskNames().size() > 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);
}
});
@@ -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<ContentRootDat
for(ContentEntry contentEntry : contentEntries) {
contentEntriesMap.put(contentEntry.getUrl(), contentEntry);
}
boolean createEmptyContentRootDirectories = false;
if (!datas.isEmpty()) {
ProjectSystemId projectSystemId = datas.iterator().next().getData().getOwner();
AbstractExternalSystemSettings externalSystemSettings =
ExternalSystemApiUtil.getSettings(module.getProject(), projectSystemId);
String path = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
if (path != null) {
ExternalProjectSettings projectSettings = externalSystemSettings.getLinkedProjectSettings(path);
createEmptyContentRootDirectories = projectSettings != null && projectSettings.isCreateEmptyContentRootDirectories();
}
}
try {
for (final DataNode<ContentRootData> 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<ContentRootDat
private static void createSourceRootIfAbsent(
@NotNull ContentEntry entry, @NotNull String path, @NotNull String moduleName,
@NotNull JpsModuleSourceRootType sourceRootType, boolean generated) {
@NotNull JpsModuleSourceRootType sourceRootType, boolean generated, boolean createEmptyContentRootDirectories) {
List<SourceFolder> folders = entry.getSourceFolders(sourceRootType);
for (SourceFolder folder : folders) {
VirtualFile file = folder.getFile();
@@ -173,11 +191,13 @@ public class ContentRootDataService implements ProjectDataService<ContentRootDat
properties.setForGeneratedSources(true);
}
}
try {
VfsUtil.createDirectoryIfMissing(path);
}
catch (IOException e) {
LOG.warn(String.format("Unable to create directory for the path: %s", path), e);
if(createEmptyContentRootDirectories) {
try {
VfsUtil.createDirectoryIfMissing(path);
}
catch (IOException e) {
LOG.warn(String.format("Unable to create directory for the path: %s", path), e);
}
}
}
@@ -112,7 +112,7 @@ public class LibraryDependencyDataService extends AbstractDependencyDataService<
// The trick is that we should perform module settings modification inside try/finally block against target root model.
// That means that we need to prepare all necessary data, obtain a model and modify it as necessary.
Map<Set<String>/* library paths */, LibraryDependencyData> moduleLibrariesToImport = ContainerUtilRt.newHashMap();
Map<String/* library name */, LibraryDependencyData> projectLibrariesToImport = ContainerUtilRt.newHashMap();
Map<String/* library name + scope */, LibraryDependencyData> projectLibrariesToImport = ContainerUtilRt.newHashMap();
Set<LibraryDependencyData> 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) {
@@ -37,6 +37,7 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
@NotNull private S myInitialSettings;
private JBCheckBox myUseAutoImportBox;
private JBCheckBox myCreateEmptyContentRootDirectoriesBox;
private boolean myHideUseAutoImportBox;
protected AbstractExternalProjectSettingsControl(@NotNull S initialSettings) {
@@ -57,13 +58,18 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
myUseAutoImportBox = new JBCheckBox(ExternalSystemBundle.message("settings.label.use.auto.import"));
myUseAutoImportBox.setVisible(!myHideUseAutoImportBox);
canvas.add(myUseAutoImportBox, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
myCreateEmptyContentRootDirectoriesBox =
new JBCheckBox(ExternalSystemBundle.message("settings.label.create.empty.content.root.directories"));
canvas.add(myCreateEmptyContentRootDirectoriesBox, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
fillExtraControls(canvas, indentLevel);
}
protected abstract void fillExtraControls(@NotNull PaintAwarePanel content, int indentLevel);
public boolean isModified() {
return myUseAutoImportBox.isSelected() != getInitialSettings().isUseAutoImport() || isExtraSettingModified();
return myUseAutoImportBox.isSelected() != getInitialSettings().isUseAutoImport()
|| myCreateEmptyContentRootDirectoriesBox.isSelected() != getInitialSettings().isCreateEmptyContentRootDirectories()
|| isExtraSettingModified();
}
protected abstract boolean isExtraSettingModified();
@@ -74,6 +80,7 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
public void reset(boolean isDefaultModuleCreation) {
myUseAutoImportBox.setSelected(getInitialSettings().isUseAutoImport());
myCreateEmptyContentRootDirectoriesBox.setSelected(getInitialSettings().isCreateEmptyContentRootDirectories());
resetExtraSettings(isDefaultModuleCreation);
}
@@ -83,6 +90,8 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
public void apply(@NotNull S settings) {
settings.setUseAutoImport(myUseAutoImportBox.isSelected());
myInitialSettings.setUseAutoImport(myUseAutoImportBox.isSelected());
settings.setCreateEmptyContentRootDirectories(myCreateEmptyContentRootDirectoriesBox.isSelected());
myInitialSettings.setCreateEmptyContentRootDirectories(myCreateEmptyContentRootDirectoriesBox.isSelected());
if (myInitialSettings.getExternalProjectPath() != null) {
settings.setExternalProjectPath(myInitialSettings.getExternalProjectPath());
}
@@ -16,6 +16,7 @@
package com.intellij.openapi.externalSystem.service.task.ui;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.project.Project;
@@ -23,6 +24,7 @@ import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Alarm;
import com.intellij.util.Producer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.tree.TreeModelAdapter;
import org.jetbrains.annotations.NotNull;
@@ -52,12 +54,12 @@ public class ExternalSystemTasksTree extends Tree implements Producer<ExternalTa
return o2.getPathCount() - o1.getPathCount();
}
};
@NotNull private final Alarm myCollapseStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
/** Holds list of paths which 'expand/collapse' state should be restored. */
@NotNull private final Set<TreePath> myPathsToProcessCollapseState = ContainerUtilRt.newHashSet();
@NotNull private final Map<String/*tree path*/, Boolean/*expanded*/> myExpandedStateHolder;
private boolean mySuppressCollapseTracking;
@@ -86,7 +88,7 @@ public class ExternalSystemTasksTree extends Tree implements Producer<ExternalTa
}
}
});
model.addTreeModelListener(new TreeModelAdapter() {
@Override
public void treeStructureChanged(TreeModelEvent e) {
@@ -183,16 +185,39 @@ public class ExternalSystemTasksTree extends Tree implements Producer<ExternalTa
@Nullable
@Override
public ExternalTaskExecutionInfo produce() {
TreePath selectionPath = getLeadSelectionPath();
if (selectionPath == null) {
return null;
}
Object component = selectionPath.getLastPathComponent();
if (!(component instanceof ExternalSystemNode)) {
TreePath[] selectionPaths = getSelectionPaths();
if (selectionPaths == null || selectionPaths.length == 0) {
return null;
}
Object element = ((ExternalSystemNode)component).getDescriptor().getElement();
return element instanceof ExternalTaskExecutionInfo ? ((ExternalTaskExecutionInfo)element) : null;
Map<String, ExternalTaskExecutionInfo> 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();
}
}
@@ -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'() {
@@ -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<VirtualFile> files,
int line, @NotNull Project project);
}
@@ -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();
}
}
}
}
@@ -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<SoftReference<Pair<PsiFile, Document>>> FILE_COPY_KEY = Key.create("CompletionFileCopy");
private static final Key<SoftReference<Trinity<PsiFile, Document, Long>>> 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<Pair<PsiFile, Document>> reference = file.getUserData(FILE_COPY_KEY);
if (reference != null) {
final Pair<PsiFile, Document> 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<PsiFile, Document, Long> 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<PsiFile,Document>>(Pair.create(copy, document)));
if (mayCacheCopy) {
final Document document = copy.getViewProvider().getDocument();
assert document != null;
file.putUserData(FILE_COPY_KEY, new SoftReference<Trinity<PsiFile,Document, Long>>(Trinity.create(copy, document, combinedOffsets)));
}
return copy;
}
@@ -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;
@@ -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<VirtualFile> files,
int line, @NotNull Project project) {
return new MultipleFilesHyperlinkInfo(files, line, project);
}
}
@@ -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<VirtualFile> myVirtualFiles;
private final int myLineNumber;
private final Project myProject;
public MultipleFilesHyperlinkInfo(@NotNull List<VirtualFile> virtualFiles, int lineNumber, @NotNull Project project) {
myVirtualFiles = virtualFiles;
myLineNumber = lineNumber;
myProject = project;
}
@Override
public void navigate(@NotNull final Project project, @Nullable RelativePoint hyperlinkLocationPoint) {
List<PsiFile> currentFiles = new ArrayList<PsiFile>();
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);
}
}
@@ -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<RangeHighlighter>() {
@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);
}
}
}
});
@@ -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
@@ -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();
@@ -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();
@@ -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());
}
}
}
@@ -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<Language> compute() {
THashSet<Language> result = new THashSet<Language>();
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()) {
@@ -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<VirtualFile> myAlreadyAddedFiles = new ArrayList<VirtualFile>();
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<Boolean>() {
@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<String> history = StringUtil.isEmpty(historyString) ? new ArrayList<String>() : 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<String> 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();
@@ -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);
@@ -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);
}
@@ -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<String, HashSet<VirtualFile>> entry : myPackagePrefixRoots.entrySet()) {
if (entry.getValue().contains(dir)) {
return entry.getKey();
@@ -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<String, String> 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<String, String> 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<String, String> 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 {
@@ -315,7 +315,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
final MyIndex<K> index = (MyIndex<K>)myIndices.get(indexKey);
try {
return index.processAllKeys(processor, idFilter);
return index.processAllKeys(processor, scope, idFilter);
}
catch (StorageException e) {
forceRebuild(e);
@@ -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<Key, Value> {
@NotNull
ValueContainer<Value> getData(Key key) throws StorageException;
boolean processAllKeys(Processor<Key> processor, @Nullable IdFilter idFilter) throws StorageException;
boolean processAllKeys(Processor<Key> processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) throws StorageException;
}
@@ -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);
@@ -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<Key, Value> extends Flushable {
@NotNull
ValueContainer<Value> read(Key key) throws StorageException;
boolean processKeys(Processor<Key> processor, @Nullable IdFilter idFilter) throws StorageException;
boolean processKeys(Processor<Key> processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) throws StorageException;
Collection<Key> getKeys() throws StorageException;
@@ -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<Key, Value> implements IndexStorage<Key, Value>{
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<Key, ValueContainer<Value>> myMap;
private PersistentBTreeEnumerator<int[]> myKeyHashToVirtualFileMapping;
private SLRUCache<Key, ChangeTrackingValueContainer<Value>> myCache;
private volatile int myLastScannedId;
private final File myStorageFile;
private final KeyDescriptor<Key> myKeyDescriptor;
private final int myCacheSize;
@@ -216,29 +222,58 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
}
@Override
public boolean processKeys(final Processor<Key> processor, final IdFilter idFilter) throws StorageException {
public boolean processKeys(final Processor<Key> 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<int[]>() {
@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<int[]>() {
@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<Key>() {
@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<Key, Value> implements IndexStorage<Key, Valu
}
}
private static TIntHashSet loadHashedIds(File fileWithCaches) throws IOException {
DataInputStream inputStream = null;
try {
inputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(fileWithCaches)));
int capacity = DataInputOutputUtil.readINT(inputStream);
TIntHashSet hashMaskSet = new TIntHashSet(capacity);
while(capacity > 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<Key> getKeys() throws StorageException {
List<Key> keys = new ArrayList<Key>();
processKeys(new CommonProcessors.CollectProcessor<Key>(keys), null);
processKeys(new CommonProcessors.CollectProcessor<Key>(keys), null, null);
return keys;
}
@@ -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<Key, Value, Input> implements UpdatableIndex<Key,Val
}
@Override
public boolean processAllKeys(Processor<Key> processor, IdFilter idFilter) throws StorageException {
public boolean processAllKeys(Processor<Key> 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();
@@ -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<Key, Value> implements IndexStorage<Key, Value>
@Override
public Collection<Key> getKeys() throws StorageException {
final Set<Key> keys = new HashSet<Key>();
processKeys(new CommonProcessors.CollectProcessor<Key>(keys), null);
processKeys(new CommonProcessors.CollectProcessor<Key>(keys), null, null);
return keys;
}
@Override
public boolean processKeys(final Processor<Key> processor, IdFilter idFilter) throws StorageException {
public boolean processKeys(final Processor<Key> processor, GlobalSearchScope scope, IdFilter idFilter) throws StorageException {
final Set<Key> stopList = new HashSet<Key>();
Processor<Key> decoratingProcessor = new Processor<Key>() {
@@ -128,7 +129,7 @@ public class MemoryIndexStorage<Key, Value> implements IndexStorage<Key, Value>
}
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
@@ -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);
}
+2
View File
@@ -32,6 +32,8 @@
<orderEntry type="library" name="proxy-vole" level="project" />
<orderEntry type="module" module-name="analysis-api" exported="" />
<orderEntry type="module" module-name="editor-ui-api" exported="" />
<orderEntry type="library" name="pty4j" level="project" />
<orderEntry type="library" name="Guava" level="project" />
</component>
</module>
@@ -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<Object, Object> myUserData = null;
private boolean myStartProcessWithPty = false;
public GeneralCommandLine() { }
public GeneralCommandLine() {
}
public GeneralCommandLine(@NotNull String... command) {
this(Arrays.asList(command));
@@ -107,13 +112,17 @@ public class GeneralCommandLine implements UserDataHolder {
return myEnvParams;
}
/** @deprecated use {@link #getEnvironment()} (to remove in IDEA 14) */
/**
* @deprecated use {@link #getEnvironment()} (to remove in IDEA 14)
*/
@SuppressWarnings("unused")
public Map<String, String> getEnvParams() {
return getEnvironment();
}
/** @deprecated use {@link #getEnvironment()} (to remove in IDEA 14) */
/**
* @deprecated use {@link #getEnvironment()} (to remove in IDEA 14)
*/
@SuppressWarnings("unused")
public void setEnvParams(@Nullable Map<String, String> envParams) {
myEnvParams.clear();
@@ -126,7 +135,9 @@ public class GeneralCommandLine implements UserDataHolder {
myPassParentEnvironment = passParentEnvironment;
}
/** @deprecated use {@link #setPassParentEnvironment(boolean)} (to remove in IDEA 14) */
/**
* @deprecated use {@link #setPassParentEnvironment(boolean)} (to remove in IDEA 14)
*/
@SuppressWarnings({"unused", "SpellCheckingInspection"})
public void setPassParentEnvs(boolean passParentEnvironment) {
setPassParentEnvironment(passParentEnvironment);
@@ -136,6 +147,15 @@ public class GeneralCommandLine implements UserDataHolder {
return myPassParentEnvironment;
}
/**
* If argument is true the process created with Pseudo-Terminal (PTY).
* This works only on Unix. On Windows the option is ignored.
*/
public GeneralCommandLine withPty(boolean startProcessWithPty) {
myStartProcessWithPty = startProcessWithPty;
return this;
}
public void addParameters(final String... parameters) {
for (String parameter : parameters) {
addParameter(parameter);
@@ -235,11 +255,16 @@ public class GeneralCommandLine implements UserDataHolder {
}
try {
ProcessBuilder builder = new ProcessBuilder(commands);
setupEnvironment(builder.environment());
builder.directory(myWorkDirectory);
builder.redirectErrorStream(myRedirectErrorStream);
return builder.start();
if (myStartProcessWithPty && SystemInfo.isUnix) {
try {
return startProcessWithPty(commands);
}
catch (Exception e) {
LOG.error("Couldn't run process with PTY", e);
}
}
return startProcess(commands);
}
catch (IOException e) {
LOG.warn(e);
@@ -247,6 +272,23 @@ public class GeneralCommandLine implements UserDataHolder {
}
}
private Process startProcessWithPty(List<String> commands) throws IOException {
Map<String, String> env = Maps.newHashMap();
setupEnvironment(env);
if (myRedirectErrorStream) {
LOG.error("Launching process with PTY and redirected error stream is unsupported yet");
}
return PtyProcess.exec(ArrayUtil.toStringArray(commands), env, myWorkDirectory.getPath(), true);
}
private Process startProcess(List<String> commands) throws IOException {
ProcessBuilder builder = new ProcessBuilder(commands);
setupEnvironment(builder.environment());
builder.directory(myWorkDirectory);
builder.redirectErrorStream(myRedirectErrorStream);
return builder.start();
}
private void checkWorkingDirectory() throws ExecutionException {
if (myWorkDirectory == null) {
return;
@@ -0,0 +1,33 @@
/*
* 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.project.Project;
import com.intellij.ui.awt.RelativePoint;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public abstract class HyperlinkInfoBase implements HyperlinkInfo {
public abstract void navigate(@NotNull Project project, @Nullable RelativePoint hyperlinkLocationPoint);
@Override
public void navigate(Project project) {
navigate(project, null);
}
}
@@ -375,6 +375,18 @@ public class SearchTextField extends JPanel {
}
}
@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;
}
protected Runnable createItemChosenCallback(final JList list) {
return new Runnable() {
public void run() {
@@ -17,7 +17,6 @@ package com.intellij.ui.components;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
@@ -67,6 +66,8 @@ public class OnOffButton extends JToggleButton {
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
c.setOpaque(false);
c.setAlignmentY(0.5f);
return new OnOffButtonUI((OnOffButton)c);
}
@@ -92,31 +93,33 @@ public class OnOffButton extends JToggleButton {
h--;
}
Graphics2D g = ((Graphics2D)gr);
GraphicsUtil.setupAAPainting(g);
g.translate(1,1);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int xOff = (myButton.getWidth() - w) / 2;
int yOff = (myButton.getHeight() - h) / 2;
g.translate(xOff, yOff);
if (button.isSelected()) {
g.setColor(new JBColor(new Color(57, 113, 238), new Color(13, 41, 62)));
g.fillRoundRect(0, 0, w, h, h, h);
g.setColor(UIUtil.getBorderColor());
g.drawRoundRect(0, 0, w, h, h, h);
g.setColor(new JBColor(Gray._220, Gray._128));
g.fillOval(w - h + 1, 1, h - 1, h - 1);
g.setColor(new JBColor(new Color(74, 146, 73), new Color(77, 105, 76)));
g.fillRoundRect(0, 0, w, h, 5, 5);
g.setColor(new JBColor(Gray._192, Gray._80));
g.drawRoundRect(0, 0, w, h, 5, 5);
g.setColor(new JBColor(Gray._200, Gray._100));
g.fillRoundRect(w - h, 1, h, h-1, 3, 3);
g.setColor(UIUtil.getListForeground(true));
g.drawString(button.getOnText(), h/2, h - 4);
} else {
g.setColor(UIUtil.getPanelBackground());
g.fillRoundRect(0, 0, w, h, h, h);
g.setColor(UIUtil.getBorderColor());
g.drawRoundRect(0, 0, w, h, h, h);
g.fillRoundRect(0, 0, w, h, 5, 5);
g.setColor(new JBColor(Gray._192, Gray._100));
g.drawRoundRect(0, 0, w, h, 5, 5);
g.setColor(UIUtil.getLabelDisabledForeground());
g.drawString(button.getOffText(), h + 4 , h - 4);
g.setColor(UIUtil.getBorderColor());
g.setPaint(new GradientPaint(h,0, Gray._178, 0,h, Gray._240));
g.fillOval(0, 0, h, h);
g.setColor(UIUtil.getBorderColor());
g.drawOval(0, 0, h, h);
g.setPaint(new GradientPaint(h, 0, new JBColor(Gray._158, Gray._100), 0, h, new JBColor(Gray._210, Gray._100)));
g.fillRoundRect(0, 0, h, h, 3, 3);
// g.setColor(UIUtil.getBorderColor());
// g.drawOval(0, 0, h, h);
}
g.translate(-1, -1);
g.translate(-xOff, -yOff);
}
@Override
@@ -129,6 +129,19 @@ public class NetUtils {
}
}
public static int tryToFindAvailableSocketPort(int defaultPort) {
try {
return findAvailableSocketPort();
}
catch (IOException ignored) {
return defaultPort;
}
}
public static int tryToFindAvailableSocketPort() {
return tryToFindAvailableSocketPort(-1);
}
public static int[] findAvailableSocketPorts(int capacity) throws IOException {
final int[] ports = new int[capacity];
final ServerSocket[] sockets = new ServerSocket[capacity];
@@ -4,9 +4,11 @@ import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
@@ -26,6 +28,20 @@ public class AttachmentFactory {
file.getFileType().isBinary() ? "File is binary" : LoadTextUtil.loadText(file).toString());
}
public static Attachment createAttachment(@NotNull File file, boolean isBinary) {
byte[] bytes = getBytes(file);
return new Attachment(file.getPath(), bytes, isBinary ? "File is binary" : new String(bytes));
}
private static byte[] getBytes(File file) {
try {
return FileUtil.loadFileBytes(file);
}
catch (IOException e) {
return Attachment.getBytes(MessageFormat.format(ERROR_MESSAGE_PATTERN, e.getMessage()));
}
}
private static byte[] getBytes(VirtualFile file) {
try {
return file.contentsToByteArray();
@@ -18,6 +18,7 @@ package com.intellij.execution.impl;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.filters.FilterMixin;
import com.intellij.execution.filters.HyperlinkInfo;
import com.intellij.execution.filters.HyperlinkInfoBase;
import com.intellij.ide.OccurenceNavigator;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -36,6 +37,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.pom.NavigatableAdapter;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.BeforeAfter;
import com.intellij.util.Consumer;
import com.intellij.util.SmartList;
@@ -87,7 +89,12 @@ public class EditorHyperlinkSupport {
if (range != null) {
final HyperlinkInfo info = myHighlighterToMessageInfoMap.get(range);
if (info != null) {
info.navigate(project);
if (info instanceof HyperlinkInfoBase) {
((HyperlinkInfoBase)info).navigate(project, new RelativePoint(mouseEvent));
}
else {
info.navigate(project);
}
linkFollowed(editor, getHyperlinks().keySet(), range);
}
}
@@ -490,9 +490,9 @@ public class Switcher extends AnAction implements DumbAware {
this.add(toolWindows, BorderLayout.WEST);
if (filesModel.size() > 0) {
files.setAlignmentY(1f);
if (files.getModel().getSize() > 30) {
if (files.getModel().getSize() > 20) {
final JScrollPane pane = ScrollPaneFactory.createScrollPane(files, true);
pane.setPreferredSize(new Dimension(files.getPreferredSize().width + 10, 30 * 20));
pane.setPreferredSize(new Dimension(files.getPreferredSize().width + 10, 20 * 20));
pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
this.add(pane, BorderLayout.EAST);
} else {
@@ -556,16 +556,9 @@ public class Switcher extends AnAction implements DumbAware {
}.registerCustomShortcutSet(CustomShortcutSet.fromString("ESCAPE"), this, myPopup);
}
Component comp = null;
final EditorWindow result = FileEditorManagerEx.getInstanceEx(project).getActiveWindow().getResult();
if (result != null) {
comp = result.getOwner();
}
if (comp == null) {
comp = ideFrame.getContentPane();
}
final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, myPopup);
myPopup.showInCenterOf(comp);
myPopup.showInCenterOf(window);
}
@@ -668,48 +661,67 @@ public class Switcher extends AnAction implements DumbAware {
}
private void closeTabOrToolWindow() {
final Object value = getSelectedList().getSelectedValue();
if (value instanceof FileInfo) {
final FileInfo info = (FileInfo)value;
final VirtualFile virtualFile = info.first;
final FileEditorManagerImpl editorManager = ((FileEditorManagerImpl)FileEditorManager.getInstance(project));
final JList jList = getSelectedList();
final EditorWindow wnd = findAppropriateWindow(info);
if (wnd == null) {
editorManager.closeFile(virtualFile, false, false);
} else {
editorManager.closeFile(virtualFile, wnd, false);
}
final int selectedIndex = jList.getSelectedIndex();
final IdeFocusManager focusManager = IdeFocusManager.getInstance(project);
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
focusManager.requestFocus(SwitcherPanel.this, true);
final int[] selected = getSelectedList().getSelectedIndices();
Arrays.sort(selected);
int selectedIndex = 0;
for (int i = selected.length - 1; i>=0; i--) {
selectedIndex = selected[i];
Object value = getSelectedList().getModel().getElementAt(selectedIndex);
if (value instanceof FileInfo) {
final FileInfo info = (FileInfo)value;
final VirtualFile virtualFile = info.first;
final FileEditorManagerImpl editorManager = ((FileEditorManagerImpl)FileEditorManager.getInstance(project));
final JList jList = getSelectedList();
final EditorWindow wnd = findAppropriateWindow(info);
if (wnd == null) {
editorManager.closeFile(virtualFile, false, false);
}
else {
editorManager.closeFile(virtualFile, wnd, false);
}
final IdeFocusManager focusManager = IdeFocusManager.getInstance(project);
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
focusManager.requestFocus(SwitcherPanel.this, true);
}
}, 300);
if (jList.getModel().getSize() == 1) {
goLeft();
removeElementAt(jList, selectedIndex);
this.remove(jList);
this.remove(separator);
final Dimension size = toolWindows.getSize();
myPopup.setSize(new Dimension(size.width, myPopup.getSize().height));
}
else {
removeElementAt(jList, selectedIndex);
jList.setSize(jList.getPreferredSize());
}
if (isPinnedMode()) {
EditorHistoryManager.getInstance(project).removeFile(virtualFile);
}
}, 300);
if (jList.getModel().getSize() == 1) {
goLeft();
removeElementAt(jList, selectedIndex);
this.remove(jList);
this.remove(separator);
final Dimension size = toolWindows.getSize();
myPopup.setSize(new Dimension(size.width, myPopup.getSize().height));
} else {
goForward();
removeElementAt(jList, selectedIndex);
jList.setSize(jList.getPreferredSize());
}
pack();
} else if (value instanceof ToolWindow) {
final ToolWindow toolWindow = (ToolWindow)value;
if (twManager instanceof ToolWindowManagerImpl) {
ToolWindowManagerImpl manager = (ToolWindowManagerImpl)twManager;
manager.hideToolWindow(ids.get(toolWindow), false, false);
} else {
toolWindow.hide(null);
else if (value instanceof ToolWindow) {
final ToolWindow toolWindow = (ToolWindow)value;
if (twManager instanceof ToolWindowManagerImpl) {
ToolWindowManagerImpl manager = (ToolWindowManagerImpl)twManager;
manager.hideToolWindow(ids.get(toolWindow), false, false);
}
else {
toolWindow.hide(null);
}
}
}
pack();
myPopup.getContent().revalidate();
myPopup.getContent().repaint();
if (getSelectedList().getModel().getSize() > selectedIndex) {
getSelectedList().setSelectedIndex(selectedIndex);
getSelectedList().ensureIndexIsVisible(selectedIndex);
}
}
private static void removeElementAt(JList jList, int index) {
@@ -34,7 +34,7 @@ public class DarculaTextBorder implements Border, UIResource {
public Insets getBorderInsets(Component c) {
int vOffset = c instanceof JPasswordField ? 3 : 4;
if (DarculaTextFieldUI.isSearchField(c)) {
vOffset++;
vOffset += 2;
}
if (DarculaTextFieldUI.isSearchFieldWithHistoryPopup(c)) {
return new InsetsUIResource(vOffset, 7 + 16 + 3, vOffset, 7 + 16);
@@ -17,33 +17,30 @@ package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.components.StateStorage;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.util.SmartList;
import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
import java.util.*;
import java.util.List;
import java.util.Map;
/**
* @author mike
*/
public class CompoundSaveSession {
private final Map<StateStorage, StateStorage.SaveSession> mySaveSessions = new HashMap<StateStorage, StateStorage.SaveSession>();
private final Map<StateStorage, StateStorage.SaveSession> mySaveSessions = new THashMap<StateStorage, StateStorage.SaveSession>();
public CompoundSaveSession(final CompoundExternalizationSession compoundExternalizationSession) {
final Collection<StateStorage> stateStorages = compoundExternalizationSession.getStateStorages();
for (StateStorage stateStorage : stateStorages) {
for (StateStorage stateStorage : compoundExternalizationSession.getStateStorages()) {
mySaveSessions.put(stateStorage, stateStorage.startSave(compoundExternalizationSession.getExternalizationSession(stateStorage)));
}
}
public List<IFile> getAllStorageFilesToSave() throws StateStorageException {
List<IFile> result = new ArrayList<IFile>();
for (StateStorage stateStorage : mySaveSessions.keySet()) {
final StateStorage.SaveSession saveSession = mySaveSessions.get(stateStorage);
List<IFile> result = new SmartList<IFile>();
for (StateStorage.SaveSession saveSession : mySaveSessions.values()) {
result.addAll(saveSession.getStorageFilesToSave());
}
return result;
}
@@ -56,11 +53,11 @@ public class CompoundSaveSession {
public void finishSave() {
RuntimeException re = null;
for (StateStorage stateStorage : mySaveSessions.keySet()) {
final StateStorage.SaveSession saveSession = mySaveSessions.get(stateStorage);
try {
stateStorage.finishSave(saveSession);
} catch(RuntimeException t) {
re = t;
stateStorage.finishSave(mySaveSessions.get(stateStorage));
}
catch (RuntimeException e) {
re = e;
}
}
@@ -74,11 +71,10 @@ public class CompoundSaveSession {
}
public List<IFile> getAllStorageFiles() {
List<IFile> result = new ArrayList<IFile>();
List<IFile> result = new SmartList<IFile>();
for (StateStorage.SaveSession saveSession : mySaveSessions.values()) {
result.addAll(saveSession.getAllStorageFiles());
}
return result;
}
}

Some files were not shown because too many files have changed in this diff Show More